Skip to content

Commit 69a3cd6

Browse files
authored
Don’t create an EventLoopFuture chain (#4)
motivation: prevent memory bloat changes: * recurse instead of event loop chain * fix flaky test
1 parent 8777630 commit 69a3cd6

File tree

2 files changed

+31
-17
lines changed

2 files changed

+31
-17
lines changed

Sources/SwiftAwsLambda/Lambda.swift

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ public enum Lambda {
119119
let runner = LambdaRunner(eventLoop: self.eventLoop, configuration: self.configuration, lambdaHandler: self.handler)
120120
return runner.initialize(logger: logger).flatMap { _ in
121121
self.state = .active
122-
return self.run(logger: logger, runner: runner, count: 0)
122+
return self.run(runner: runner)
123123
}
124124
}
125125

@@ -133,23 +133,37 @@ public enum Lambda {
133133
self.state = .shutdown
134134
}
135135

136-
private func run(logger: Logger, runner: LambdaRunner, count: Int) -> EventLoopFuture<Int> {
137-
switch self.state {
138-
case .active:
139-
if self.configuration.lifecycle.maxTimes > 0, count >= self.configuration.lifecycle.maxTimes {
140-
return self.eventLoop.makeSucceededFuture(count)
136+
@inline(__always)
137+
private func run(runner: LambdaRunner) -> EventLoopFuture<Int> {
138+
let promise = self.eventLoop.makePromise(of: Int.self)
139+
140+
func _run(_ count: Int) {
141+
switch self.state {
142+
case .active:
143+
if self.configuration.lifecycle.maxTimes > 0, count >= self.configuration.lifecycle.maxTimes {
144+
return promise.succeed(count)
145+
}
146+
var logger = self.logger
147+
logger[metadataKey: "lifecycleIteration"] = "\(count)"
148+
runner.run(logger: logger).whenComplete { result in
149+
switch result {
150+
case .success:
151+
// recursive! per aws lambda runtime spec the polling requests are to be done one at a time
152+
_run(count + 1)
153+
case .failure(let error):
154+
promise.fail(error)
155+
}
156+
}
157+
case .stopping, .shutdown:
158+
promise.succeed(count)
159+
default:
160+
preconditionFailure("invalid run state: \(self.state)")
141161
}
142-
var logger = logger
143-
logger[metadataKey: "lifecycleIteration"] = "\(count)"
144-
return runner.run(logger: logger).flatMap { _ in
145-
// recursive! per aws lambda runtime spec the polling requests are to be done one at a time
146-
self.run(logger: logger, runner: runner, count: count + 1)
147-
}
148-
case .stopping, .shutdown:
149-
return self.eventLoop.makeSucceededFuture(count)
150-
default:
151-
preconditionFailure("invalid run state: \(self.state)")
152162
}
163+
164+
_run(0)
165+
166+
return promise.futureResult
153167
}
154168
}
155169

Tests/SwiftAwsLambdaTests/LambdaTest.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ class LambdaTest: XCTestCase {
7979
}
8080
}
8181
let signal = Signal.ALRM
82-
let maxTimes = 50
82+
let maxTimes = 1000
8383
let configuration = Lambda.Configuration(lifecycle: .init(maxTimes: maxTimes, stopSignal: signal))
8484
let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: System.coreCount)
8585
let future = Lambda.runAsync(eventLoopGroup: eventLoopGroup, handler: MyHandler(), configuration: configuration)

0 commit comments

Comments
 (0)