@@ -50,6 +50,7 @@ use database::Transaction;
50
50
use deno_core:: v8;
51
51
use futures:: {
52
52
channel:: mpsc,
53
+ future:: BoxFuture ,
53
54
select_biased,
54
55
stream:: BoxStream ,
55
56
Future ,
@@ -154,6 +155,7 @@ use crate::{
154
155
} ,
155
156
metrics:: {
156
157
self ,
158
+ log_isolate_request_cancelled,
157
159
log_unawaited_pending_op,
158
160
} ,
159
161
ops:: OpProvider ,
@@ -257,6 +259,7 @@ impl<RT: Runtime> ActionEnvironment<RT> {
257
259
isolate_clean : & mut bool ,
258
260
validated_path : ValidatedHttpPath ,
259
261
request : HttpActionRequest ,
262
+ cancellation : BoxFuture < ' _ , ( ) > ,
260
263
) -> anyhow:: Result < HttpActionOutcome > {
261
264
let client_id = Arc :: new ( client_id) ;
262
265
let start_unix_timestamp = self . rt . unix_timestamp ( ) ;
@@ -278,6 +281,7 @@ impl<RT: Runtime> ActionEnvironment<RT> {
278
281
& mut isolate_context,
279
282
validated_path. canonicalized_udf_path ( ) ,
280
283
request,
284
+ cancellation,
281
285
)
282
286
. await ;
283
287
// Override the returned result if we hit a termination error.
@@ -325,6 +329,7 @@ impl<RT: Runtime> ActionEnvironment<RT> {
325
329
isolate : & mut RequestScope < ' _ , ' _ , RT , Self > ,
326
330
router_path : & CanonicalizedUdfPath ,
327
331
http_request : HttpActionRequest ,
332
+ cancellation : BoxFuture < ' _ , ( ) > ,
328
333
) -> anyhow:: Result < ( HttpActionRoute , Result < HttpActionResponse , JsError > ) > {
329
334
let handle = isolate. handle ( ) ;
330
335
let mut v8_scope = isolate. scope ( ) ;
@@ -415,6 +420,7 @@ impl<RT: Runtime> ActionEnvironment<RT> {
415
420
v8_function,
416
421
& v8_args,
417
422
Self :: collect_http_result,
423
+ cancellation,
418
424
)
419
425
. await ?;
420
426
Ok ( ( route, result) )
@@ -478,6 +484,7 @@ impl<RT: Runtime> ActionEnvironment<RT> {
478
484
isolate : & mut Isolate < RT > ,
479
485
isolate_clean : & mut bool ,
480
486
request_params : ActionRequestParams ,
487
+ cancellation : BoxFuture < ' _ , ( ) > ,
481
488
) -> anyhow:: Result < ActionOutcome > {
482
489
let client_id = Arc :: new ( client_id) ;
483
490
let start_unix_timestamp = self . rt . unix_timestamp ( ) ;
@@ -493,8 +500,13 @@ impl<RT: Runtime> ActionEnvironment<RT> {
493
500
let mut isolate_context =
494
501
RequestScope :: new ( & mut context_scope, handle. clone ( ) , state, true ) . await ?;
495
502
496
- let mut result =
497
- Self :: run_action_inner ( client_id, & mut isolate_context, request_params. clone ( ) ) . await ;
503
+ let mut result = Self :: run_action_inner (
504
+ client_id,
505
+ & mut isolate_context,
506
+ request_params. clone ( ) ,
507
+ cancellation,
508
+ )
509
+ . await ;
498
510
499
511
// Perform a microtask checkpoint one last time before taking the environment
500
512
// to ensure the microtask queue is empty. Otherwise, JS from this request may
@@ -539,6 +551,7 @@ impl<RT: Runtime> ActionEnvironment<RT> {
539
551
client_id : Arc < String > ,
540
552
isolate : & mut RequestScope < ' _ , ' _ , RT , Self > ,
541
553
request_params : ActionRequestParams ,
554
+ cancellation : BoxFuture < ' _ , ( ) > ,
542
555
) -> anyhow:: Result < Result < ConvexValue , JsError > > {
543
556
let handle = isolate. handle ( ) ;
544
557
let mut v8_scope = isolate. scope ( ) ;
@@ -625,6 +638,7 @@ impl<RT: Runtime> ActionEnvironment<RT> {
625
638
let result = deserialize_udf_result ( & udf_path, & result_str) ?;
626
639
Ok ( async move { Ok ( result) } )
627
640
} ,
641
+ cancellation,
628
642
)
629
643
. await
630
644
}
@@ -752,6 +766,7 @@ impl<RT: Runtime> ActionEnvironment<RT> {
752
766
& mut ExecutionScope < ' a , ' b , RT , Self > ,
753
767
String ,
754
768
) -> anyhow:: Result < Fut > ,
769
+ cancellation : BoxFuture < ' _ , ( ) > ,
755
770
) -> anyhow:: Result < Result < T , JsError > >
756
771
where
757
772
Fut : Future < Output = anyhow:: Result < Result < T , JsError > > > + Send + ' static ,
@@ -784,6 +799,7 @@ impl<RT: Runtime> ActionEnvironment<RT> {
784
799
// collecting a result. Using None would be nice, but `select_biased!`
785
800
// does not like Options.
786
801
let mut collecting_result = ( async { std:: future:: pending ( ) . await } ) . boxed ( ) . fuse ( ) ;
802
+ let mut cancellation = cancellation. fuse ( ) ;
787
803
let result = loop {
788
804
// Advance the user's promise as far as it can go by draining the microtask
789
805
// queue.
@@ -914,6 +930,10 @@ impl<RT: Runtime> ActionEnvironment<RT> {
914
930
_ = timeout. fuse( ) => {
915
931
continue ;
916
932
} ,
933
+ _ = cancellation => {
934
+ log_isolate_request_cancelled( ) ;
935
+ anyhow:: bail!( "Cancelled" ) ;
936
+ } ,
917
937
}
918
938
let permit_acquire = scope. with_state_mut ( |state| {
919
939
state
0 commit comments