Skip to content

Commit 61effed

Browse files
author
Andrea Scuderi
committed
Simplify Implementation - Graceful Shutdown Not Working
1 parent 6b635ca commit 61effed

File tree

11 files changed

+86
-219
lines changed

11 files changed

+86
-219
lines changed

Package.swift

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@ let package = Package(
1616
name: "BreezeDynamoDBService",
1717
targets: ["BreezeDynamoDBService"]
1818
),
19-
.library(
20-
name: "BreezeHTTPClientService",
21-
targets: ["BreezeHTTPClientService"]
22-
),
2319
.library(
2420
name: "BreezeLambdaAPI",
2521
targets: ["BreezeLambdaAPI"]
@@ -35,7 +31,6 @@ let package = Package(
3531
.package(url: "https://github.com/swift-server/swift-service-lifecycle.git", from: "2.0.0"),
3632
.package(url: "https://github.com/soto-project/soto.git", from: "7.0.0"),
3733
.package(url: "https://github.com/apple/swift-log.git", from: "1.6.2"),
38-
.package(url: "https://github.com/swift-server/async-http-client.git", from: "1.24.0"),
3934
],
4035
targets: [
4136
.executableTarget(
@@ -44,20 +39,12 @@ let package = Package(
4439
"BreezeLambdaAPI"
4540
]
4641
),
47-
.target(
48-
name: "BreezeHTTPClientService",
49-
dependencies: [
50-
.product(name: "AsyncHTTPClient", package: "async-http-client"),
51-
.product(name: "Logging", package: "swift-log")
52-
]
53-
),
5442
.target(
5543
name: "BreezeDynamoDBService",
5644
dependencies: [
5745
.product(name: "SotoDynamoDB", package: "soto"),
5846
.product(name: "ServiceLifecycle", package: "swift-service-lifecycle"),
5947
.product(name: "Logging", package: "swift-log"),
60-
"BreezeHTTPClientService"
6148
]
6249
),
6350
.target(
@@ -87,14 +74,6 @@ let package = Package(
8774
.product(name: "ServiceLifecycleTestKit", package: "swift-service-lifecycle"),
8875
"BreezeDynamoDBService"
8976
]
90-
),
91-
.testTarget(
92-
name: "BreezeHTTPClientServiceTests",
93-
dependencies: [
94-
.product(name: "ServiceLifecycle", package: "swift-service-lifecycle"),
95-
.product(name: "ServiceLifecycleTestKit", package: "swift-service-lifecycle"),
96-
"BreezeHTTPClientService"
97-
]
9877
)
9978
]
10079
)

