@@ -19,10 +19,8 @@ import Darwin.C
19
19
#endif
20
20
21
21
import Backtrace
22
- import Dispatch
23
22
import Logging
24
23
import NIO
25
- import NIOConcurrencyHelpers
26
24
27
25
public enum Lambda {
28
26
/// Run a Lambda defined by implementing the `LambdaClosure` closure.
@@ -113,248 +111,6 @@ public enum Lambda {
113
111
signalSource. cancel ( )
114
112
}
115
113
}
116
-
117
- public class Context {
118
- /// The request ID, which identifies the request that triggered the function invocation.
119
- public let requestId : String
120
-
121
- /// The AWS X-Ray tracing header.
122
- public let traceId : String
123
-
124
- /// The ARN of the Lambda function, version, or alias that's specified in the invocation.
125
- public let invokedFunctionArn : String
126
-
127
- /// The timestamp that the function times out
128
- public let deadline : DispatchWallTime
129
-
130
- /// For invocations from the AWS Mobile SDK, data about the Amazon Cognito identity provider.
131
- public let cognitoIdentity : String ?
132
-
133
- /// For invocations from the AWS Mobile SDK, data about the client application and device.
134
- public let clientContext : String ?
135
-
136
- /// a logger to log
137
- public let logger : Logger
138
-
139
- internal init ( requestId: String ,
140
- traceId: String ,
141
- invokedFunctionArn: String ,
142
- deadline: DispatchWallTime ,
143
- cognitoIdentity: String ? = nil ,
144
- clientContext: String ? = nil ,
145
- logger: Logger ) {
146
- self . requestId = requestId
147
- self . traceId = traceId
148
- self . invokedFunctionArn = invokedFunctionArn
149
- self . cognitoIdentity = cognitoIdentity
150
- self . clientContext = clientContext
151
- self . deadline = deadline
152
- // mutate logger with context
153
- var logger = logger
154
- logger [ metadataKey: " awsRequestId " ] = . string( requestId)
155
- logger [ metadataKey: " awsTraceId " ] = . string( traceId)
156
- self . logger = logger
157
- }
158
-
159
- public func getRemainingTime( ) -> TimeAmount {
160
- let deadline = self . deadline. millisSinceEpoch
161
- let now = DispatchWallTime . now ( ) . millisSinceEpoch
162
-
163
- let remaining = deadline - now
164
- return . milliseconds( remaining)
165
- }
166
- }
167
-
168
- private final class Lifecycle {
169
- private let eventLoop : EventLoop
170
- private let logger : Logger
171
- private let configuration : Configuration
172
- private let factory : LambdaHandlerFactory
173
-
174
- private var _state = State . idle
175
- private let stateLock = Lock ( )
176
-
177
- init ( eventLoop: EventLoop , logger: Logger , configuration: Configuration , factory: @escaping LambdaHandlerFactory ) {
178
- self . eventLoop = eventLoop
179
- self . logger = logger
180
- self . configuration = configuration
181
- self . factory = factory
182
- }
183
-
184
- deinit {
185
- guard case . shutdown = self . state else {
186
- preconditionFailure ( " invalid state \( self . state) " )
187
- }
188
- }
189
-
190
- private var state : State {
191
- get {
192
- return self . stateLock. withLock {
193
- self . _state
194
- }
195
- }
196
- set {
197
- self . stateLock. withLockVoid {
198
- precondition ( newValue. order > _state. order, " invalid state \( newValue) after \( self . _state) " )
199
- self . _state = newValue
200
- }
201
- }
202
- }
203
-
204
- func start( ) -> EventLoopFuture < Int > {
205
- logger. info ( " lambda lifecycle starting with \( self . configuration) " )
206
- self . state = . initializing
207
- var logger = self . logger
208
- logger [ metadataKey: " lifecycleId " ] = . string( self . configuration. lifecycle. id)
209
- let runner = LambdaRunner ( eventLoop: self . eventLoop, configuration: self . configuration)
210
- return runner. initialize ( logger: logger, factory: self . factory) . flatMap { handler in
211
- self . state = . active( runner, handler)
212
- return self . run ( )
213
- }
214
- }
215
-
216
- func stop( ) {
217
- self . logger. debug ( " lambda lifecycle stopping " )
218
- self . state = . stopping
219
- }
220
-
221
- func shutdown( ) {
222
- self . logger. debug ( " lambda lifecycle shutdown " )
223
- self . state = . shutdown
224
- }
225
-
226
- @inline ( __always)
227
- private func run( ) -> EventLoopFuture < Int > {
228
- let promise = self . eventLoop. makePromise ( of: Int . self)
229
-
230
- func _run( _ count: Int ) {
231
- switch self . state {
232
- case . active( let runner, let handler) :
233
- if self . configuration. lifecycle. maxTimes > 0 , count >= self . configuration. lifecycle. maxTimes {
234
- return promise. succeed ( count)
235
- }
236
- var logger = self . logger
237
- logger [ metadataKey: " lifecycleIteration " ] = " \( count) "
238
- runner. run ( logger: logger, handler: handler) . whenComplete { result in
239
- switch result {
240
- case . success:
241
- // recursive! per aws lambda runtime spec the polling requests are to be done one at a time
242
- _run ( count + 1 )
243
- case . failure( let error) :
244
- promise. fail ( error)
245
- }
246
- }
247
- case . stopping, . shutdown:
248
- promise. succeed ( count)
249
- default :
250
- preconditionFailure ( " invalid run state: \( self . state) " )
251
- }
252
- }
253
-
254
- _run ( 0 )
255
-
256
- return promise. futureResult
257
- }
258
-
259
- private enum State {
260
- case idle
261
- case initializing
262
- case active( LambdaRunner , LambdaHandler )
263
- case stopping
264
- case shutdown
265
-
266
- internal var order : Int {
267
- switch self {
268
- case . idle:
269
- return 0
270
- case . initializing:
271
- return 1
272
- case . active:
273
- return 2
274
- case . stopping:
275
- return 3
276
- case . shutdown:
277
- return 4
278
- }
279
- }
280
- }
281
- }
282
-
283
- @usableFromInline
284
- internal struct Configuration : CustomStringConvertible {
285
- let general : General
286
- let lifecycle : Lifecycle
287
- let runtimeEngine : RuntimeEngine
288
-
289
- @usableFromInline
290
- init ( ) {
291
- self . init ( general: . init( ) , lifecycle: . init( ) , runtimeEngine: . init( ) )
292
- }
293
-
294
- init ( general: General ? = nil , lifecycle: Lifecycle ? = nil , runtimeEngine: RuntimeEngine ? = nil ) {
295
- self . general = general ?? General ( )
296
- self . lifecycle = lifecycle ?? Lifecycle ( )
297
- self . runtimeEngine = runtimeEngine ?? RuntimeEngine ( )
298
- }
299
-
300
- struct General : CustomStringConvertible {
301
- let logLevel : Logger . Level
302
-
303
- init ( logLevel: Logger . Level ? = nil ) {
304
- self . logLevel = logLevel ?? env ( " LOG_LEVEL " ) . flatMap ( Logger . Level. init) ?? . info
305
- }
306
-
307
- var description : String {
308
- return " \( General . self) (logLevel: \( self . logLevel) ) "
309
- }
310
- }
311
-
312
- struct Lifecycle : CustomStringConvertible {
313
- let id : String
314
- let maxTimes : Int
315
- let stopSignal : Signal
316
-
317
- init ( id: String ? = nil , maxTimes: Int ? = nil , stopSignal: Signal ? = nil ) {
318
- self . id = id ?? " \( DispatchTime . now ( ) . uptimeNanoseconds) "
319
- self . maxTimes = maxTimes ?? env ( " MAX_REQUESTS " ) . flatMap ( Int . init) ?? 0
320
- self . stopSignal = stopSignal ?? env ( " STOP_SIGNAL " ) . flatMap ( Int32 . init) . flatMap ( Signal . init) ?? Signal . TERM
321
- precondition ( self . maxTimes >= 0 , " maxTimes must be equal or larger than 0 " )
322
- }
323
-
324
- var description : String {
325
- return " \( Lifecycle . self) (id: \( self . id) , maxTimes: \( self . maxTimes) , stopSignal: \( self . stopSignal) ) "
326
- }
327
- }
328
-
329
- struct RuntimeEngine : CustomStringConvertible {
330
- let ip : String
331
- let port : Int
332
- let keepAlive : Bool
333
- let requestTimeout : TimeAmount ?
334
- let offload : Bool
335
-
336
- init ( baseURL: String ? = nil , keepAlive: Bool ? = nil , requestTimeout: TimeAmount ? = nil , offload: Bool ? = nil ) {
337
- let ipPort = env ( " AWS_LAMBDA_RUNTIME_API " ) ? . split ( separator: " : " ) ?? [ " 127.0.0.1 " , " 7000 " ]
338
- guard ipPort. count == 2 , let port = Int ( ipPort [ 1 ] ) else {
339
- preconditionFailure ( " invalid ip+port configuration \( ipPort) " )
340
- }
341
- self . ip = String ( ipPort [ 0 ] )
342
- self . port = port
343
- self . keepAlive = keepAlive ?? env ( " KEEP_ALIVE " ) . flatMap ( Bool . init) ?? true
344
- self . requestTimeout = requestTimeout ?? env ( " REQUEST_TIMEOUT " ) . flatMap ( Int64 . init) . flatMap { . milliseconds( $0) }
345
- self . offload = offload ?? env ( " OFFLOAD " ) . flatMap ( Bool . init) ?? false
346
- }
347
-
348
- var description : String {
349
- return " \( RuntimeEngine . self) (ip: \( self . ip) , port: \( self . port) , keepAlive: \( self . keepAlive) , requestTimeout: \( String ( describing: self . requestTimeout) ) , offload: \( self . offload) "
350
- }
351
- }
352
-
353
- @usableFromInline
354
- var description : String {
355
- return " \( Configuration . self) \n \( self . general) ) \n \( self . lifecycle) \n \( self . runtimeEngine) "
356
- }
357
- }
358
114
}
359
115
360
116
public typealias LambdaResult = Result < [ UInt8 ] , Error >
0 commit comments