-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathfutures.rs
105 lines (91 loc) · 3.33 KB
/
futures.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use deno_core::anyhow::Error;
use deno_core::error::AnyError;
use deno_core::v8::Handle;
use deno_core::{anyhow, v8, JsRuntime, PollEventLoopOptions};
use deno_runtime::worker::MainWorker;
use log::info; // Import the JsRuntime struct.
use futures::{Future, FutureExt};
use std::pin::Pin;
use std::sync::Arc;
use std::task::{Context, Poll};
use std::thread::sleep;
use tokio::sync::Mutex as TokioMutex;
pub struct EventLoopFuture {
worker: Arc<TokioMutex<MainWorker>>,
}
impl EventLoopFuture {
pub fn new(worker: Arc<TokioMutex<MainWorker>>) -> Self {
EventLoopFuture { worker }
}
}
impl Future for EventLoopFuture {
type Output = Result<(), AnyError>; // You can customize the output type.
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
sleep(std::time::Duration::from_millis(1));
let worker = self.worker.try_lock();
if let Ok(mut worker) = worker {
let res = worker.js_runtime.poll_event_loop(cx, PollEventLoopOptions {
pump_v8_message_loop: true,
wait_for_inspector: false,
});
cx.waker().wake_by_ref();
res
} else {
Poll::Pending
}
}
}
pub struct SmartGlobalVariableFuture<F>
where
F: Future<Output = Result<v8::Global<v8::Value>, AnyError>> + Unpin,
{
worker: Arc<TokioMutex<MainWorker>>,
value: F,
}
impl<F> SmartGlobalVariableFuture<F>
where
F: Future<Output = Result<v8::Global<v8::Value>, AnyError>> + Unpin,
{
pub fn new(worker: Arc<TokioMutex<MainWorker>>, value: F) -> Self {
SmartGlobalVariableFuture { worker, value }
}
}
impl<F> Future for SmartGlobalVariableFuture<F>
where
F: Future<Output = Result<v8::Global<v8::Value>, AnyError>> + Unpin,
{
type Output = Result<String, AnyError>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut value_pin = Pin::new(&mut self.value);
let mut worker = match self.worker.try_lock() {
Ok(w) => w,
Err(_) => return Poll::Pending,
};
let scope = &mut worker.js_runtime.handle_scope();
if let Poll::Ready(result) = value_pin.as_mut().poll(cx) {
match result {
Ok(result) => {
let result = result.open(scope).to_rust_string_lossy(scope);
return Poll::Ready(Ok(result));
},
Err(err) => return Poll::Ready(Err(err)),
};
}
if let Poll::Ready(event_loop_result) = &mut worker.js_runtime.poll_event_loop(cx, deno_core::PollEventLoopOptions::default()) {
if let Err(err) = event_loop_result {
return Poll::Ready(Err(anyhow::anyhow!("Error polling event loop: {:?}", err)));
}
if let Poll::Ready(result) = value_pin.poll(cx) {
match result {
Ok(result) => {
let result = result.open(scope).to_rust_string_lossy(scope);
return Poll::Ready(Ok(result));
},
Err(err) => return Poll::Ready(Err(err)),
};
}
return Poll::Ready(Err(anyhow::anyhow!("Promise resolution is still pending but the event loop has already resolved.")));
}
Poll::Pending
}
}