Sources/BreezeDemoApplication/BreezeDemoApplication.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ struct APIConfiguration: APIConfiguring {
4848
struct BreezeDemoApplication {
4949
static func main() async throws {
5050
do {
51-
let lambdaAPIService = try BreezeLambdaAPI<Item>(apiConfig: APIConfiguration())
51+
let lambdaAPIService = try await BreezeLambdaAPI<Item>(apiConfig: APIConfiguration())
5252
try await lambdaAPIService.run()
5353
} catch {
5454
print(error.localizedDescription)

Sources/BreezeDynamoDBService/BreezeDynamoDBService.swift

Lines changed: 42 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -13,75 +13,74 @@
1313
// limitations under the License.
1414

1515
import SotoDynamoDB
16+
import AsyncHTTPClient
1617
import ServiceLifecycle
17-
import BreezeHTTPClientService
1818
import Logging
1919

20-
public protocol BreezeDynamoDBServing: Actor, Service {
20+
public protocol BreezeDynamoDBServing: Actor {
2121
func dbManager() async -> BreezeDynamoDBManaging
22+
func gracefulShutdown() throws
2223
}
2324

2425
public actor BreezeDynamoDBService: BreezeDynamoDBServing {
2526

26-
private var _dbManager: BreezeDynamoDBManaging?
27+
private let dbManager: BreezeDynamoDBManaging
2728
private let config: BreezeDynamoDBConfig
28-
private let serviceConfig: BreezeClientServiceConfig
29+
private let httpConfig: BreezeHTTPClientConfig
30+
private let logger: Logger
2931
private let DBManagingType: BreezeDynamoDBManaging.Type
32+
private var awsClient: AWSClient
33+
private let httpClient: HTTPClient
3034

31-
public func dbManager() async -> BreezeDynamoDBManaging {
32-
if let _dbManager {
33-
return _dbManager
34-
}
35-
let httpClient = await serviceConfig.httpClientService.httpClient
36-
let awsClient = AWSClient(httpClient: httpClient)
37-
self.awsClient = awsClient
35+
public init(
36+
config: BreezeDynamoDBConfig,
37+
httpConfig: BreezeHTTPClientConfig,
38+
logger: Logger,
39+
DBManagingType: BreezeDynamoDBManaging.Type = BreezeDynamoDBManager.self
40+
) async {
41+
logger.info("Init DynamoDBService with config...")
42+
logger.info("region: \(config.region)")
43+
logger.info("tableName: \(config.tableName)")
44+
logger.info("keyName: \(config.keyName)")
45+
46+
self.config = config
47+
self.httpConfig = httpConfig
48+
self.logger = logger
49+
self.DBManagingType = DBManagingType
50+
let timeout = HTTPClient.Configuration.Timeout(
51+
connect: httpConfig.timeout,
52+
read: httpConfig.timeout
53+
)
54+
let configuration = HTTPClient.Configuration(timeout: timeout)
55+
self.httpClient = HTTPClient(
56+
eventLoopGroupProvider: .singleton,
57+
configuration: configuration
58+
)
59+
self.awsClient = AWSClient(httpClient: httpClient)
3860
let db = SotoDynamoDB.DynamoDB(
3961
client: awsClient,
4062
region: config.region,
4163
endpoint: config.endpoint
4264
)
43-
let dbManager = DBManagingType.init(
65+
self.dbManager = DBManagingType.init(
4466
db: db,
4567
tableName: config.tableName,
4668
keyName: config.keyName
4769
)
48-
_dbManager = dbManager
49-
return dbManager
50-
}
51-
52-
public init(
53-
config: BreezeDynamoDBConfig,
54-
serviceConfig: BreezeClientServiceConfig,
55-
DBManagingType: BreezeDynamoDBManaging.Type = BreezeDynamoDBManager.self
56-
) {
57-
self.config = config
58-
self.serviceConfig = serviceConfig
59-
self.DBManagingType = DBManagingType
70+
logger.info("DBManager is ready.")
6071
}
6172

62-
private var awsClient: AWSClient?
63-
64-
private var logger: Logger {
65-
serviceConfig.logger
73+
public func dbManager() async -> BreezeDynamoDBManaging {
74+
self.dbManager
6675
}
6776

68-
public func run() async throws {
69-
logger.info("Starting DynamoDBService...")
70-
logger.info("DynamoDBService is running with config...")
71-
logger.info("region: \(config.region)")
72-
logger.info("tableName: \(config.tableName)")
73-
logger.info("keyName: \(config.keyName)")
74-
75-
try await gracefulShutdown()
76-
77+
public func gracefulShutdown() throws {
7778
logger.info("Stopping DynamoDBService...")
78-
try await awsClient?.shutdown()
79-
self.awsClient = nil
79+
try awsClient.syncShutdown()
8080
logger.info("DynamoDBService is stopped.")
81-
}
82-
83-
deinit {
84-
try? awsClient?.syncShutdown()
81+
logger.info("Stopping HTTPClient...")
82+
try httpClient.syncShutdown()
83+
logger.info("HTTPClient is stopped.")
8584
}
8685
}
8786

Sources/BreezeHTTPClientService/BreezeClientServiceConfig.swift renamed to Sources/BreezeDynamoDBService/BreezeHTTPClientConfig.swift

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,18 @@
1313
// limitations under the License.
1414

1515
import Logging
16+
import NIOCore
1617

17-
public struct BreezeClientServiceConfig: Sendable {
18-
19-
public let httpClientService: BreezeHTTPClientServing
20-
public let logger: Logger
21-
22-
public init(
23-
httpClientService: BreezeHTTPClientServing,
24-
logger: Logger
25-
) {
26-
self.httpClientService = httpClientService
18+
public enum BreezeClientServiceError: Error {
19+
case invalidHttpClient
20+
}
21+
22+
public struct BreezeHTTPClientConfig: Sendable {
23+
public init(timeout: TimeAmount, logger: Logger) {
24+
self.timeout = timeout
2725
self.logger = logger
2826
}
27+
28+
public let timeout: TimeAmount
29+
public let logger: Logger
2930
}

Sources/BreezeHTTPClientService/BreezeHTTPClientService.swift

Lines changed: 0 additions & 57 deletions
This file was deleted.

Sources/BreezeLambdaAPI/BreezeLambdaAPI.swift

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,33 +15,31 @@
1515
import SotoDynamoDB
1616
import ServiceLifecycle
1717
import BreezeDynamoDBService
18-
import BreezeHTTPClientService
1918
import AWSLambdaRuntime
2019

2120
public actor BreezeLambdaAPI<T: BreezeCodable>: Service {
2221

2322
let logger = Logger(label: "service-group-breeze-lambda-api")
2423
let timeout: TimeAmount
25-
let httpClientService: BreezeHTTPClientServing
2624
let dynamoDBService: BreezeDynamoDBServing
2725
let breezeLambdaService: BreezeLambdaService<T>
2826
private let serviceGroup: ServiceGroup
2927
private let apiConfig: any APIConfiguring
3028

31-
public init(apiConfig: APIConfiguring = BreezeAPIConfiguration()) throws {
29+
public init(apiConfig: APIConfiguring = BreezeAPIConfiguration()) async throws {
3230
do {
3331
self.apiConfig = apiConfig
3432
self.timeout = .seconds(apiConfig.dbTimeout)
35-
self.httpClientService = BreezeHTTPClientService(
36-
timeout: timeout,
33+
let config = try apiConfig.getConfig()
34+
let httpConfig = BreezeHTTPClientConfig(
35+
timeout: .seconds(60),
3736
logger: logger
3837
)
39-
let config = try apiConfig.getConfig()
40-
let serviceConfig = BreezeClientServiceConfig(
41-
httpClientService: httpClientService,
38+
self.dynamoDBService = await BreezeDynamoDBService(
39+
config: config,
40+
httpConfig: httpConfig,
4241
logger: logger
4342
)
44-
self.dynamoDBService = BreezeDynamoDBService(config: config, serviceConfig: serviceConfig)
4543
self.breezeLambdaService = BreezeLambdaService<T>(
4644
dynamoDBService: dynamoDBService,
4745
operation: try apiConfig.operation(),
@@ -50,22 +48,13 @@ public actor BreezeLambdaAPI<T: BreezeCodable>: Service {
5048
self.serviceGroup = ServiceGroup(
5149
configuration: .init(
5250
services: [
53-
.init(
54-
service: httpClientService,
55-
successTerminationBehavior: .ignore,
56-
failureTerminationBehavior: .gracefullyShutdownGroup
57-
),
58-
.init(
59-
service: dynamoDBService,
60-
successTerminationBehavior: .gracefullyShutdownGroup,
61-
failureTerminationBehavior: .gracefullyShutdownGroup
62-
),
6351
.init(
6452
service: breezeLambdaService,
6553
successTerminationBehavior: .gracefullyShutdownGroup,
6654
failureTerminationBehavior: .gracefullyShutdownGroup
6755
)
6856
],
57+
gracefulShutdownSignals: [.sigterm],
6958
logger: logger
7059
)
7160
)

Sources/BreezeLambdaAPI/BreezeLambdaService.swift

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,24 @@ actor BreezeLambdaService<T: BreezeCodable>: Service {
4040
}
4141

4242
func run() async throws {
43-
do {
44-
logger.info("Starting BreezeLambdaService...")
45-
let dbManager = await dynamoDBService.dbManager()
46-
let breezeApi = BreezeLambdaHandler<T>(dbManager: dbManager, operation: operation)
47-
self.breezeApi = breezeApi
48-
logger.info("Starting BreezeLambdaService...")
49-
let runtime = LambdaRuntime(body: handler)
50-
try await runtime.run()
51-
logger.info("BreezeLambdaService stopped.")
52-
} catch {
53-
logger.error("\(error.localizedDescription)")
54-
throw error
43+
let dbManager = await dynamoDBService.dbManager()
44+
try await withGracefulShutdownHandler {
45+
do {
46+
let breezeApi = BreezeLambdaHandler<T>(dbManager: dbManager, operation: operation)
47+
self.breezeApi = breezeApi
48+
logger.info("Starting BreezeLambdaService...")
49+
logger.info("Starting BreezeLambdaService...")
50+
let runtime = LambdaRuntime(body: handler)
51+
try await runtime.run()
52+
logger.info("BreezeLambdaService stopped.")
53+
} catch {
54+
logger.error("\(error.localizedDescription)")
55+
throw error
56+
}
57+
} onGracefulShutdown: {
58+
Task {
59+
try await self.dynamoDBService.gracefulShutdown()
60+
}
5561
}
5662
}
5763
}

0 commit comments

Comments
 (0)