【问题标题】:Making a rust wasm bindgen future example from cc::Build从 cc::Build 制作一个 rust wasm bindgen 未来示例
【发布时间】:2022-08-15 01:56:09
【问题描述】:

我并不是想问太多,但我认为我已经超越了使用 Rust VS Code 格式化程序的基本要求.我正需要期货,我相信run_until本地池方法可以执行该操作。我认为需要一生的elide,我认为它完全是由 \'a 类型声明插入的。

use futures::executor::LocalPool;

pub fn pathify(path: &str) -> std::path::PathBuf {
    let mut input_file = std::path::PathBuf::new();

    let arr: () = path.split(\"/\").map(|x| input_file.push(x)).collect();
    return input_file;
}

struct DropOnce{  //ERROR: \"expected named lifetime parameter\"
    _bosun: dyn Mak<std::sync::Once, Output = cc::Build>, //::new()
}
trait Mak<\'a,T:\'a> { //fn resolve(self) -> cc::Build;
    type Output; //static types before compilation! (concrete type)
    fn _bosun() {
        let lock: std::path::PathBuf = pathify(\"./exec.c\");
        cc::Build::new().file(lock).expand(); //= Default::default().await
    }
}
impl<\'a> std::future::Future for DropOnce{
    fn poll(&\'a mut self) -> &\'a mut Self {
        println!(\"poll\");
        self
    }
}
fn main() {
    let mut pool = LocalPool::new();
    let _bosun = DropOnce; //ERROR: \"expected value, found struct `DropOnce`\"
    pool.run_until(_bosun);
}

full code

use wasm_bindgen::prelude::wasm_bindgen;
#[wasm_bindgen(start)]
fn main () {}

如果这个例子还太新,无法在 SO 答案中发挥作用,我会感谢社区文档参考.我想我可能会混淆traitimpl 中的定义,例如,\'[是impl 的成员函数,与其trait 定义+声明一样可变,但对于名称]?\'

    标签: rust wasm-bindgen


    【解决方案1】:

    事实证明,cc::Build 用例/后者的唯一用例不需要 wasm-bindgen。

    use serde::Serialize;
    use std::{
        collections::HashMap,
        future::Future,
        mem,
        pin::Pin,
        sync::mpsc::{channel, Sender},
        sync::{Arc, Mutex},
        task::{Context, Poll, Waker},
        thread::{self, JoinHandle},
        time::Duration,
    };
    #[derive(Serialize)]
    struct Product {
        ivity: String,
    }
    

    显然,以下是从async{block.await}“任务”创建Future 的最低要求。

    //(1) Reactor
    enum TaskState {
        Ready,
        NotReady(Waker),
        Finished,
    } //https://cfsamson.github.io/books-futures-explained/6_future_example.html
    struct Reactor {
        dispatcher: Sender<Event>,
        handle: Option<JoinHandle<()>>,
        tasks: HashMap<usize, TaskState>,
    }
    #[derive(Debug)]
    enum Event {
        Close,
        Timeout(u64, usize),
    }
    impl Reactor {
        fn new() -> Arc<Mutex<Box<Self>>> {
            let (tx, rx) = channel::<Event>();
            let reactor = Arc::new(Mutex::new(Box::new(Reactor {
                dispatcher: tx,
                handle: None,
                tasks: HashMap::new(),
            })));
            let reactor_clone = Arc::downgrade(&reactor);
            let handle = thread::spawn(move || {
                let mut handles = vec![];
                for event in rx {
                    println!("REACTOR: {:?}", event);
                    let reactor = reactor_clone.clone();
                    match event {
                        Event::Close => break,
                        Event::Timeout(duration, id) => {
                            let event_handle = thread::spawn(move || {
                                thread::sleep(Duration::from_secs(duration));
                                let reactor = reactor.upgrade().unwrap();
                                reactor.lock().map(|mut r| r.wake(id)).unwrap();
                            });
                            handles.push(event_handle);
                        }
                    }
                }
                handles
                    .into_iter()
                    .for_each(|handle| handle.join().unwrap());
            });
            reactor.lock().map(|mut r| r.handle = Some(handle)).unwrap();
            reactor
        }
        fn wake(&mut self, id: usize) {
            self.tasks
                .get_mut(&id)
                .map(|state| {
                    match mem::replace(state, TaskState::Ready) {
                        TaskState::NotReady(waker) => waker.wake(),
                        TaskState::Finished => {
                            panic!("Called 'wake' twice on task: {}", id)
                        }
                        _ => unreachable!(),
                    }
                })
                .unwrap();
        }
        fn register(&mut self, duration: u64, waker: Waker, id: usize) {
            if self.tasks.insert(id, TaskState::NotReady(waker)).is_some() {
                panic!("Tried to insert a task with id: '{}', twice!", id);
            }
            self.dispatcher.send(Event::Timeout(duration, id)).unwrap();
        }
        fn is_ready(&self, id: usize) -> bool {
            self.tasks
                .get(&id)
                .map(|state| match state {
                    TaskState::Ready => true,
                    _ => false,
                })
                .unwrap_or(false)
        }
    }
    
    impl Drop for Reactor {
        fn drop(&mut self) {
            self.dispatcher.send(Event::Close).unwrap();
            self.handle.take().map(|h| h.join().unwrap()).unwrap();
        }
    }
    //(2) Task
    #[derive(Clone)]
    pub struct Task {
        app: u64,
        reactor: Arc<Mutex<Box<Reactor>>>,
        id: usize,
    }
    impl Task {
        fn new(pathstr: &str, reactor: Arc<Mutex<Box<Reactor>>>, id: usize) -> Self {
            //Task {
            Task {
                app: match pathstr {
                    //let s: String = match pathstr {
                    "/" => {
                        fn pathify(path: &str) -> std::path::PathBuf {
                            let mut input_file = std::path::PathBuf::new();
                            let _arr: () =
                                path.split("/").map(|x| input_file.push(x)).collect();
                            return input_file;
                        }
                        let lock: std::path::PathBuf = pathify("./exec.c");
                        let appel = cc::Build::new().file(lock).expand();
                        //String::from_utf8(appel).unwrap()
                        u64::from_be_bytes(appel.try_into().expect(""))
                        //.iter().collect()
                    }
                    &_ => u64::from_be_bytes("".as_bytes().try_into().expect("")),
                    //};
                    //u64::from_str_radix(s.expect("")) //,16
                },
                reactor,
                id,
            }
        }
    }
    // (3) Future implementation
    impl Future for Task {
        type Output = usize;
    
        fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
            //let mut r = self.app;
            let mut r = self.reactor.lock().unwrap();
            if r.is_ready(self.id) {
                *r.tasks.get_mut(&self.id).unwrap() = TaskState::Finished;
                Poll::Ready(self.id)
            } else if r.tasks.contains_key(&self.id) {
                r.tasks
                    .insert(self.id, TaskState::NotReady(cx.waker().clone()));
                Poll::Pending
            } else {
                r.register(self.app, cx.waker().clone(), self.id);
                Poll::Pending
            }
        }
    }
    let path = req.path(); //longer lived with let
    let pathstr: &str = path.as_str();
    let reactor = Reactor::new();
    let id = 1;
    let future1 = Task::new(pathstr, reactor.clone(), id);
    let fut1 = async {
        future1.await
        //let val = future1.await;
        //println!("Got {} at time: {:.2}.", val, start.elapsed().as_secs_f32());
    };
    Response::from_json(&Product {
        ivity: fut1.await.to_string(),
    })
    

    在我构建它时,我将使用use wasm_bindgen::prelude::*; use wasm_bindgen_futures::{JsFuture, future_to_promise}; 对其进行编辑,但我不想用这个通过的 rustup 分析器进一步误导这个问题(也就是我现在正在测试,请记住,VS 代码像终端一样钝,可能需要关闭一次)。

    【讨论】:

      猜你喜欢
      • 2021-09-15
      • 2020-09-11
      • 2021-03-22
      • 1970-01-01
      • 2021-01-01
      • 1970-01-01
      • 2021-09-15
      • 2021-03-10
      • 2020-05-03
      相关资源
      最近更新 更多