1use crate::context::{
2 CallFuture, DurableFuture, InvocationHandle, Request, RequestTarget, RunClosure, RunFuture,
3 RunRetryPolicy, SendHandle,
4};
5use crate::endpoint::futures::async_result_poll::VmAsyncResultPollFuture;
6use crate::endpoint::futures::durable_future_impl::DurableFutureImpl;
7use crate::endpoint::futures::intercept_error::InterceptErrorFuture;
8use crate::endpoint::futures::select_poll::VmSelectAsyncResultPollFuture;
9use crate::endpoint::futures::trap::TrapFuture;
10use crate::endpoint::handler_state::HandlerStateNotifier;
11use crate::endpoint::{Error, ErrorInner, InputReceiver, OutputSender};
12use crate::errors::{HandlerErrorInner, HandlerResult, TerminalError};
13use crate::serde::{Deserialize, Serialize};
14use futures::future::{BoxFuture, Either, Shared};
15use futures::{FutureExt, TryFutureExt};
16use pin_project_lite::pin_project;
17use restate_sdk_shared_core::{
18 AttachInvocationTarget, AwaitResponse, AwakeableHandle, CoreVM, Error as CoreError, Header,
19 NonEmptyValue, NotificationHandle, OnMaxAttempts, PayloadOptions, RetryPolicy, RunExitResult,
20 RunHandle, Target, TerminalFailure, UnresolvedFuture, VM, Value,
21};
22use std::borrow::Cow;
23use std::collections::HashMap;
24use std::future::{Future, poll_fn, ready};
25use std::marker::PhantomData;
26use std::mem;
27use std::pin::Pin;
28use std::sync::{Arc, Mutex};
29use std::task::{Context, Poll, ready};
30use std::time::{Duration, Instant, SystemTime};
31
32pub struct ContextInternalInner {
33 pub(crate) vm: CoreVM,
34 pub(crate) read: InputReceiver,
35 pub(crate) write: OutputSender,
36 pub(super) handler_state: HandlerStateNotifier,
37
38 pub(super) span_replaying_field_state: bool,
41}
42
43impl ContextInternalInner {
44 fn new(
45 vm: CoreVM,
46 read: InputReceiver,
47 write: OutputSender,
48 handler_state: HandlerStateNotifier,
49 ) -> Self {
50 Self {
51 vm,
52 read,
53 write,
54 handler_state,
55 span_replaying_field_state: false,
56 }
57 }
58
59 pub(super) fn fail(&mut self, e: Error) {
60 self.maybe_flip_span_replaying_field();
61 self.vm.notify_error(
62 CoreError::new(500u16, e.0.to_string())
63 .with_stacktrace(Cow::<str>::Owned(format!("{:#}", e.0))),
64 None,
65 );
66 self.handler_state.mark_error(e);
67 }
68
69 pub(super) fn maybe_flip_span_replaying_field(&mut self) {
70 if !self.span_replaying_field_state && self.vm.state().is_replaying() {
71 tracing::Span::current().record("restate.sdk.is_replaying", true);
72 self.span_replaying_field_state = true;
73 } else if self.span_replaying_field_state && !self.vm.state().is_replaying() {
74 tracing::Span::current().record("restate.sdk.is_replaying", false);
75 self.span_replaying_field_state = false;
76 }
77 }
78}
79
80#[allow(unused)]
81const fn is_send_sync<T: Send + Sync>() {}
82const _: () = is_send_sync::<ContextInternal>();
83
84macro_rules! must_lock {
85 ($mutex:expr) => {
86 $mutex.try_lock().expect("You're trying to await two futures at the same time and/or trying to perform some operation on the restate context while awaiting a future. This is not supported!")
87 };
88}
89
90macro_rules! unwrap_or_trap {
91 ($inner_lock:expr, $res:expr) => {
92 match $res {
93 Ok(t) => t,
94 Err(e) => {
95 $inner_lock.fail(e.into());
96 return Either::Right(TrapFuture::default());
97 }
98 }
99 };
100}
101
102macro_rules! unwrap_or_trap_durable_future {
103 ($ctx:expr, $inner_lock:expr, $res:expr) => {
104 match $res {
105 Ok(t) => t,
106 Err(e) => {
107 $inner_lock.fail(e.into());
108 return DurableFutureImpl::new(
109 $ctx.clone(),
110 NotificationHandle::from(u32::MAX),
111 Either::Right(TrapFuture::default()),
112 );
113 }
114 }
115 };
116}
117
118#[derive(Debug, Eq, PartialEq)]
119pub struct InputMetadata {
120 pub invocation_id: String,
121 pub random_seed: u64,
122 pub key: String,
123 pub headers: http::HeaderMap<String>,
124 pub scope: Option<String>,
125 pub limit_key: Option<String>,
126 pub idempotency_key: Option<String>,
127}
128
129impl From<RequestTarget> for Target {
130 fn from(value: RequestTarget) -> Self {
131 match value {
132 RequestTarget::Service { name, handler } => Target {
133 service: name,
134 handler,
135 key: None,
136 idempotency_key: None,
137 scope: None,
138 limit_key: None,
139 headers: vec![],
140 },
141 RequestTarget::Object { name, key, handler } => Target {
142 service: name,
143 handler,
144 key: Some(key),
145 idempotency_key: None,
146 scope: None,
147 limit_key: None,
148 headers: vec![],
149 },
150 RequestTarget::Workflow { name, key, handler } => Target {
151 service: name,
152 handler,
153 key: Some(key),
154 idempotency_key: None,
155 scope: None,
156 limit_key: None,
157 headers: vec![],
158 },
159 }
160 }
161}
162
163#[derive(Clone)]
167pub struct ContextInternal {
168 svc_name: String,
169 handler_name: String,
170 inner: Arc<Mutex<ContextInternalInner>>,
171}
172
173impl ContextInternal {
174 pub(super) fn new(
175 vm: CoreVM,
176 svc_name: String,
177 handler_name: String,
178 read: InputReceiver,
179 write: OutputSender,
180 handler_state: HandlerStateNotifier,
181 ) -> Self {
182 Self {
183 svc_name,
184 handler_name,
185 inner: Arc::new(Mutex::new(ContextInternalInner::new(
186 vm,
187 read,
188 write,
189 handler_state,
190 ))),
191 }
192 }
193
194 pub fn service_name(&self) -> &str {
195 &self.svc_name
196 }
197
198 pub fn handler_name(&self) -> &str {
199 &self.handler_name
200 }
201
202 pub fn input<T: Deserialize>(&self) -> impl Future<Output = (T, InputMetadata)> {
203 let mut inner_lock = must_lock!(self.inner);
204 let input_result =
205 inner_lock
206 .vm
207 .sys_input()
208 .map_err(ErrorInner::VM)
209 .map(|mut raw_input| {
210 let headers = http::HeaderMap::<String>::try_from(
211 &raw_input
212 .headers
213 .into_iter()
214 .map(|h| (h.key.to_string(), h.value.to_string()))
215 .collect::<HashMap<String, String>>(),
216 )
217 .map_err(|e| {
218 TerminalError::new_with_code(400, format!("Cannot decode headers: {e:?}"))
219 })?;
220
221 Ok::<_, TerminalError>((
222 T::deserialize(&mut (raw_input.input)).map_err(|e| {
223 TerminalError::new_with_code(
224 400,
225 format!("Cannot decode input payload: {e:?}"),
226 )
227 })?,
228 InputMetadata {
229 invocation_id: raw_input.invocation_id,
230 random_seed: raw_input.random_seed,
231 key: raw_input.key,
232 headers,
233 scope: raw_input.scope,
234 limit_key: raw_input.limit_key,
235 idempotency_key: raw_input.idempotency_key,
236 },
237 ))
238 });
239 inner_lock.maybe_flip_span_replaying_field();
240
241 match input_result {
242 Ok(Ok(i)) => {
243 drop(inner_lock);
244 return Either::Left(ready(i));
245 }
246 Ok(Err(err)) => {
247 let error_inner = ErrorInner::Deserialization {
248 syscall: "input",
249 err: err.0.clone().into(),
250 };
251 let _ = inner_lock.vm.sys_write_output(
252 NonEmptyValue::Failure(err.into()),
253 PayloadOptions::default(),
254 );
255 let _ = inner_lock.vm.sys_end();
256 inner_lock.handler_state.mark_error(error_inner.into());
258 drop(inner_lock);
259 }
260 Err(e) => {
261 inner_lock.fail(e.into());
262 drop(inner_lock);
263 }
264 }
265 Either::Right(TrapFuture::default())
266 }
267
268 pub fn get<T: Deserialize>(
269 &self,
270 key: &str,
271 ) -> impl Future<Output = Result<Option<T>, TerminalError>> + Send {
272 let mut inner_lock = must_lock!(self.inner);
273 let handle = unwrap_or_trap!(
274 inner_lock,
275 inner_lock
276 .vm
277 .sys_state_get(key.to_owned(), PayloadOptions::default())
278 );
279 inner_lock.maybe_flip_span_replaying_field();
280
281 let poll_future = get_async_result(Arc::clone(&self.inner), handle).map(|res| match res {
282 Ok(Value::Void) => Ok(Ok(None)),
283 Ok(Value::Success(mut s)) => {
284 let t =
285 T::deserialize(&mut s).map_err(|e| Error::deserialization("get_state", e))?;
286 Ok(Ok(Some(t)))
287 }
288 Ok(Value::Failure(f)) => Ok(Err(f.into())),
289 Ok(v) => Err(ErrorInner::UnexpectedValueVariantForSyscall {
290 variant: <&'static str>::from(v),
291 syscall: "get_state",
292 }
293 .into()),
294 Err(e) => Err(e),
295 });
296
297 Either::Left(InterceptErrorFuture::new(self.clone(), poll_future))
298 }
299
300 pub fn get_keys(&self) -> impl Future<Output = Result<Vec<String>, TerminalError>> + Send {
301 let mut inner_lock = must_lock!(self.inner);
302 let handle = unwrap_or_trap!(inner_lock, inner_lock.vm.sys_state_get_keys());
303 inner_lock.maybe_flip_span_replaying_field();
304
305 let poll_future = get_async_result(Arc::clone(&self.inner), handle).map(|res| match res {
306 Ok(Value::Failure(f)) => Ok(Err(f.into())),
307 Ok(Value::StateKeys(s)) => Ok(Ok(s)),
308 Ok(v) => Err(ErrorInner::UnexpectedValueVariantForSyscall {
309 variant: <&'static str>::from(v),
310 syscall: "get_keys",
311 }
312 .into()),
313 Err(e) => Err(e),
314 });
315
316 Either::Left(InterceptErrorFuture::new(self.clone(), poll_future))
317 }
318
319 pub fn set<T: Serialize>(&self, key: &str, t: T) {
320 let mut inner_lock = must_lock!(self.inner);
321 match t.serialize() {
322 Ok(b) => {
323 let _ = inner_lock
324 .vm
325 .sys_state_set(key.to_owned(), b, PayloadOptions::default());
326 inner_lock.maybe_flip_span_replaying_field();
327 }
328 Err(e) => {
329 inner_lock.fail(Error::serialization("set_state", e));
330 }
331 }
332 }
333
334 pub fn clear(&self, key: &str) {
335 let mut inner_lock = must_lock!(self.inner);
336 let _ = inner_lock.vm.sys_state_clear(key.to_string());
337 inner_lock.maybe_flip_span_replaying_field();
338 }
339
340 pub fn clear_all(&self) {
341 let mut inner_lock = must_lock!(self.inner);
342 let _ = inner_lock.vm.sys_state_clear_all();
343 inner_lock.maybe_flip_span_replaying_field();
344 }
345
346 pub fn select(
347 &self,
348 handles: Vec<NotificationHandle>,
349 ) -> impl Future<Output = Result<usize, TerminalError>> + Send {
350 InterceptErrorFuture::new(
351 self.clone(),
352 VmSelectAsyncResultPollFuture::new(self.inner.clone(), handles).map_err(Error::from),
353 )
354 }
355
356 pub fn sleep(
357 &self,
358 sleep_duration: Duration,
359 ) -> impl DurableFuture<Output = Result<(), TerminalError>> + Send {
360 let now = SystemTime::now()
361 .duration_since(SystemTime::UNIX_EPOCH)
362 .expect("Duration since unix epoch cannot fail");
363 let mut inner_lock = must_lock!(self.inner);
364 let handle = unwrap_or_trap_durable_future!(
365 self,
366 inner_lock,
367 inner_lock
368 .vm
369 .sys_sleep(String::default(), now + sleep_duration, Some(now))
370 );
371 inner_lock.maybe_flip_span_replaying_field();
372
373 let poll_future = get_async_result(Arc::clone(&self.inner), handle).map(|res| match res {
374 Ok(Value::Void) => Ok(Ok(())),
375 Ok(Value::Failure(f)) => Ok(Err(f.into())),
376 Ok(v) => Err(ErrorInner::UnexpectedValueVariantForSyscall {
377 variant: <&'static str>::from(v),
378 syscall: "sleep",
379 }
380 .into()),
381 Err(e) => Err(e),
382 });
383
384 DurableFutureImpl::new(self.clone(), handle, Either::Left(poll_future))
385 }
386
387 pub fn request<Req, Res>(
388 &self,
389 request_target: RequestTarget,
390 req: Req,
391 ) -> Request<'_, Req, Res> {
392 Request::new(self, request_target, req)
393 }
394
395 pub fn call<Req: Serialize, Res: Deserialize>(
396 &self,
397 request_target: RequestTarget,
398 idempotency_key: Option<String>,
399 scope: Option<String>,
400 limit_key: Option<String>,
401 headers: Vec<(String, String)>,
402 req: Req,
403 ) -> impl CallFuture<Response = Res> + Send {
404 let mut inner_lock = must_lock!(self.inner);
405
406 let mut target: Target = request_target.into();
407 target.idempotency_key = idempotency_key;
408 target.scope = scope;
409 target.limit_key = limit_key;
410 target.headers = headers
411 .into_iter()
412 .map(|(k, v)| Header {
413 key: k.into(),
414 value: v.into(),
415 })
416 .collect();
417 let call_result = Req::serialize(&req)
418 .map_err(|e| Error::serialization("call", e))
419 .and_then(|input| {
420 inner_lock
421 .vm
422 .sys_call(target, input, None, PayloadOptions::default())
423 .map_err(Into::into)
424 });
425
426 let call_handle = match call_result {
427 Ok(t) => t,
428 Err(e) => {
429 inner_lock.fail(e);
430 return CallFutureImpl {
431 invocation_id_future: Either::Right(TrapFuture::default()).shared(),
432 result_future: Either::Right(TrapFuture::default()),
433 call_notification_handle: NotificationHandle::from(u32::MAX),
434 ctx: self.clone(),
435 };
436 }
437 };
438 inner_lock.maybe_flip_span_replaying_field();
439 drop(inner_lock);
440
441 let invocation_id_fut = InterceptErrorFuture::new(
443 self.clone(),
444 get_async_result(
445 Arc::clone(&self.inner),
446 call_handle.invocation_id_notification_handle,
447 )
448 .map(|res| match res {
449 Ok(Value::Failure(f)) => Ok(Err(f.into())),
450 Ok(Value::InvocationId(s)) => Ok(Ok(s)),
451 Ok(v) => Err(ErrorInner::UnexpectedValueVariantForSyscall {
452 variant: <&'static str>::from(v),
453 syscall: "call",
454 }
455 .into()),
456 Err(e) => Err(e),
457 }),
458 );
459 let result_future = get_async_result(
460 Arc::clone(&self.inner),
461 call_handle.call_notification_handle,
462 )
463 .map(|res| match res {
464 Ok(Value::Success(mut s)) => Ok(Ok(
465 Res::deserialize(&mut s).map_err(|e| Error::deserialization("call", e))?
466 )),
467 Ok(Value::Failure(f)) => Ok(Err(TerminalError::from(f))),
468 Ok(v) => Err(ErrorInner::UnexpectedValueVariantForSyscall {
469 variant: <&'static str>::from(v),
470 syscall: "call",
471 }
472 .into()),
473 Err(e) => Err(e),
474 });
475
476 CallFutureImpl {
477 invocation_id_future: Either::Left(invocation_id_fut).shared(),
478 result_future: Either::Left(result_future),
479 call_notification_handle: call_handle.call_notification_handle,
480 ctx: self.clone(),
481 }
482 }
483
484 #[allow(clippy::too_many_arguments)]
485 pub fn send<Req: Serialize>(
486 &self,
487 request_target: RequestTarget,
488 idempotency_key: Option<String>,
489 scope: Option<String>,
490 limit_key: Option<String>,
491 headers: Vec<(String, String)>,
492 req: Req,
493 delay: Option<Duration>,
494 ) -> SendHandle {
495 let mut inner_lock = must_lock!(self.inner);
496
497 let mut target: Target = request_target.into();
498 target.idempotency_key = idempotency_key;
499 target.scope = scope;
500 target.limit_key = limit_key;
501 target.headers = headers
502 .into_iter()
503 .map(|(k, v)| Header {
504 key: k.into(),
505 value: v.into(),
506 })
507 .collect();
508 let input = match Req::serialize(&req) {
509 Ok(b) => b,
510 Err(e) => {
511 inner_lock.fail(Error::serialization("send", e));
512 return SendHandle::new(self.clone(), TrapFuture::default().boxed());
513 }
514 };
515
516 let send_handle = match inner_lock.vm.sys_send(
517 target,
518 input,
519 delay.map(|delay| {
520 SystemTime::now()
521 .duration_since(SystemTime::UNIX_EPOCH)
522 .expect("Duration since unix epoch cannot fail")
523 + delay
524 }),
525 None,
526 PayloadOptions::default(),
527 ) {
528 Ok(h) => h,
529 Err(e) => {
530 inner_lock.fail(e.into());
531 return SendHandle::new(self.clone(), TrapFuture::default().boxed());
532 }
533 };
534 inner_lock.maybe_flip_span_replaying_field();
535 drop(inner_lock);
536
537 let invocation_id_fut = InterceptErrorFuture::new(
538 self.clone(),
539 get_async_result(
540 Arc::clone(&self.inner),
541 send_handle.invocation_id_notification_handle,
542 )
543 .map(|res| match res {
544 Ok(Value::Failure(f)) => Ok(Err(f.into())),
545 Ok(Value::InvocationId(s)) => Ok(Ok(s)),
546 Ok(v) => Err(ErrorInner::UnexpectedValueVariantForSyscall {
547 variant: <&'static str>::from(v),
548 syscall: "send",
549 }
550 .into()),
551 Err(e) => Err(e),
552 }),
553 );
554
555 SendHandle::new(self.clone(), invocation_id_fut.boxed())
556 }
557
558 pub fn invocation_handle(&self, invocation_id: String) -> InvocationHandle {
559 InvocationHandle::new(self.clone(), invocation_id)
560 }
561
562 pub fn cancel_invocation(&self, invocation_id: &str) {
564 let mut inner_lock = must_lock!(self.inner);
565 let _ = inner_lock
566 .vm
567 .sys_cancel_invocation(invocation_id.to_owned());
568 inner_lock.maybe_flip_span_replaying_field();
569 }
570
571 pub fn attach_invocation<T: Deserialize + 'static>(
573 &self,
574 invocation_id: String,
575 ) -> impl DurableFuture<Output = Result<T, TerminalError>> + Send + use<T> {
576 let mut inner_lock = must_lock!(self.inner);
577 let handle = unwrap_or_trap_durable_future!(
578 self,
579 inner_lock,
580 inner_lock
581 .vm
582 .sys_attach_invocation(AttachInvocationTarget::InvocationId(invocation_id))
583 );
584 inner_lock.maybe_flip_span_replaying_field();
585 drop(inner_lock);
586
587 let poll_future = get_async_result(Arc::clone(&self.inner), handle).map(|res| match res {
588 Ok(Value::Success(mut s)) => Ok(Ok(T::deserialize(&mut s)
589 .map_err(|e| Error::deserialization("attach_invocation", e))?)),
590 Ok(Value::Failure(f)) => Ok(Err(f.into())),
591 Ok(v) => Err(ErrorInner::UnexpectedValueVariantForSyscall {
592 variant: <&'static str>::from(v),
593 syscall: "attach_invocation",
594 }
595 .into()),
596 Err(e) => Err(e),
597 });
598
599 DurableFutureImpl::new(self.clone(), handle, Either::Left(poll_future))
600 }
601
602 pub fn signal<T: Deserialize + 'static>(
604 &self,
605 name: &str,
606 ) -> impl DurableFuture<Output = Result<T, TerminalError>> + Send + use<T> {
607 let mut inner_lock = must_lock!(self.inner);
608 let handle = unwrap_or_trap_durable_future!(
609 self,
610 inner_lock,
611 inner_lock.vm.create_signal_handle(name.to_owned())
612 );
613 inner_lock.maybe_flip_span_replaying_field();
614 drop(inner_lock);
615
616 let poll_future = get_async_result(Arc::clone(&self.inner), handle).map(|res| match res {
617 Ok(Value::Success(mut s)) => {
618 let t = T::deserialize(&mut s).map_err(|e| Error::deserialization("signal", e))?;
619 Ok(Ok(t))
620 }
621 Ok(Value::Failure(f)) => Ok(Err(f.into())),
622 Ok(v) => Err(ErrorInner::UnexpectedValueVariantForSyscall {
623 variant: <&'static str>::from(v),
624 syscall: "signal",
625 }
626 .into()),
627 Err(e) => Err(e),
628 });
629
630 DurableFutureImpl::new(self.clone(), handle, Either::Left(poll_future))
631 }
632
633 pub fn resolve_signal<T: Serialize>(&self, invocation_id: &str, name: &str, t: T) {
635 let mut inner_lock = must_lock!(self.inner);
636 match t.serialize() {
637 Ok(b) => {
638 let _ = inner_lock.vm.sys_complete_signal(
639 invocation_id.to_owned(),
640 name.to_owned(),
641 NonEmptyValue::Success(b),
642 );
643 }
644 Err(e) => {
645 inner_lock.fail(Error::serialization("resolve_signal", e));
646 }
647 }
648 }
649
650 pub fn reject_signal(&self, invocation_id: &str, name: &str, failure: TerminalError) {
652 let _ = must_lock!(self.inner).vm.sys_complete_signal(
653 invocation_id.to_owned(),
654 name.to_owned(),
655 NonEmptyValue::Failure(failure.into()),
656 );
657 }
658
659 pub fn awakeable<T: Deserialize>(
660 &self,
661 ) -> (
662 String,
663 impl DurableFuture<Output = Result<T, TerminalError>> + Send,
664 ) {
665 let mut inner_lock = must_lock!(self.inner);
666 let maybe_awakeable_id_and_handle = inner_lock.vm.sys_awakeable();
667 inner_lock.maybe_flip_span_replaying_field();
668
669 let (awakeable_id, handle) = match maybe_awakeable_id_and_handle {
670 Ok(AwakeableHandle { id, handle }) => (id, handle),
671 Err(e) => {
672 inner_lock.fail(e.into());
673 return (
674 "invalid".to_owned(),
677 DurableFutureImpl::new(
678 self.clone(),
679 NotificationHandle::from(u32::MAX),
680 Either::Right(TrapFuture::default()),
681 ),
682 );
683 }
684 };
685 drop(inner_lock);
686
687 let poll_future = get_async_result(Arc::clone(&self.inner), handle).map(|res| match res {
688 Ok(Value::Success(mut s)) => Ok(Ok(
689 T::deserialize(&mut s).map_err(|e| Error::deserialization("awakeable", e))?
690 )),
691 Ok(Value::Failure(f)) => Ok(Err(f.into())),
692 Ok(v) => Err(ErrorInner::UnexpectedValueVariantForSyscall {
693 variant: <&'static str>::from(v),
694 syscall: "awakeable",
695 }
696 .into()),
697 Err(e) => Err(e),
698 });
699
700 (
701 awakeable_id,
702 DurableFutureImpl::new(self.clone(), handle, Either::Left(poll_future)),
703 )
704 }
705
706 pub fn resolve_awakeable<T: Serialize>(&self, id: &str, t: T) {
707 let mut inner_lock = must_lock!(self.inner);
708 match t.serialize() {
709 Ok(b) => {
710 let _ = inner_lock.vm.sys_complete_awakeable(
711 id.to_owned(),
712 NonEmptyValue::Success(b),
713 PayloadOptions::default(),
714 );
715 }
716 Err(e) => {
717 inner_lock.fail(Error::serialization("resolve_awakeable", e));
718 }
719 }
720 }
721
722 pub fn reject_awakeable(&self, id: &str, failure: TerminalError) {
723 let _ = must_lock!(self.inner).vm.sys_complete_awakeable(
724 id.to_owned(),
725 NonEmptyValue::Failure(failure.into()),
726 PayloadOptions::default(),
727 );
728 }
729
730 pub fn promise<T: Deserialize>(
731 &self,
732 name: &str,
733 ) -> impl DurableFuture<Output = Result<T, TerminalError>> + Send {
734 let mut inner_lock = must_lock!(self.inner);
735 let handle = unwrap_or_trap_durable_future!(
736 self,
737 inner_lock,
738 inner_lock.vm.sys_get_promise(name.to_owned())
739 );
740 inner_lock.maybe_flip_span_replaying_field();
741 drop(inner_lock);
742
743 let poll_future = get_async_result(Arc::clone(&self.inner), handle).map(|res| match res {
744 Ok(Value::Success(mut s)) => {
745 let t = T::deserialize(&mut s).map_err(|e| Error::deserialization("promise", e))?;
746 Ok(Ok(t))
747 }
748 Ok(Value::Failure(f)) => Ok(Err(f.into())),
749 Ok(v) => Err(ErrorInner::UnexpectedValueVariantForSyscall {
750 variant: <&'static str>::from(v),
751 syscall: "promise",
752 }
753 .into()),
754 Err(e) => Err(e),
755 });
756
757 DurableFutureImpl::new(self.clone(), handle, Either::Left(poll_future))
758 }
759
760 pub fn peek_promise<T: Deserialize>(
761 &self,
762 name: &str,
763 ) -> impl Future<Output = Result<Option<T>, TerminalError>> + Send {
764 let mut inner_lock = must_lock!(self.inner);
765 let handle = unwrap_or_trap!(inner_lock, inner_lock.vm.sys_peek_promise(name.to_owned()));
766 inner_lock.maybe_flip_span_replaying_field();
767 drop(inner_lock);
768
769 let poll_future = get_async_result(Arc::clone(&self.inner), handle).map(|res| match res {
770 Ok(Value::Void) => Ok(Ok(None)),
771 Ok(Value::Success(mut s)) => {
772 let t = T::deserialize(&mut s)
773 .map_err(|e| Error::deserialization("peek_promise", e))?;
774 Ok(Ok(Some(t)))
775 }
776 Ok(Value::Failure(f)) => Ok(Err(f.into())),
777 Ok(v) => Err(ErrorInner::UnexpectedValueVariantForSyscall {
778 variant: <&'static str>::from(v),
779 syscall: "peek_promise",
780 }
781 .into()),
782 Err(e) => Err(e),
783 });
784
785 Either::Left(InterceptErrorFuture::new(self.clone(), poll_future))
786 }
787
788 pub fn resolve_promise<T: Serialize>(&self, name: &str, t: T) {
789 let mut inner_lock = must_lock!(self.inner);
790 match t.serialize() {
791 Ok(b) => {
792 let _ = inner_lock.vm.sys_complete_promise(
793 name.to_owned(),
794 NonEmptyValue::Success(b),
795 PayloadOptions::default(),
796 );
797 }
798 Err(e) => {
799 inner_lock.fail(
800 ErrorInner::Serialization {
801 syscall: "resolve_promise",
802 err: Box::new(e),
803 }
804 .into(),
805 );
806 }
807 }
808 }
809
810 pub fn reject_promise(&self, id: &str, failure: TerminalError) {
811 let _ = must_lock!(self.inner).vm.sys_complete_promise(
812 id.to_owned(),
813 NonEmptyValue::Failure(failure.into()),
814 PayloadOptions::default(),
815 );
816 }
817
818 pub fn run<'a, Run, Fut, Out>(
819 &'a self,
820 run_closure: Run,
821 ) -> impl RunFuture<Result<Out, TerminalError>> + Send + 'a
822 where
823 Run: RunClosure<Fut = Fut, Output = Out> + Send + 'a,
824 Fut: Future<Output = HandlerResult<Out>> + Send + 'a,
825 Out: Serialize + Deserialize + 'static,
826 {
827 let this = Arc::clone(&self.inner);
828 InterceptErrorFuture::new(self.clone(), RunFutureImpl::new(this, run_closure))
829 }
830
831 pub fn handle_handler_result<T: Serialize>(&self, res: HandlerResult<T>) {
833 let mut inner_lock = must_lock!(self.inner);
834
835 let res_to_write = match res {
836 Ok(success) => match T::serialize(&success) {
837 Ok(t) => NonEmptyValue::Success(t),
838 Err(e) => {
839 inner_lock.fail(
840 ErrorInner::Serialization {
841 syscall: "output",
842 err: Box::new(e),
843 }
844 .into(),
845 );
846 return;
847 }
848 },
849 Err(e) => match e.0 {
850 HandlerErrorInner::Retryable(err) => {
851 inner_lock.fail(ErrorInner::HandlerResult { err }.into());
852 return;
853 }
854 HandlerErrorInner::Terminal(t) => NonEmptyValue::Failure(TerminalError(t).into()),
855 },
856 };
857
858 let _ = inner_lock
859 .vm
860 .sys_write_output(res_to_write, PayloadOptions::default());
861 inner_lock.maybe_flip_span_replaying_field();
862 }
863
864 pub fn end(&self) {
865 let _ = must_lock!(self.inner).vm.sys_end();
866 }
867
868 pub(crate) fn consume_to_end(&self) {
869 let mut inner_lock = must_lock!(self.inner);
870
871 let b = inner_lock.vm.take_output();
872 if !b.is_empty() && !inner_lock.write.send(b) {
873 }
875 }
876
877 pub(crate) async fn drain_input(&self) -> Result<(), ErrorInner> {
882 tokio::time::timeout(Duration::from_secs(60), async {
883 loop {
884 let result = poll_fn(|cx| {
885 let mut inner = must_lock!(self.inner);
886 inner.read.poll_recv(cx)
887 })
888 .await;
889 match result {
890 None => return Ok(()),
891 Some(Ok(_)) => continue,
892 Some(Err(e)) => return Err(ErrorInner::InputDrain(e)),
893 }
894 }
895 })
896 .await
897 .unwrap_or_else(|_| {
898 Err(ErrorInner::InputDrain(
899 "Timed out draining input stream after 60s".into(),
900 ))
901 })
902 }
903
904 pub(super) fn fail(&self, e: Error) {
905 must_lock!(self.inner).fail(e)
906 }
907}
908
909pin_project! {
910 struct RunFutureImpl<Run, Ret, RunFnFut> {
911 name: String,
912 retry_policy: RetryPolicy,
913 phantom_data: PhantomData<fn() -> Ret>,
914 #[pin]
915 state: RunState<Run, RunFnFut, Ret>,
916 }
917}
918
919pin_project! {
920 #[project = RunStateProj]
921 enum RunState<Run, RunFnFut, Ret> {
922 New {
923 ctx: Option<Arc<Mutex<ContextInternalInner>>>,
924 closure: Option<Run>,
925 },
926 ClosureRunning {
927 ctx: Option<Arc<Mutex<ContextInternalInner>>>,
928 handle: NotificationHandle,
929 start_time: Instant,
930 #[pin]
931 closure_fut: RunFnFut,
932 },
933 WaitingResultFut {
934 result_fut: BoxFuture<'static, Result<Result<Ret, TerminalError>, Error>>
935 }
936 }
937}
938
939impl<Run, Ret, RunFnFut> RunFutureImpl<Run, Ret, RunFnFut> {
940 fn new(ctx: Arc<Mutex<ContextInternalInner>>, closure: Run) -> Self {
941 Self {
942 name: "".to_string(),
943 retry_policy: RetryPolicy::Infinite,
944 phantom_data: PhantomData,
945 state: RunState::New {
946 ctx: Some(ctx),
947 closure: Some(closure),
948 },
949 }
950 }
951
952 fn boxed_result_fut(
953 ctx: Arc<Mutex<ContextInternalInner>>,
954 handle: NotificationHandle,
955 ) -> BoxFuture<'static, Result<Result<Ret, TerminalError>, Error>>
956 where
957 Ret: Deserialize,
958 {
959 get_async_result(Arc::clone(&ctx), handle)
960 .map(|res| match res {
961 Ok(Value::Success(mut s)) => {
962 let t =
963 Ret::deserialize(&mut s).map_err(|e| Error::deserialization("run", e))?;
964 Ok(Ok(t))
965 }
966 Ok(Value::Failure(f)) => Ok(Err(f.into())),
967 Ok(v) => Err(ErrorInner::UnexpectedValueVariantForSyscall {
968 variant: <&'static str>::from(v),
969 syscall: "run",
970 }
971 .into()),
972 Err(e) => Err(e),
973 })
974 .boxed()
975 }
976}
977
978impl<Run, Ret, RunFnFut> RunFuture<Result<Result<Ret, TerminalError>, Error>>
979 for RunFutureImpl<Run, Ret, RunFnFut>
980where
981 Run: RunClosure<Fut = RunFnFut, Output = Ret> + Send,
982 Ret: Serialize + Deserialize,
983 RunFnFut: Future<Output = HandlerResult<Ret>> + Send,
984{
985 fn retry_policy(mut self, retry_policy: RunRetryPolicy) -> Self {
986 self.retry_policy = RetryPolicy::Exponential {
987 initial_interval: retry_policy.initial_delay,
988 factor: retry_policy.factor,
989 max_interval: retry_policy.max_delay,
990 max_attempts: retry_policy.max_attempts,
991 max_duration: retry_policy.max_duration,
992 on_max_attempts: OnMaxAttempts::FailAsTerminal,
993 };
994 self
995 }
996
997 fn name(mut self, name: impl Into<String>) -> Self {
998 self.name = name.into();
999 self
1000 }
1001}
1002
1003impl<Run, Ret, RunFnFut> Future for RunFutureImpl<Run, Ret, RunFnFut>
1004where
1005 Run: RunClosure<Fut = RunFnFut, Output = Ret> + Send,
1006 Ret: Serialize + Deserialize,
1007 RunFnFut: Future<Output = HandlerResult<Ret>> + Send,
1008{
1009 type Output = Result<Result<Ret, TerminalError>, Error>;
1010
1011 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
1012 let mut this = self.project();
1013
1014 loop {
1015 match this.state.as_mut().project() {
1016 RunStateProj::New { ctx, closure, .. } => {
1017 let ctx = ctx
1018 .take()
1019 .expect("Future should not be polled after returning Poll::Ready");
1020 let closure = closure
1021 .take()
1022 .expect("Future should not be polled after returning Poll::Ready");
1023 let mut inner_ctx = must_lock!(ctx);
1024
1025 let RunHandle { handle, .. } = inner_ctx
1026 .vm
1027 .sys_run(this.name.to_owned())
1028 .map_err(ErrorInner::from)?;
1029
1030 let b = inner_ctx.vm.take_output();
1033 if !b.is_empty() && !inner_ctx.write.send(b) {
1034 return Poll::Ready(Err(ErrorInner::Suspended.into()));
1035 }
1036
1037 match inner_ctx.vm.do_await(UnresolvedFuture::Single(handle)) {
1039 Ok(AwaitResponse::ExecuteRun(handle_to_run)) => {
1040 assert_eq!(handle, handle_to_run);
1043
1044 drop(inner_ctx);
1045 this.state.set(RunState::ClosureRunning {
1046 ctx: Some(ctx),
1047 handle,
1048 start_time: Instant::now(),
1049 closure_fut: closure.run(),
1050 });
1051 }
1052 Ok(AwaitResponse::CancelSignalReceived) => {
1053 drop(inner_ctx);
1054 this.state.set(RunState::WaitingResultFut {
1056 result_fut: async {
1057 Ok(Err(TerminalError::from(TerminalFailure {
1058 code: 409,
1059 message: "cancelled".to_string(),
1060 metadata: vec![],
1061 })))
1062 }
1063 .boxed(),
1064 })
1065 }
1066 _ => {
1067 drop(inner_ctx);
1068 this.state.set(RunState::WaitingResultFut {
1072 result_fut: Self::boxed_result_fut(Arc::clone(&ctx), handle),
1073 })
1074 }
1075 }
1076 }
1077 RunStateProj::ClosureRunning {
1078 ctx,
1079 handle,
1080 start_time,
1081 closure_fut,
1082 } => {
1083 let res = match ready!(closure_fut.poll(cx)) {
1084 Ok(t) => RunExitResult::Success(Ret::serialize(&t).map_err(|e| {
1085 ErrorInner::Serialization {
1086 syscall: "run",
1087 err: Box::new(e),
1088 }
1089 })?),
1090 Err(e) => match e.0 {
1091 HandlerErrorInner::Retryable(err) => RunExitResult::RetryableFailure {
1092 attempt_duration: start_time.elapsed(),
1093 error: CoreError::new(500u16, err.to_string()),
1094 },
1095 HandlerErrorInner::Terminal(t) => {
1096 RunExitResult::TerminalFailure(TerminalError(t).into())
1097 }
1098 },
1099 };
1100
1101 let ctx = ctx
1102 .take()
1103 .expect("Future should not be polled after returning Poll::Ready");
1104 let handle = *handle;
1105
1106 let _ = {
1107 must_lock!(ctx).vm.propose_run_completion(
1108 handle,
1109 res,
1110 mem::take(this.retry_policy),
1111 )
1112 };
1113
1114 this.state.set(RunState::WaitingResultFut {
1115 result_fut: Self::boxed_result_fut(Arc::clone(&ctx), handle),
1116 });
1117 }
1118 RunStateProj::WaitingResultFut { result_fut } => return result_fut.poll_unpin(cx),
1119 }
1120 }
1121 }
1122}
1123
1124pin_project! {
1125 struct CallFutureImpl<InvIdFut: Future, ResultFut> {
1126 #[pin]
1127 invocation_id_future: Shared<InvIdFut>,
1128 #[pin]
1129 result_future: ResultFut,
1130 call_notification_handle: NotificationHandle,
1131 ctx: ContextInternal,
1132 }
1133}
1134
1135impl<InvIdFut, ResultFut, Res> Future for CallFutureImpl<InvIdFut, ResultFut>
1136where
1137 InvIdFut: Future<Output = Result<String, TerminalError>> + Send,
1138 ResultFut: Future<Output = Result<Result<Res, TerminalError>, Error>> + Send,
1139{
1140 type Output = Result<Res, TerminalError>;
1141
1142 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
1143 let this = self.project();
1144 let result = ready!(this.result_future.poll(cx));
1145
1146 match result {
1147 Ok(r) => Poll::Ready(r),
1148 Err(e) => {
1149 this.ctx.fail(e);
1150
1151 cx.waker().wake_by_ref();
1154 Poll::Pending
1155 }
1156 }
1157 }
1158}
1159
1160impl<InvIdFut, ResultFut, Res> CallFuture for CallFutureImpl<InvIdFut, ResultFut>
1161where
1162 InvIdFut: Future<Output = Result<String, TerminalError>> + Send,
1163 ResultFut: Future<Output = Result<Result<Res, TerminalError>, Error>> + Send,
1164{
1165 type Response = Res;
1166
1167 fn invocation_handle(
1168 &self,
1169 ) -> impl Future<Output = Result<InvocationHandle, TerminalError>> + Send {
1170 let invocation_id_fut = Shared::clone(&self.invocation_id_future);
1171 let ctx = self.ctx.clone();
1172 async move {
1173 let invocation_id = invocation_id_fut.await?;
1174 Ok(ctx.invocation_handle(invocation_id))
1175 }
1176 }
1177
1178 fn invocation_id(&self) -> impl Future<Output = Result<String, TerminalError>> + Send {
1179 Shared::clone(&self.invocation_id_future)
1180 }
1181}
1182
1183impl<InvIdFut, ResultFut> crate::context::macro_support::SealedDurableFuture
1184 for CallFutureImpl<InvIdFut, ResultFut>
1185where
1186 InvIdFut: Future,
1187{
1188 fn inner_context(&self) -> ContextInternal {
1189 self.ctx.clone()
1190 }
1191
1192 fn handle(&self) -> NotificationHandle {
1193 self.call_notification_handle
1194 }
1195}
1196
1197impl<InvIdFut, ResultFut, Res> DurableFuture for CallFutureImpl<InvIdFut, ResultFut>
1198where
1199 InvIdFut: Future<Output = Result<String, TerminalError>> + Send,
1200 ResultFut: Future<Output = Result<Result<Res, TerminalError>, Error>> + Send,
1201{
1202}
1203
1204impl Error {
1205 fn serialization<E: std::error::Error + Send + Sync + 'static>(
1206 syscall: &'static str,
1207 e: E,
1208 ) -> Self {
1209 ErrorInner::Serialization {
1210 syscall,
1211 err: Box::new(e),
1212 }
1213 .into()
1214 }
1215
1216 fn deserialization<E: std::error::Error + Send + Sync + 'static>(
1217 syscall: &'static str,
1218 e: E,
1219 ) -> Self {
1220 ErrorInner::Deserialization {
1221 syscall,
1222 err: Box::new(e),
1223 }
1224 .into()
1225 }
1226}
1227
1228fn get_async_result(
1229 ctx: Arc<Mutex<ContextInternalInner>>,
1230 handle: NotificationHandle,
1231) -> impl Future<Output = Result<Value, Error>> + Send {
1232 VmAsyncResultPollFuture::new(ctx, handle).map_err(Error::from)
1233}