1
- use std:: { error:: Error , result} ;
1
+ use std:: { error:: Error , marker :: PhantomData , result} ;
2
2
3
3
use serde;
4
4
use serde_json;
@@ -12,7 +12,19 @@ use tokio::runtime::Runtime as TokioRuntime;
12
12
const MAX_RETRIES : i8 = 3 ;
13
13
14
14
/// Functions acting as a handler must conform to this type.
15
- pub type Handler < E , O > = fn ( E , Context ) -> Result < O , HandlerError > ;
15
+ pub trait Handler < E , O > {
16
+ /// Run the handler.
17
+ fn run ( & mut self , event : E , ctx : Context ) -> Result < O , HandlerError > ;
18
+ }
19
+
20
+ impl < F , E , O > Handler < E , O > for F
21
+ where
22
+ F : FnMut ( E , Context ) -> Result < O , HandlerError > ,
23
+ {
24
+ fn run ( & mut self , event : E , ctx : Context ) -> Result < O , HandlerError > {
25
+ ( * self ) ( event, ctx)
26
+ }
27
+ }
16
28
17
29
/// Creates a new runtime and begins polling for events using Lambda's Runtime APIs.
18
30
///
@@ -22,9 +34,9 @@ pub type Handler<E, O> = fn(E, Context) -> Result<O, HandlerError>;
22
34
///
23
35
/// # Panics
24
36
/// The function panics if the Lambda environment variables are not set.
25
- pub fn start < E , O > ( f : Handler < E , O > , runtime : Option < TokioRuntime > )
37
+ pub fn start < E , O > ( f : impl Handler < E , O > , runtime : Option < TokioRuntime > )
26
38
where
27
- for < ' invocation > E : serde:: Deserialize < ' invocation > ,
39
+ E : serde:: de :: DeserializeOwned ,
28
40
O : serde:: Serialize ,
29
41
{
30
42
start_with_config ( f, & EnvConfigProvider :: new ( ) , runtime)
@@ -53,9 +65,9 @@ macro_rules! lambda {
53
65
/// The function panics if the `ConfigProvider` returns an error from the `get_runtime_api_endpoint()`
54
66
/// or `get_function_settings()` methods. The panic forces AWS Lambda to terminate the environment
55
67
/// and spin up a new one for the next invocation.
56
- pub ( crate ) fn start_with_config < E , O , C > ( f : Handler < E , O > , config : & C , runtime : Option < TokioRuntime > )
68
+ pub ( crate ) fn start_with_config < E , O , C > ( f : impl Handler < E , O > , config : & C , runtime : Option < TokioRuntime > )
57
69
where
58
- for < ' invocation > E : serde:: Deserialize < ' invocation > ,
70
+ E : serde:: de :: DeserializeOwned ,
59
71
O : serde:: Serialize ,
60
72
C : ConfigProvider ,
61
73
{
@@ -100,12 +112,15 @@ where
100
112
///
101
113
/// # Panics
102
114
/// The function panics if we cannot instantiate a new `RustRuntime` object.
103
- pub ( crate ) fn start_with_runtime_client < E , O > ( f : Handler < E , O > , func_settings : FunctionSettings , client : RuntimeClient )
104
- where
105
- for < ' invocation > E : serde:: Deserialize < ' invocation > ,
115
+ pub ( crate ) fn start_with_runtime_client < E , O > (
116
+ f : impl Handler < E , O > ,
117
+ func_settings : FunctionSettings ,
118
+ client : RuntimeClient ,
119
+ ) where
120
+ E : serde:: de:: DeserializeOwned ,
106
121
O : serde:: Serialize ,
107
122
{
108
- let lambda_runtime: Runtime < E , O > ;
123
+ let mut lambda_runtime: Runtime < _ , E , O > ;
109
124
match Runtime :: new ( f, func_settings, MAX_RETRIES , client) {
110
125
Ok ( r) => lambda_runtime = r,
111
126
Err ( e) => {
@@ -119,15 +134,16 @@ where
119
134
120
135
/// Internal representation of the runtime object that polls for events and communicates
121
136
/// with the Runtime APIs
122
- pub ( super ) struct Runtime < E , O > {
137
+ pub ( super ) struct Runtime < F , E , O > {
123
138
runtime_client : RuntimeClient ,
124
- handler : Handler < E , O > ,
139
+ handler : F ,
125
140
max_retries : i8 ,
126
141
settings : FunctionSettings ,
142
+ _phan : PhantomData < ( E , O ) > ,
127
143
}
128
144
129
145
// generic methods implementation
130
- impl < E , O > Runtime < E , O > {
146
+ impl < F , E , O > Runtime < F , E , O > {
131
147
/// Creates a new instance of the `Runtime` object populated with the environment
132
148
/// settings.
133
149
///
@@ -142,11 +158,11 @@ impl<E, O> Runtime<E, O> {
142
158
/// fails the init if this function returns an error. If we cannot find the
143
159
/// `AWS_LAMBDA_RUNTIME_API` variable in the environment the function panics.
144
160
pub ( super ) fn new (
145
- f : Handler < E , O > ,
161
+ f : F ,
146
162
config : FunctionSettings ,
147
163
retries : i8 ,
148
164
client : RuntimeClient ,
149
- ) -> result:: Result < Runtime < E , O > , RuntimeError > {
165
+ ) -> result:: Result < Self , RuntimeError > {
150
166
debug ! (
151
167
"Creating new runtime with {} max retries for endpoint {}" ,
152
168
retries,
@@ -157,21 +173,23 @@ impl<E, O> Runtime<E, O> {
157
173
settings : config,
158
174
handler : f,
159
175
max_retries : retries,
176
+ _phan : PhantomData ,
160
177
} )
161
178
}
162
179
}
163
180
164
181
// implementation of methods that require the Event and Output types
165
182
// to be compatible with `serde`'s Deserialize/Serialize.
166
- impl < ' env , E , O > Runtime < E , O >
183
+ impl < F , E , O > Runtime < F , E , O >
167
184
where
168
- for < ' de > E : serde:: Deserialize < ' de > ,
185
+ F : Handler < E , O > ,
186
+ E : serde:: de:: DeserializeOwned ,
169
187
O : serde:: Serialize ,
170
188
{
171
189
/// Starts the main event loop and begin polling or new events. If one of the
172
190
/// Runtime APIs returns an unrecoverable error this method calls the init failed
173
191
/// API and then panics.
174
- fn start ( & self ) {
192
+ fn start ( & mut self ) {
175
193
debug ! ( "Beginning main event loop" ) ;
176
194
loop {
177
195
let ( event, ctx) = self . get_next_event ( 0 , None ) ;
@@ -238,8 +256,8 @@ where
238
256
239
257
/// Invoke the handler function. This method is split out of the main loop to
240
258
/// make it testable.
241
- pub ( super ) fn invoke ( & self , e : E , ctx : Context ) -> Result < O , HandlerError > {
242
- ( self . handler ) ( e, ctx)
259
+ pub ( super ) fn invoke ( & mut self , e : E , ctx : Context ) -> Result < O , HandlerError > {
260
+ ( & mut self . handler ) . run ( e, ctx)
243
261
}
244
262
245
263
/// Attempts to get the next event from the Runtime APIs and keeps retrying
0 commit comments