(
create: CreateRt,
make_span: F,
)
| 11 | use crate::vm::{CreateRt, ShutdownReason, Vm, VmShutdownHandle}; |
| 12 | |
| 13 | pub async fn spawn_vm_thread<F: FnOnce() -> tracing::Span + Send + Sync + 'static>( |
| 14 | create: CreateRt, |
| 15 | make_span: F, |
| 16 | ) -> VmShutdownHandle { |
| 17 | let (vm_created_send, vm_created_recv) = oneshot::channel(); |
| 18 | let (ping_send, mut ping_recv) = mpsc::channel::<oneshot::Sender<()>>(1); |
| 19 | |
| 20 | std::thread::spawn(move || { |
| 21 | let rt = tokio::runtime::Builder::new_current_thread() |
| 22 | .enable_all() |
| 23 | .build() |
| 24 | .unwrap(); |
| 25 | |
| 26 | let cpu_counter = counter!("bl.vm.cpu_microseconds_total"); |
| 27 | let result = Vm::create_with_handles(create, cpu_counter); |
| 28 | vm_created_send |
| 29 | .send(result.shutdown_handle.clone()) |
| 30 | .unwrap(); |
| 31 | |
| 32 | // tokio_current.block_on(t); |
| 33 | let span = make_span(); |
| 34 | rt.block_on( |
| 35 | async move { |
| 36 | let set = LocalSet::new(); |
| 37 | |
| 38 | // A simple task that sends echo responses on a channel |
| 39 | // |
| 40 | // if the js runtime encounters a runaway situation with something like |
| 41 | // an infinite "for" loop, then the thread will be blocked and this task |
| 42 | // will not send echo responses anymore, leading to an outside thread |
| 43 | // being able to detect the runaway and being able to shut down the runaway runtime |
| 44 | set.spawn_local(async move { |
| 45 | loop { |
| 46 | match ping_recv.recv().await { |
| 47 | Some(r) => { |
| 48 | let _ = r.send(()); |
| 49 | } |
| 50 | None => return, |
| 51 | } |
| 52 | } |
| 53 | }); |
| 54 | set.run_until(result.future).await |
| 55 | } |
| 56 | .instrument(span), |
| 57 | ); |
| 58 | |
| 59 | rt.shutdown_timeout(tokio::time::Duration::from_secs(60)); |
| 60 | }); |
| 61 | |
| 62 | let shutdown_handle = vm_created_recv.await.unwrap(); |
| 63 | |
| 64 | tokio::spawn(monitor_vm_runaway(shutdown_handle.clone(), ping_send)); |
| 65 | |
| 66 | shutdown_handle |
| 67 | } |
| 68 | |
| 69 | // runaway script detection ensures that no single vm can |
| 70 | // block the thread for more than the allowed interval |
no test coverage detected