Skip to main content

restate_sdk/endpoint/
context.rs

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    /// We remember here the state of the span replaying field state, because setting it might be expensive (it's guarded behind locks and other stuff).
39    /// For details, see [ContextInternalInner::maybe_flip_span_replaying_field]
40    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/// Internal context interface.
164///
165/// For the high level interfaces, look at [`crate::context`].
166#[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                // This causes the trap, plus logs the error
257                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's prepare the two futures here
442        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    /// Cancel a target invocation (fire-and-forget).
563    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    /// Attach to a target invocation, awaiting its output.
572    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    /// Await a named signal on the current invocation.
603    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    /// Resolve a named signal on a target invocation.
634    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    /// Reject a named signal on a target invocation.
651    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                    // TODO NOW this is REALLY BAD. The reason for this is that we would need to return a future of a future instead, which is not nice.
675                    //  we assume for the time being this works because no user should use the awakeable without doing any other syscall first, which will prevent this invalid awakeable id to work in the first place.
676                    "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    // Used by codegen
832    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            // Nothing we can do anymore here
874        }
875    }
876
877    /// Drain the request input stream to completion.
878    ///
879    /// This ensures we don't close the HTTP/2 response stream before the request
880    /// stream is done, which causes connection errors on proxies like Google Cloud Run.
881    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                    // TODO this is a mitigation for https://github.com/restatedev/sdk-rust/issues/72
1031                    // Should be removed once we correctly support run async
1032                    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                    // Now we do progress once to check whether this closure should be executed or not.
1038                    match inner_ctx.vm.do_await(UnresolvedFuture::Single(handle)) {
1039                        Ok(AwaitResponse::ExecuteRun(handle_to_run)) => {
1040                            // In case it returns ExecuteRun, it must be the handle we just gave it,
1041                            // and it means we need to execute the closure
1042                            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                            // Got cancellation!
1055                            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                            // In all the other cases, just move on waiting the result,
1069                            // the poll future state will take care of doing whatever needs to be done here,
1070                            // that is propagating state machine error, or result, or whatever
1071                            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                // Here is the secret sauce. This will immediately cause the whole future chain to be polled,
1152                //  but the poll here will be intercepted by HandlerStateAwareFuture
1153                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}