Skip to content

Commit e5b4496

Browse files
authored
Prefix data structures with Lambda instead of namespacing them (#256)
motivation: consisten naming convention changes: * Lambda.InitializationContext -> LambdaInitializationContext * Lambda.Runner -> LambdaRunner * Lambda.Configuration -> LambdaConfiguration * Lambda.RuntimeError -> LambdaRuntimeError * adjust call sites, tests, and examples
1 parent d35e827 commit e5b4496

28 files changed

+352
-359
lines changed

Examples/Benchmark/BenchmarkHandler.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ struct BenchmarkHandler: EventLoopLambdaHandler {
2525
typealias Event = String
2626
typealias Output = String
2727

28-
static func makeHandler(context: Lambda.InitializationContext) -> EventLoopFuture<Self> {
28+
static func makeHandler(context: LambdaInitializationContext) -> EventLoopFuture<Self> {
2929
context.eventLoop.makeSucceededFuture(BenchmarkHandler())
3030
}
3131

Examples/Deployment/Sources/Benchmark/BenchmarkHandler.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ struct BenchmarkHandler: EventLoopLambdaHandler {
2525
typealias Event = String
2626
typealias Output = String
2727

28-
static func makeHandler(context: Lambda.InitializationContext) -> EventLoopFuture<Self> {
28+
static func makeHandler(context: LambdaInitializationContext) -> EventLoopFuture<Self> {
2929
context.eventLoop.makeSucceededFuture(BenchmarkHandler())
3030
}
3131

Examples/Deployment/Sources/HelloWorld/HelloWorldHandler.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ struct HelloWorldHandler: LambdaHandler {
2020
typealias Event = String
2121
typealias Output = String
2222

23-
init(context: Lambda.InitializationContext) async throws {
23+
init(context: LambdaInitializationContext) async throws {
2424
// setup your resources that you want to reuse here.
2525
}
2626

Examples/Echo/Lambda.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ struct MyLambda: LambdaHandler {
2121
typealias Event = String
2222
typealias Output = String
2323

24-
init(context: Lambda.InitializationContext) async throws {
24+
init(context: LambdaInitializationContext) async throws {
2525
// setup your resources that you want to reuse for every invocation here.
2626
}
2727

Examples/ErrorHandling/Lambda.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ struct MyLambda: LambdaHandler {
2121
typealias Event = Request
2222
typealias Output = Response
2323

24-
init(context: Lambda.InitializationContext) async throws {}
24+
init(context: LambdaInitializationContext) async throws {}
2525

2626
func handle(_ request: Request, context: LambdaContext) async throws -> Response {
2727
// switch over the error type "requested" by the request, and trigger such error accordingly

Examples/Foundation/Lambda.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ struct MyLambda: LambdaHandler {
3030

3131
let calculator: ExchangeRatesCalculator
3232

33-
init(context: Lambda.InitializationContext) async throws {
33+
init(context: LambdaInitializationContext) async throws {
3434
// the ExchangeRatesCalculator() can be reused over and over
3535
self.calculator = ExchangeRatesCalculator()
3636
}

Examples/JSON/Lambda.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ struct MyLambda: LambdaHandler {
3030
typealias Event = Request
3131
typealias Output = Response
3232

33-
init(context: Lambda.InitializationContext) async throws {
33+
init(context: LambdaInitializationContext) async throws {
3434
// setup your resources that you want to reuse for every invocation here.
3535
}
3636

Examples/LocalDebugging/MyLambda/Lambda.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ struct MyLambda: LambdaHandler {
2323
typealias Event = Request
2424
typealias Output = Response
2525

26-
init(context: Lambda.InitializationContext) async throws {
26+
init(context: LambdaInitializationContext) async throws {
2727
// setup your resources that you want to reuse for every invocation here.
2828
}
2929

Examples/Testing/Sources/Lambda.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ struct MyLambda: LambdaHandler {
2121
typealias Event = String
2222
typealias Output = String
2323

24-
init(context: Lambda.InitializationContext) async throws {
24+
init(context: LambdaInitializationContext) async throws {
2525
// setup your resources that you want to reuse for every invocation here.
2626
}
2727

Sources/AWSLambdaRuntimeCore/ControlPlaneRequest.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,17 @@ struct Invocation: Hashable {
3838

3939
init(headers: HTTPHeaders) throws {
4040
guard let requestID = headers.first(name: AmazonHeaders.requestID), !requestID.isEmpty else {
41-
throw Lambda.RuntimeError.invocationMissingHeader(AmazonHeaders.requestID)
41+
throw LambdaRuntimeError.invocationMissingHeader(AmazonHeaders.requestID)
4242
}
4343

4444
guard let deadline = headers.first(name: AmazonHeaders.deadline),
4545
let unixTimeInMilliseconds = Int64(deadline)
4646
else {
47-
throw Lambda.RuntimeError.invocationMissingHeader(AmazonHeaders.deadline)
47+
throw LambdaRuntimeError.invocationMissingHeader(AmazonHeaders.deadline)
4848
}
4949

5050
guard let invokedFunctionARN = headers.first(name: AmazonHeaders.invokedFunctionARN) else {
51-
throw Lambda.RuntimeError.invocationMissingHeader(AmazonHeaders.invokedFunctionARN)
51+
throw LambdaRuntimeError.invocationMissingHeader(AmazonHeaders.invokedFunctionARN)
5252
}
5353

5454
self.requestID = requestID

Sources/AWSLambdaRuntimeCore/HTTPClient.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ import NIOPosix
2222
/// This means we can avoid locks and other concurrency concern we would otherwise need to build into the client
2323
internal final class HTTPClient {
2424
private let eventLoop: EventLoop
25-
private let configuration: Lambda.Configuration.RuntimeEngine
25+
private let configuration: LambdaConfiguration.RuntimeEngine
2626
private let targetHost: String
2727

2828
private var state = State.disconnected
2929
private var executing = false
3030

31-
init(eventLoop: EventLoop, configuration: Lambda.Configuration.RuntimeEngine) {
31+
init(eventLoop: EventLoop, configuration: LambdaConfiguration.RuntimeEngine) {
3232
self.eventLoop = eventLoop
3333
self.configuration = configuration
3434
self.targetHost = "\(self.configuration.ip):\(self.configuration.port)"

Sources/AWSLambdaRuntimeCore/Lambda+LocalServer.swift

+2-3
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ extension Lambda {
3535
/// - invocationEndpoint: The endpoint to post events to.
3636
/// - body: Code to run within the context of the mock server. Typically this would be a Lambda.run function call.
3737
///
38-
/// - note: This API is designed stricly for local testing and is behind a DEBUG flag
38+
/// - note: This API is designed strictly for local testing and is behind a DEBUG flag
3939
internal static func withLocalServer<Value>(invocationEndpoint: String? = nil, _ body: @escaping () -> Value) throws -> Value {
4040
let server = LocalLambda.Server(invocationEndpoint: invocationEndpoint)
4141
try server.start().wait()
@@ -55,7 +55,7 @@ private enum LocalLambda {
5555
private let invocationEndpoint: String
5656

5757
public init(invocationEndpoint: String?) {
58-
let configuration = Lambda.Configuration()
58+
let configuration = LambdaConfiguration()
5959
var logger = Logger(label: "LocalLambdaServer")
6060
logger.logLevel = configuration.general.logLevel
6161
self.logger = logger
@@ -299,5 +299,4 @@ private enum LocalLambda {
299299
case cantBind
300300
}
301301
}
302-
303302
#endif

Sources/AWSLambdaRuntimeCore/Lambda.swift

+14-10
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,6 @@ import NIOCore
2424
import NIOPosix
2525

2626
public enum Lambda {
27-
/// Utility to access/read environment variables
28-
public static func env(_ name: String) -> String? {
29-
guard let value = getenv(name) else {
30-
return nil
31-
}
32-
return String(cString: value)
33-
}
34-
3527
/// Run a Lambda defined by implementing the ``ByteBufferLambdaHandler`` protocol.
3628
/// The Runtime will manage the Lambdas application lifecycle automatically. It will invoke the
3729
/// ``ByteBufferLambdaHandler/makeHandler(context:)`` to create a new Handler.
@@ -42,10 +34,10 @@ public enum Lambda {
4234
///
4335
/// - note: This is a blocking operation that will run forever, as its lifecycle is managed by the AWS Lambda Runtime Engine.
4436
internal static func run<Handler: ByteBufferLambdaHandler>(
45-
configuration: Configuration = .init(),
37+
configuration: LambdaConfiguration = .init(),
4638
handlerType: Handler.Type
4739
) -> Result<Int, Error> {
48-
let _run = { (configuration: Configuration) -> Result<Int, Error> in
40+
let _run = { (configuration: LambdaConfiguration) -> Result<Int, Error> in
4941
Backtrace.install()
5042
var logger = Logger(label: "Lambda")
5143
logger.logLevel = configuration.general.logLevel
@@ -97,3 +89,15 @@ public enum Lambda {
9789
#endif
9890
}
9991
}
92+
93+
// MARK: - Public API
94+
95+
extension Lambda {
96+
/// Utility to access/read environment variables
97+
public static func env(_ name: String) -> String? {
98+
guard let value = getenv(name) else {
99+
return nil
100+
}
101+
return String(cString: value)
102+
}
103+
}

Sources/AWSLambdaRuntimeCore/LambdaConfiguration.swift

+49-51
Original file line numberDiff line numberDiff line change
@@ -16,73 +16,71 @@ import Dispatch
1616
import Logging
1717
import NIOCore
1818

19-
extension Lambda {
20-
internal struct Configuration: CustomStringConvertible {
21-
let general: General
22-
let lifecycle: Lifecycle
23-
let runtimeEngine: RuntimeEngine
19+
internal struct LambdaConfiguration: CustomStringConvertible {
20+
let general: General
21+
let lifecycle: Lifecycle
22+
let runtimeEngine: RuntimeEngine
2423

25-
init() {
26-
self.init(general: .init(), lifecycle: .init(), runtimeEngine: .init())
27-
}
24+
init() {
25+
self.init(general: .init(), lifecycle: .init(), runtimeEngine: .init())
26+
}
2827

29-
init(general: General? = nil, lifecycle: Lifecycle? = nil, runtimeEngine: RuntimeEngine? = nil) {
30-
self.general = general ?? General()
31-
self.lifecycle = lifecycle ?? Lifecycle()
32-
self.runtimeEngine = runtimeEngine ?? RuntimeEngine()
33-
}
28+
init(general: General? = nil, lifecycle: Lifecycle? = nil, runtimeEngine: RuntimeEngine? = nil) {
29+
self.general = general ?? General()
30+
self.lifecycle = lifecycle ?? Lifecycle()
31+
self.runtimeEngine = runtimeEngine ?? RuntimeEngine()
32+
}
3433

35-
struct General: CustomStringConvertible {
36-
let logLevel: Logger.Level
34+
struct General: CustomStringConvertible {
35+
let logLevel: Logger.Level
3736

38-
init(logLevel: Logger.Level? = nil) {
39-
self.logLevel = logLevel ?? env("LOG_LEVEL").flatMap(Logger.Level.init) ?? .info
40-
}
41-
42-
var description: String {
43-
"\(General.self)(logLevel: \(self.logLevel))"
44-
}
37+
init(logLevel: Logger.Level? = nil) {
38+
self.logLevel = logLevel ?? Lambda.env("LOG_LEVEL").flatMap(Logger.Level.init) ?? .info
4539
}
4640

47-
struct Lifecycle: CustomStringConvertible {
48-
let id: String
49-
let maxTimes: Int
50-
let stopSignal: Signal
41+
var description: String {
42+
"\(General.self)(logLevel: \(self.logLevel))"
43+
}
44+
}
5145

52-
init(id: String? = nil, maxTimes: Int? = nil, stopSignal: Signal? = nil) {
53-
self.id = id ?? "\(DispatchTime.now().uptimeNanoseconds)"
54-
self.maxTimes = maxTimes ?? env("MAX_REQUESTS").flatMap(Int.init) ?? 0
55-
self.stopSignal = stopSignal ?? env("STOP_SIGNAL").flatMap(Int32.init).flatMap(Signal.init) ?? Signal.TERM
56-
precondition(self.maxTimes >= 0, "maxTimes must be equal or larger than 0")
57-
}
46+
struct Lifecycle: CustomStringConvertible {
47+
let id: String
48+
let maxTimes: Int
49+
let stopSignal: Signal
5850

59-
var description: String {
60-
"\(Lifecycle.self)(id: \(self.id), maxTimes: \(self.maxTimes), stopSignal: \(self.stopSignal))"
61-
}
51+
init(id: String? = nil, maxTimes: Int? = nil, stopSignal: Signal? = nil) {
52+
self.id = id ?? "\(DispatchTime.now().uptimeNanoseconds)"
53+
self.maxTimes = maxTimes ?? Lambda.env("MAX_REQUESTS").flatMap(Int.init) ?? 0
54+
self.stopSignal = stopSignal ?? Lambda.env("STOP_SIGNAL").flatMap(Int32.init).flatMap(Signal.init) ?? Signal.TERM
55+
precondition(self.maxTimes >= 0, "maxTimes must be equal or larger than 0")
6256
}
6357

64-
struct RuntimeEngine: CustomStringConvertible {
65-
let ip: String
66-
let port: Int
67-
let requestTimeout: TimeAmount?
58+
var description: String {
59+
"\(Lifecycle.self)(id: \(self.id), maxTimes: \(self.maxTimes), stopSignal: \(self.stopSignal))"
60+
}
61+
}
6862

69-
init(address: String? = nil, keepAlive: Bool? = nil, requestTimeout: TimeAmount? = nil) {
70-
let ipPort = (address ?? env("AWS_LAMBDA_RUNTIME_API"))?.split(separator: ":") ?? ["127.0.0.1", "7000"]
71-
guard ipPort.count == 2, let port = Int(ipPort[1]) else {
72-
preconditionFailure("invalid ip+port configuration \(ipPort)")
73-
}
74-
self.ip = String(ipPort[0])
75-
self.port = port
76-
self.requestTimeout = requestTimeout ?? env("REQUEST_TIMEOUT").flatMap(Int64.init).flatMap { .milliseconds($0) }
77-
}
63+
struct RuntimeEngine: CustomStringConvertible {
64+
let ip: String
65+
let port: Int
66+
let requestTimeout: TimeAmount?
7867

79-
var description: String {
80-
"\(RuntimeEngine.self)(ip: \(self.ip), port: \(self.port), requestTimeout: \(String(describing: self.requestTimeout))"
68+
init(address: String? = nil, keepAlive: Bool? = nil, requestTimeout: TimeAmount? = nil) {
69+
let ipPort = (address ?? Lambda.env("AWS_LAMBDA_RUNTIME_API"))?.split(separator: ":") ?? ["127.0.0.1", "7000"]
70+
guard ipPort.count == 2, let port = Int(ipPort[1]) else {
71+
preconditionFailure("invalid ip+port configuration \(ipPort)")
8172
}
73+
self.ip = String(ipPort[0])
74+
self.port = port
75+
self.requestTimeout = requestTimeout ?? Lambda.env("REQUEST_TIMEOUT").flatMap(Int64.init).flatMap { .milliseconds($0) }
8276
}
8377

8478
var description: String {
85-
"\(Configuration.self)\n \(self.general))\n \(self.lifecycle)\n \(self.runtimeEngine)"
79+
"\(RuntimeEngine.self)(ip: \(self.ip), port: \(self.port), requestTimeout: \(String(describing: self.requestTimeout))"
8680
}
8781
}
82+
83+
var description: String {
84+
"\(Self.self)\n \(self.general))\n \(self.lifecycle)\n \(self.runtimeEngine)"
85+
}
8886
}

Sources/AWSLambdaRuntimeCore/LambdaContext.swift

+39-41
Original file line numberDiff line numberDiff line change
@@ -24,48 +24,46 @@ import NIOCore
2424

2525
// MARK: - InitializationContext
2626

27-
extension Lambda {
28-
/// Lambda runtime initialization context.
29-
/// The Lambda runtime generates and passes the `InitializationContext` to the Handlers
30-
/// ``ByteBufferLambdaHandler/makeHandler(context:)`` or ``LambdaHandler/init(context:)``
31-
/// as an argument.
32-
public struct InitializationContext: _AWSLambdaSendable {
33-
/// `Logger` to log with
34-
///
35-
/// - note: The `LogLevel` can be configured using the `LOG_LEVEL` environment variable.
36-
public let logger: Logger
37-
38-
/// The `EventLoop` the Lambda is executed on. Use this to schedule work with.
39-
///
40-
/// - note: The `EventLoop` is shared with the Lambda runtime engine and should be handled with extra care.
41-
/// Most importantly the `EventLoop` must never be blocked.
42-
public let eventLoop: EventLoop
43-
44-
/// `ByteBufferAllocator` to allocate `ByteBuffer`
45-
public let allocator: ByteBufferAllocator
46-
47-
/// `Terminator` to register shutdown operations
48-
public let terminator: LambdaTerminator
49-
50-
init(logger: Logger, eventLoop: EventLoop, allocator: ByteBufferAllocator, terminator: LambdaTerminator) {
51-
self.eventLoop = eventLoop
52-
self.logger = logger
53-
self.allocator = allocator
54-
self.terminator = terminator
55-
}
27+
/// Lambda runtime initialization context.
28+
/// The Lambda runtime generates and passes the `LambdaInitializationContext` to the Handlers
29+
/// ``ByteBufferLambdaHandler/makeHandler(context:)`` or ``LambdaHandler/init(context:)``
30+
/// as an argument.
31+
public struct LambdaInitializationContext: _AWSLambdaSendable {
32+
/// `Logger` to log with
33+
///
34+
/// - note: The `LogLevel` can be configured using the `LOG_LEVEL` environment variable.
35+
public let logger: Logger
5636

57-
/// This interface is not part of the public API and must not be used by adopters. This API is not part of semver versioning.
58-
public static func __forTestsOnly(
59-
logger: Logger,
60-
eventLoop: EventLoop
61-
) -> InitializationContext {
62-
InitializationContext(
63-
logger: logger,
64-
eventLoop: eventLoop,
65-
allocator: ByteBufferAllocator(),
66-
terminator: LambdaTerminator()
67-
)
68-
}
37+
/// The `EventLoop` the Lambda is executed on. Use this to schedule work with.
38+
///
39+
/// - note: The `EventLoop` is shared with the Lambda runtime engine and should be handled with extra care.
40+
/// Most importantly the `EventLoop` must never be blocked.
41+
public let eventLoop: EventLoop
42+
43+
/// `ByteBufferAllocator` to allocate `ByteBuffer`
44+
public let allocator: ByteBufferAllocator
45+
46+
/// `Terminator` to register shutdown operations
47+
public let terminator: LambdaTerminator
48+
49+
init(logger: Logger, eventLoop: EventLoop, allocator: ByteBufferAllocator, terminator: LambdaTerminator) {
50+
self.eventLoop = eventLoop
51+
self.logger = logger
52+
self.allocator = allocator
53+
self.terminator = terminator
54+
}
55+
56+
/// This interface is not part of the public API and must not be used by adopters. This API is not part of semver versioning.
57+
public static func __forTestsOnly(
58+
logger: Logger,
59+
eventLoop: EventLoop
60+
) -> LambdaInitializationContext {
61+
LambdaInitializationContext(
62+
logger: logger,
63+
eventLoop: eventLoop,
64+
allocator: ByteBufferAllocator(),
65+
terminator: LambdaTerminator()
66+
)
6967
}
7068
}
7169

0 commit comments

Comments
 (0)