1- use lambda_runtime:: { Error , LambdaEvent , Service } ;
2- use serde:: { Deserialize , Serialize } ;
31use std:: {
42 future:: { ready, Future } ,
53 pin:: Pin ,
4+ sync:: atomic:: { AtomicBool , Ordering } ,
65} ;
6+
7+ use lambda_runtime:: { Error , LambdaEvent , Service } ;
8+ use serde:: { Deserialize , Serialize } ;
79use tracing:: info;
810
911#[ derive( Deserialize , Debug ) ]
@@ -16,9 +18,30 @@ struct Response {
1618 message : String ,
1719}
1820
19- #[ derive( Default ) ]
2021struct MyHandler {
2122 invoke_count : usize ,
23+ ready : AtomicBool ,
24+ }
25+
26+ impl Default for MyHandler {
27+ fn default ( ) -> Self {
28+ Self {
29+ invoke_count : usize:: default ( ) ,
30+ // New instances are not ready to be called until polled.
31+ ready : false . into ( ) ,
32+ }
33+ }
34+ }
35+
36+ impl Clone for MyHandler {
37+ fn clone ( & self ) -> Self {
38+ Self {
39+ invoke_count : self . invoke_count ,
40+ // Cloned instances may not be immediately ready to be called.
41+ // https://docs.rs/tower/0.4.13/tower/trait.Service.html#be-careful-when-cloning-inner-services
42+ ready : false . into ( ) ,
43+ }
44+ }
2245}
2346
2447impl Service < LambdaEvent < Request > > for MyHandler {
@@ -27,12 +50,30 @@ impl Service<LambdaEvent<Request>> for MyHandler {
2750 type Response = Response ;
2851
2952 fn poll_ready ( & mut self , _cx : & mut core:: task:: Context < ' _ > ) -> core:: task:: Poll < Result < ( ) , Self :: Error > > {
53+ if self . ready . swap ( true , Ordering :: SeqCst ) {
54+ info ! ( "[runtime-trait] Service was already ready" ) ;
55+ } else {
56+ info ! ( "[runtime-trait] Service is now ready" ) ;
57+ } ;
58+
3059 core:: task:: Poll :: Ready ( Ok ( ( ) ) )
3160 }
3261
3362 fn call ( & mut self , request : LambdaEvent < Request > ) -> Self :: Future {
3463 self . invoke_count += 1 ;
35- info ! ( "[handler] Received event {}: {:?}" , self . invoke_count, request) ;
64+ info ! ( "[runtime-trait] Received event {}: {:?}" , self . invoke_count, request) ;
65+
66+ // After being called once, the service is no longer ready until polled again.
67+ if self . ready . swap ( false , Ordering :: SeqCst ) {
68+ info ! ( "[runtime-trait] The service is ready" ) ;
69+ } else {
70+ // https://docs.rs/tower/latest/tower/trait.Service.html#backpressure
71+ // https://docs.rs/tower/latest/tower/trait.Service.html#be-careful-when-cloning-inner-services
72+ // > Services are permitted to panic if `call` is invoked without obtaining
73+ // > `Poll::Ready(Ok(()))` from `poll_ready`.
74+ panic ! ( "[runtime-trait] The service is not ready; `.poll_ready()` must be called first" ) ;
75+ }
76+
3677 Box :: pin ( ready ( Ok ( Response {
3778 message : request. payload . command . to_uppercase ( ) ,
3879 } ) ) )
0 commit comments