-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathrequest.rs
141 lines (127 loc) · 3.73 KB
/
request.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
use super::DurableFuture;
use crate::endpoint::ContextInternal;
use crate::errors::TerminalError;
use crate::serde::{Deserialize, Serialize};
use std::fmt;
use std::future::Future;
use std::marker::PhantomData;
use std::time::Duration;
/// Target of a request to a Restate service.
#[derive(Debug, Clone)]
pub enum RequestTarget {
Service {
name: String,
handler: String,
},
Object {
name: String,
key: String,
handler: String,
},
Workflow {
name: String,
key: String,
handler: String,
},
}
impl RequestTarget {
pub fn service(name: impl Into<String>, handler: impl Into<String>) -> Self {
Self::Service {
name: name.into(),
handler: handler.into(),
}
}
pub fn object(
name: impl Into<String>,
key: impl Into<String>,
handler: impl Into<String>,
) -> Self {
Self::Object {
name: name.into(),
key: key.into(),
handler: handler.into(),
}
}
pub fn workflow(
name: impl Into<String>,
key: impl Into<String>,
handler: impl Into<String>,
) -> Self {
Self::Workflow {
name: name.into(),
key: key.into(),
handler: handler.into(),
}
}
}
impl fmt::Display for RequestTarget {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
RequestTarget::Service { name, handler } => write!(f, "{name}/{handler}"),
RequestTarget::Object { name, key, handler } => write!(f, "{name}/{key}/{handler}"),
RequestTarget::Workflow { name, key, handler } => write!(f, "{name}/{key}/{handler}"),
}
}
}
/// This struct encapsulates the parameters for a request to a service.
pub struct Request<'a, Req, Res = ()> {
ctx: &'a ContextInternal,
request_target: RequestTarget,
idempotency_key: Option<String>,
req: Req,
res: PhantomData<Res>,
}
impl<'a, Req, Res> Request<'a, Req, Res> {
pub(crate) fn new(ctx: &'a ContextInternal, request_target: RequestTarget, req: Req) -> Self {
Self {
ctx,
request_target,
idempotency_key: None,
req,
res: PhantomData,
}
}
/// Add idempotency key to the request
pub fn idempotency_key(mut self, idempotency_key: impl Into<String>) -> Self {
self.idempotency_key = Some(idempotency_key.into());
self
}
/// Call a service. This returns a future encapsulating the response.
pub fn call(self) -> impl CallFuture<Response = Res> + Send
where
Req: Serialize + 'static,
Res: Deserialize + 'static,
{
self.ctx
.call(self.request_target, self.idempotency_key, self.req)
}
/// Send the request to the service, without waiting for the response.
pub fn send(self) -> impl InvocationHandle
where
Req: Serialize + 'static,
{
self.ctx
.send(self.request_target, self.idempotency_key, self.req, None)
}
/// Schedule the request to the service, without waiting for the response.
pub fn send_after(self, delay: Duration) -> impl InvocationHandle
where
Req: Serialize + 'static,
{
self.ctx.send(
self.request_target,
self.idempotency_key,
self.req,
Some(delay),
)
}
}
pub trait InvocationHandle {
fn invocation_id(&self) -> impl Future<Output = Result<String, TerminalError>> + Send;
fn cancel(&self) -> impl Future<Output = Result<(), TerminalError>> + Send;
}
pub trait CallFuture:
DurableFuture<Output = Result<Self::Response, TerminalError>> + InvocationHandle
{
type Response;
}