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

added example

parent 4b7cfe2a
No related branches found
No related tags found
No related merge requests found
Pipeline #38722 passed
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "coroutines_better"
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_better"
version = "0.1.0"
edition = "2021"
[dependencies]
mio = { version = "1.0.3", features = ["net", "os-poll"] }
// Future trait looks like standard Future except for the missing context
// pub trait Future {
// type Output;
// fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
//}
pub trait Future {
type Output;
fn poll(&mut self) -> PollState<Self::Output>;
}
// Similar to the Poll #[derive(Debug)]
// pub enum Poll<T> {
// Ready(T),
// Pending,
// }
pub enum PollState<T> {
Ready(T),
NotReady,
}
use mio::{Interest, Token};
use crate::future::{Future, PollState};
use crate::runtime;
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();
// 1. Registering the Tcp stream as a source of events in the poll instance
// 2. On retourne pas encore NotReady mais on essaie de lire le stream directement
}
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 => {
println!("Data not ready");
break PollState::NotReady;
}
Err(e) if e.kind() == ErrorKind::Interrupted => {
continue;
}
Err(e) => panic!("{e:?}"),
}
}
}
}
mod future;
mod http;
mod runtime;
use future::{Future, PollState};
use http::Http;
use runtime::Runtime;
fn main() {
let future = async_main();
let mut runtime = Runtime::new();
runtime.block_on(future);
}
// =================================
// We rewrite this:
// =================================
// coroutine fn async_main() -> impl Future<Output = String> {
// println!("Program starting");
// let txt = Http::get("/600/HelloAsyncAwait").wait;
// println!("{txt}");
// let txt = Http::get("/400/HelloAsyncAwait").wait;
// println!("{txt}");
// }
// =================================
// Into this:
// =================================
fn async_main() -> impl Future<Output = String> {
Coroutine::new()
}
enum State {
Start,
Wait1(Box<dyn Future<Output = String>>),
Wait2(Box<dyn Future<Output = String>>),
Resolved,
}
struct Coroutine {
state: State,
}
impl Coroutine {
fn new() -> Self {
Self {
state: State::Start,
}
}
}
impl Future for Coroutine {
type Output = String;
fn poll(&mut self) -> PollState<Self::Output> {
loop {
match self.state {
State::Start => {
println!("Program starting");
let fut1 = Box::new(Http::get("/600/HelloAsyncAwait"));
self.state = State::Wait1(fut1);
}
State::Wait1(ref mut future) => match future.poll() {
PollState::Ready(txt) => {
println!("{txt}");
let fut2 = Box::new(Http::get("/400/HelloAsyncAwait"));
self.state = State::Wait2(fut2);
}
PollState::NotReady => break PollState::NotReady,
},
State::Wait2(ref mut future) => match future.poll() {
PollState::Ready(txt) => {
println!("{txt}");
self.state = State::Resolved;
break PollState::Ready(String::new());
}
PollState::NotReady => break PollState::NotReady,
},
State::Resolved => panic!("Polled a resolved future"),
}
}
}
}
use std::sync::OnceLock;
use mio::{Events, Poll, Registry};
use crate::future::{Future, PollState};
static REGISTRY: OnceLock<Registry> = OnceLock::new();
pub fn registry() -> &'static Registry {
REGISTRY.get().expect("Called outside a runtime context")
}
pub struct Runtime {
poll: Poll,
}
impl Runtime {
pub fn new() -> Self {
// 1. creation d'une nouvelle instance de Poll
// 2. try_clone() du registry associé pour pouvoir ajouter une source plus tard
// 3. set() le registry au REGISTRY
// 4. return d'une nouvelle install avec le poll associé
unimplemented!()
}
pub fn block_on<F>(&mut self, future: F)
where
F: Future<Output = String>,
{
// 1. future -> mut future
// 2. tant que future.poll() n'est pas Ready poll.poll() un mut Event
// 3. Voilà
unimplemented!()
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment