@@ -21,12 +21,14 @@ extension Lambda {
2121 internal final class Runner {
2222 private let runtimeClient : RuntimeClient
2323 private let eventLoop : EventLoop
24+ private let allocator : ByteBufferAllocator
2425
2526 private var isGettingNextInvocation = false
2627
2728 init ( eventLoop: EventLoop , configuration: Configuration ) {
2829 self . eventLoop = eventLoop
2930 self . runtimeClient = RuntimeClient ( eventLoop: self . eventLoop, configuration: configuration. runtimeEngine)
31+ self . allocator = ByteBufferAllocator ( )
3032 }
3133
3234 /// Run the user provided initializer. This *must* only be called once.
@@ -36,13 +38,22 @@ extension Lambda {
3638 logger. debug ( " initializing lambda " )
3739 // 1. create the handler from the factory
3840 // 2. report initialization error if one occured
39- return factory ( self . eventLoop) . hop ( to: self . eventLoop) . peekError { error in
40- self . runtimeClient. reportInitializationError ( logger: logger, error: error) . peekError { reportingError in
41- // We're going to bail out because the init failed, so there's not a lot we can do other than log
42- // that we couldn't report this error back to the runtime.
43- logger. error ( " failed reporting initialization error to lambda runtime engine: \( reportingError) " )
41+ let context = InitializationContext ( logger: logger,
42+ eventLoop: self . eventLoop,
43+ allocator: self . allocator)
44+ return factory ( context)
45+ // Hopping back to "our" EventLoop is importnant in case the factory returns a future
46+ // that originated from a foreign EventLoop/EventLoopGroup.
47+ // This can happen if the factory uses a library (let's say a database client) that manages its own threads/loops
48+ // for whatever reason and returns a future that originated from that foreign EventLoop.
49+ . hop ( to: self . eventLoop)
50+ . peekError { error in
51+ self . runtimeClient. reportInitializationError ( logger: logger, error: error) . peekError { reportingError in
52+ // We're going to bail out because the init failed, so there's not a lot we can do other than log
53+ // that we couldn't report this error back to the runtime.
54+ logger. error ( " failed reporting initialization error to lambda runtime engine: \( reportingError) " )
55+ }
4456 }
45- }
4657 }
4758
4859 func run( logger: Logger , handler: Handler ) -> EventLoopFuture < Void > {
@@ -54,9 +65,17 @@ extension Lambda {
5465 } . flatMap { invocation, event in
5566 // 2. send invocation to handler
5667 self . isGettingNextInvocation = false
57- let context = Context ( logger: logger, eventLoop: self . eventLoop, invocation: invocation)
68+ let context = Context ( logger: logger,
69+ eventLoop: self . eventLoop,
70+ allocator: self . allocator,
71+ invocation: invocation)
5872 logger. debug ( " sending invocation to lambda handler \( handler) " )
5973 return handler. handle ( context: context, event: event)
74+ // Hopping back to "our" EventLoop is importnant in case the handler returns a future that
75+ // originiated from a foreign EventLoop/EventLoopGroup.
76+ // This can happen if the handler uses a library (lets say a DB client) that manages its own threads/loops
77+ // for whatever reason and returns a future that originated from that foreign EventLoop.
78+ . hop ( to: self . eventLoop)
6079 . mapResult { result in
6180 if case . failure( let error) = result {
6281 logger. warning ( " lambda handler returned an error: \( error) " )
@@ -82,15 +101,16 @@ extension Lambda {
82101}
83102
84103private extension Lambda . Context {
85- convenience init ( logger: Logger , eventLoop: EventLoop , invocation: Lambda . Invocation ) {
104+ convenience init ( logger: Logger , eventLoop: EventLoop , allocator : ByteBufferAllocator , invocation: Lambda . Invocation ) {
86105 self . init ( requestID: invocation. requestID,
87106 traceID: invocation. traceID,
88107 invokedFunctionARN: invocation. invokedFunctionARN,
89108 deadline: DispatchWallTime ( millisSinceEpoch: invocation. deadlineInMillisSinceEpoch) ,
90109 cognitoIdentity: invocation. cognitoIdentity,
91110 clientContext: invocation. clientContext,
92111 logger: logger,
93- eventLoop: eventLoop)
112+ eventLoop: eventLoop,
113+ allocator: allocator)
94114 }
95115}
96116
0 commit comments