Skip to content
Snippets Groups Projects
Verified Commit 6748aaf6 authored by orestis.malaspin's avatar orestis.malaspin
Browse files

added correction

parent feb323e0
No related branches found
No related tags found
No related merge requests found
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "coroutines"
version = "0.1.0"
dependencies = [
"mio",
]
[[package]]
name = "libc"
version = "0.2.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
[[package]]
name = "log"
version = "0.4.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e"
[[package]]
name = "mio"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
dependencies = [
"libc",
"log",
"wasi",
"windows-sys",
]
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[package]
name = "coroutines"
version = "0.1.0"
edition = "2021"
[dependencies]
mio = { version = "1.0.3", features = ["net", "os-poll"] }
pub trait Future {
type Output;
fn poll(&mut self) -> PollState<Self::Output>;
}
pub enum PollState<T> {
Ready(T),
NotReady,
}
pub struct JoinThree<F: Future> {
future1: (bool, F),
future2: (bool, F),
future3: (bool, F),
}
impl<F: Future> Future for JoinThree<F> {
type Output = ();
fn poll(&mut self) -> PollState<Self::Output> {
if !self.future1.0 {
match self.future1.1.poll() {
PollState::Ready(_) => {
self.future1.0 = true;
}
PollState::NotReady => {}
}
}
if !self.future2.0 {
match self.future2.1.poll() {
PollState::Ready(_) => {
self.future2.0 = true;
}
PollState::NotReady => {}
}
}
if !self.future3.0 {
match self.future3.1.poll() {
PollState::Ready(_) => {
self.future3.0 = true;
}
PollState::NotReady => {}
}
}
if self.future1.0 && self.future2.0 && self.future3.0 {
PollState::Ready(())
} else {
PollState::NotReady
}
}
}
pub fn join_three<F: Future>(future1: F, future2: F, future3: F) -> JoinThree<F> {
JoinThree {
future1: (false, future1),
future2: (false, future2),
future3: (false, future3),
}
}
use crate::future::{Future, PollState};
use std::io::{ErrorKind, Read, Write};
fn get_req(path: &str) -> String {
format!(
"GET {path} HTTP/1.1\r\n\
Host: localhost\r\n\
Connection: close\r\n\
\r\n"
)
}
pub struct Http;
impl Http {
pub fn get(path: &str) -> impl Future<Output = String> {
HttpGetFuture::new(path)
}
}
struct HttpGetFuture {
stream: Option<mio::net::TcpStream>,
buffer: Vec<u8>,
path: String,
}
impl HttpGetFuture {
fn new(path: &str) -> Self {
Self {
stream: None,
buffer: vec![],
path: String::from(path),
}
}
fn write_request(&mut self) {
let stream = std::net::TcpStream::connect("localhost:8080").unwrap();
stream.set_nonblocking(true).unwrap();
let mut stream = mio::net::TcpStream::from_std(stream);
stream.write_all(get_req(&self.path).as_bytes()).unwrap();
self.stream = Some(stream);
}
}
impl Future for HttpGetFuture {
type Output = String;
fn poll(&mut self) -> PollState<Self::Output> {
if self.stream.is_none() {
println!("First poll - start operation");
self.write_request();
return PollState::NotReady;
}
let mut buf = vec![0u8; 4096];
loop {
match self.stream.as_mut().unwrap().read(&mut buf) {
Ok(0) => {
let s = String::from_utf8_lossy(&self.buffer);
break PollState::Ready(String::from(s));
}
Ok(n) => {
self.buffer.extend(&buf[0..n]);
continue;
}
Err(e) if e.kind() == ErrorKind::WouldBlock => {
break PollState::NotReady;
}
Err(e) if e.kind() == ErrorKind::Interrupted => {
continue;
}
Err(e) => panic!("{e:?}"),
}
}
}
}
pub mod future;
pub mod http;
use std::time::Instant;
use coroutines::future::{join_three, Future, PollState};
use coroutines::http::Http;
struct Coroutine {
state: CoroutineState,
}
impl Coroutine {
fn new(i: usize) -> Self {
Self {
state: CoroutineState::Start(i),
}
}
}
impl Future for Coroutine {
type Output = (); // We return nothing from the Coroutine Future
fn poll(&mut self) -> PollState<Self::Output> {
loop {
match self.state {
CoroutineState::Start(i) => {
println!("Program starting");
let path = format!("/{}/HelloWorld{i}", i * 1000);
self.state = CoroutineState::Wait(Box::new(Http::get(&path)));
}
CoroutineState::Wait(ref mut future) => match future.poll() {
PollState::Ready(txt) => {
println!("{txt}");
self.state = CoroutineState::Resolved;
break PollState::Ready(());
}
PollState::NotReady => break PollState::NotReady,
},
CoroutineState::Resolved => panic!("Polled a resolved Future which is illegal!"),
}
}
}
}
enum CoroutineState {
Start(usize),
Wait(Box<dyn Future<Output = String>>),
Resolved,
}
fn async_main() -> impl Future<Output = ()> {
let future1 = Coroutine::new(1);
let future2 = Coroutine::new(2);
let future3 = Coroutine::new(3);
join_three(future1, future2, future3)
}
fn main() {
let start = Instant::now();
let mut future = async_main();
while let PollState::NotReady = future.poll() {}
println!("Elapsed time: {}", start.elapsed().as_millis());
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment