Skip to content

Commit 3fc2286

Browse files
committed
add prelude service to run PG initialization code
1 parent a31814f commit 3fc2286

File tree

2 files changed

+68
-8
lines changed

2 files changed

+68
-8
lines changed

Examples/ServiceLifecycle+Postgres/Sources/Lambda.swift

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,21 @@ struct LambdaFunction {
4747
private func main() async throws {
4848

4949
// Instantiate LambdaRuntime with a handler implementing the business logic of the Lambda function
50-
let runtime = LambdaRuntime(logger: self.logger, body: self.handler)
50+
let lambdaRuntime = LambdaRuntime(logger: self.logger, body: self.handler)
51+
52+
// Use a prelude service to execute PG code before setting up the Lambda service
53+
// the PG code will run only once and will create the database schema and populate it with initial data
54+
let preludeService = PreludeService(
55+
service: lambdaRuntime,
56+
prelude: {
57+
try await prepareDatabase()
58+
}
59+
)
5160

5261
/// Use ServiceLifecycle to manage the initialization and termination
5362
/// of the PGClient together with the LambdaRuntime
5463
let serviceGroup = ServiceGroup(
55-
services: [self.pgClient, runtime],
64+
services: [self.pgClient, preludeService],
5665
gracefulShutdownSignals: [.sigterm],
5766
cancellationSignals: [.sigint],
5867
logger: self.logger
@@ -76,12 +85,6 @@ struct LambdaFunction {
7685
// This is why there is a timeout, as suggested Fabian
7786
// See: https://github.com/vapor/postgres-nio/issues/489#issuecomment-2186509773
7887
result = try await timeout(deadline: .seconds(3)) {
79-
// check if table exists
80-
// TODO: ideally, I want to do this once, after serviceGroup.run() is done
81-
// but before the handler is called
82-
logger.trace("Checking database")
83-
try await prepareDatabase()
84-
8588
// query users
8689
logger.trace("Querying database")
8790
return try await self.queryUsers()
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the SwiftAWSLambdaRuntime open source project
4+
//
5+
// Copyright (c) 2025 Apple Inc. and the SwiftAWSLambdaRuntime project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
//===----------------------------------------------------------------------===//
15+
//
16+
// This source file is part of the Hummingbird server framework project
17+
//
18+
// Copyright (c) 2024 the Hummingbird authors
19+
// Licensed under Apache License v2.0
20+
//
21+
// See LICENSE.txt for license information
22+
// See hummingbird/CONTRIBUTORS.txt for the list of Hummingbird authors
23+
//
24+
// SPDX-License-Identifier: Apache-2.0
25+
//
26+
//===----------------------------------------------------------------------===//
27+
28+
// Copied from https://github.com/hummingbird-project/hummingbird/blob/main/Sources/Hummingbird/Utils/PreludeService.swift
29+
30+
import ServiceLifecycle
31+
32+
/// Wrap another service to run after a prelude closure has completed
33+
struct PreludeService<S: Service>: Service, CustomStringConvertible {
34+
let prelude: @Sendable () async throws -> Void
35+
let service: S
36+
37+
var description: String {
38+
"PreludeService<\(S.self)>"
39+
}
40+
41+
init(service: S, prelude: @escaping @Sendable () async throws -> Void) {
42+
self.service = service
43+
self.prelude = prelude
44+
}
45+
46+
func run() async throws {
47+
try await self.prelude()
48+
try await self.service.run()
49+
}
50+
}
51+
52+
extension Service {
53+
/// Build existential ``PreludeService`` from an existential `Service`
54+
func withPrelude(_ prelude: @escaping @Sendable () async throws -> Void) -> Service {
55+
PreludeService(service: self, prelude: prelude)
56+
}
57+
}

0 commit comments

Comments
 (0)