Skip to content

Commit a3f75ba

Browse files
author
Andrea Scuderi
committed
Remove BreezeLambdaWebHookService
1 parent b49c718 commit a3f75ba

File tree

7 files changed

+89
-162
lines changed

7 files changed

+89
-162
lines changed

Sources/BreezeDemoHTTPApplication/BreezeDemoHTTPApplication.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,14 @@ struct DemoLambdaHandler: BreezeLambdaWebHookHandler, Sendable {
2929
self.handlerContext = handlerContext
3030
}
3131

32+
var httpClient: HTTPClient {
33+
handlerContext.httpClient
34+
}
35+
3236
func handle(_ event: APIGatewayV2Request, context: LambdaContext) async throws -> APIGatewayV2Response {
3337
context.logger.info("Received event: \(event)")
3438
let request = HTTPClientRequest(url: "https://example.com")
35-
let response = try await handlerContext.httpClient.execute(request, timeout: .seconds(5))
39+
let response = try await httpClient.execute(request, timeout: .seconds(5))
3640
let bytes = try await response.body.collect(upTo: 1024 * 1024) // 1 MB Buffer
3741
let body = String(buffer: bytes)
3842
context.logger.info("Response body: \(body)")

Sources/BreezeLambdaWebHook/BreezeLambdaWebHook.swift

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,18 +53,20 @@ public struct BreezeLambdaWebHook<LambdaHandler: BreezeLambdaWebHookHandler>: Se
5353
/// handling any errors that may occur during the process.
5454
/// It gracefully shuts down the service on termination signals.
5555
public func run() async throws {
56+
let handlerContext = HandlerContext(config: config)
57+
let lambdaHandler = LambdaHandler(handlerContext: handlerContext)
58+
let runtime = LambdaRuntime(body: lambdaHandler.handle)
59+
60+
let serviceGroup = ServiceGroup(
61+
services: [handlerContext, runtime],
62+
gracefulShutdownSignals: [.sigterm, .sigint],
63+
logger: config.logger
64+
)
5665
do {
57-
let lambdaService = BreezeLambdaWebHookService<LambdaHandler>(
58-
config: config
59-
)
60-
let serviceGroup = ServiceGroup(
61-
services: [lambdaService],
62-
gracefulShutdownSignals: [.sigterm, .sigint],
63-
logger: config.logger
64-
)
6566
config.logger.error("Starting \(name) ...")
6667
try await serviceGroup.run()
6768
} catch {
69+
try? handlerContext.syncShutdown()
6870
config.logger.error("Error running \(name): \(error.localizedDescription)")
6971
}
7072
}

Sources/BreezeLambdaWebHook/BreezeLambdaWebHookHandler.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,4 @@ public extension BreezeLambdaWebHookHandler {
3232
var handler: String? {
3333
Lambda.env("_HANDLER")
3434
}
35-
36-
var httpClient: AsyncHTTPClient.HTTPClient {
37-
handlerContext.httpClient
38-
}
3935
}

Sources/BreezeLambdaWebHook/BreezeLambdaWebHookService.swift

Lines changed: 0 additions & 108 deletions
This file was deleted.
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright 2023 (c) Andrea Scuderi - https://github.com/swift-serverless
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
import AsyncHTTPClient
16+
import AWSLambdaEvents
17+
import AWSLambdaRuntime
18+
#if canImport(FoundationEssentials)
19+
import FoundationEssentials
20+
#else
21+
import Foundation
22+
#endif
23+
import ServiceLifecycle
24+
import Logging
25+
26+
public struct HandlerContext: Service {
27+
public let httpClient: HTTPClient
28+
private let config: BreezeHTTPClientConfig
29+
30+
public init(config: BreezeHTTPClientConfig) {
31+
let timeout = HTTPClient.Configuration.Timeout(
32+
connect: config.timeout,
33+
read: config.timeout
34+
)
35+
let configuration = HTTPClient.Configuration(timeout: timeout)
36+
self.httpClient = HTTPClient(
37+
eventLoopGroupProvider: .singleton,
38+
configuration: configuration
39+
)
40+
self.config = config
41+
}
42+
43+
public func run() async throws {
44+
config.logger.info("BreezeHTTPClientProvider started")
45+
try await gracefulShutdown()
46+
config.logger.info("BreezeHTTPClientProvider is gracefully shutting down ...")
47+
try await onGracefulShutdown()
48+
}
49+
50+
public func onGracefulShutdown() async throws {
51+
try await httpClient.shutdown()
52+
config.logger.info("BreezeHTTPClientProvider: HTTPClient shutdown is completed.")
53+
}
54+
55+
public func syncShutdown() throws {
56+
try httpClient.syncShutdown()
57+
config.logger.info("BreezeHTTPClientProvider: HTTPClient syncShutdown is completed.")
58+
}
59+
}

Tests/BreezeLambdaWebHookTests/BreezeLambdaWebHookService.swift

Lines changed: 10 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -33,22 +33,16 @@ struct BreezeLambdaWebHookServiceTests {
3333

3434
let decoder = JSONDecoder()
3535

36-
@Test("HandlerContext initializes with provided HTTP client")
37-
func handlerContextInitializesWithClient() throws {
38-
let httpClient = HTTPClient(eventLoopGroupProvider: .singleton)
39-
defer { try? httpClient.syncShutdown() }
40-
let context = HandlerContext(httpClient: httpClient)
41-
#expect(context.httpClient === httpClient)
42-
}
43-
4436
@Test("Service creates HTTP client with correct timeout configuration")
4537
func serviceCreatesHTTPClientWithCorrectConfig() async throws {
4638
try await testGracefulShutdown { gracefulShutdownTestTrigger in
4739
let (gracefulStream, continuation) = AsyncStream<Void>.makeStream()
4840
try await withThrowingTaskGroup(of: Void.self) { group in
4941
let logger = Logger(label: "test")
5042
let config = BreezeHTTPClientConfig(timeout: .seconds(30), logger: logger)
51-
let sut = BreezeLambdaWebHookService<MockHandler>(config: config)
43+
let handlerContext = HandlerContext(config: config)
44+
let lambdaHandler = MockHandler(handlerContext: handlerContext)
45+
let sut = LambdaRuntime(body: lambdaHandler.handle)
5246
group.addTask {
5347
try await Task.sleep(nanoseconds: 1_000_000_000)
5448
gracefulShutdownTestTrigger.triggerGracefulShutdown()
@@ -60,12 +54,12 @@ struct BreezeLambdaWebHookServiceTests {
6054
} onGracefulShutdown: {
6155
logger.info("On Graceful Shutdown")
6256
continuation.yield()
63-
continuation.finish()
6457
}
6558
}
6659
for await _ in gracefulStream {
60+
continuation.finish()
61+
try handlerContext.syncShutdown()
6762
logger.info("Graceful shutdown stream received")
68-
let handlerContext = try #require(await sut.handlerContext)
6963
#expect(handlerContext.httpClient.configuration.timeout.read == .seconds(30))
7064
#expect(handlerContext.httpClient.configuration.timeout.connect == .seconds(30))
7165
group.cancelAll()
@@ -74,29 +68,16 @@ struct BreezeLambdaWebHookServiceTests {
7468
}
7569
}
7670

77-
@Test("Handler throws when handlerContext is nil")
78-
func handlerThrowsWhenContextIsNil() async throws {
79-
let logger = Logger(label: "test")
80-
let config = BreezeHTTPClientConfig(timeout: .seconds(30), logger: logger)
81-
let service = BreezeLambdaWebHookService<MockHandler>(config: config)
82-
83-
let createRequest = try Fixtures.fixture(name: Fixtures.getWebHook, type: "json")
84-
let event = try decoder.decode(APIGatewayV2Request.self, from: createRequest)
85-
let context = LambdaContext(requestID: "req1", traceID: "trace1", invokedFunctionARN: "", deadline: LambdaClock().now, logger: logger)
86-
87-
await #expect(throws: BreezeClientServiceError.invalidHandler) {
88-
try await service.handler(event: event, context: context)
89-
}
90-
}
91-
9271
@Test("Handler delegates to specific handler implementation")
9372
func handlerDelegatesToImplementation() async throws {
9473
try await testGracefulShutdown { gracefulShutdownTestTrigger in
9574
let (gracefulStream, continuation) = AsyncStream<Void>.makeStream()
9675
try await withThrowingTaskGroup(of: Void.self) { group in
9776
let logger = Logger(label: "test")
9877
let config = BreezeHTTPClientConfig(timeout: .seconds(30), logger: logger)
99-
let sut = BreezeLambdaWebHookService<MockHandler>(config: config)
78+
let handlerContext = HandlerContext(config: config)
79+
let lambdaHandler = MockHandler(handlerContext: handlerContext)
80+
let sut = LambdaRuntime(body: lambdaHandler.handle)
10081
group.addTask {
10182
try await Task.sleep(nanoseconds: 1_000_000_000)
10283
gracefulShutdownTestTrigger.triggerGracefulShutdown()
@@ -116,14 +97,13 @@ struct BreezeLambdaWebHookServiceTests {
11697
let createRequest = try Fixtures.fixture(name: Fixtures.getWebHook, type: "json")
11798
let event = try decoder.decode(APIGatewayV2Request.self, from: createRequest)
11899
let context = LambdaContext(requestID: "req1", traceID: "trace1", invokedFunctionARN: "", deadline: LambdaClock().now, logger: logger)
119-
120-
let response = try await sut.handler(event: event, context: context)
121-
let handlerContext = try #require(await sut.handlerContext)
100+
let response = try await lambdaHandler.handle(event, context: context)
122101
#expect(response.statusCode == 200)
123102
#expect(response.body == "Mock response")
124103
#expect(handlerContext.httpClient.configuration.timeout.read == .seconds(30))
125104
#expect(handlerContext.httpClient.configuration.timeout.connect == .seconds(30))
126105
group.cancelAll()
106+
try handlerContext.syncShutdown()
127107
}
128108
}
129109
}

Tests/BreezeLambdaWebHookTests/Lambda.swift

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,12 @@ extension Lambda {
3434
let logger = Logger(label: "evaluateHandler")
3535
let decoder = JSONDecoder()
3636
let encoder = JSONEncoder()
37-
let timeout = HTTPClient.Configuration.Timeout(
38-
connect: config.timeout,
39-
read: config.timeout
40-
)
41-
let configuration = HTTPClient.Configuration(timeout: timeout)
42-
let httpClient = HTTPClient(
43-
eventLoopGroupProvider: .singleton,
44-
configuration: configuration
45-
)
37+
let handlerContext = HandlerContext(config: config)
38+
defer {
39+
try? handlerContext.syncShutdown()
40+
}
4641
let sut = handlerType.init(
47-
handlerContext: HandlerContext(httpClient: httpClient)
42+
handlerContext: handlerContext
4843
)
4944
let closureHandler = ClosureHandler { event, context in
5045
//Inject Mock Response
@@ -69,7 +64,6 @@ extension Lambda {
6964
try await handler.handle(event, responseWriter: writer, context: context)
7065
let result = await writer.output ?? ByteBuffer()
7166
let value = Data(result.readableBytesView)
72-
try await httpClient.shutdown()
7367
return try decoder.decode(APIGatewayV2Response.self, from: value)
7468
}
7569
}

0 commit comments

Comments
 (0)