Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d889fe8

Browse files
committed
Add passthrough configuration parameters for the new idle connection pruning support in AsyncKit 1.21.0, enabling direct use by Fluent users.
1 parent 095bc5a commit d889fe8

File tree

7 files changed

+77
-25
lines changed

7 files changed

+77
-25
lines changed

‎.github/workflows/test.yml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929
container: swift:noble
3030
steps:
3131
- name: Checkout
32-
uses: actions/checkout@v4
32+
uses: actions/checkout@v5
3333
with: { 'fetch-depth': 0 }
3434
- name: API breaking changes
3535
run: |
@@ -74,10 +74,12 @@ jobs:
7474
POSTGRES_HOST_AUTH_METHOD: ${{ matrix.postgres-auth }}
7575
POSTGRES_INITDB_ARGS: --auth-host=${{ matrix.postgres-auth }}
7676
steps:
77+
- name: Ensure curl is available
78+
run: apt-get update -y && apt-get install -y curl
7779
- name: Check out package
78-
uses: actions/checkout@v4
80+
uses: actions/checkout@v5
7981
- name: Run all tests
80-
run: swift test --sanitize=thread --enable-code-coverage
82+
run: swift test --enable-code-coverage
8183
- name: Submit coverage report to Codecov.io
8284
uses: vapor/swift-codecov-action@v0.3
8385
with:
@@ -115,6 +117,6 @@ jobs:
115117
PGPASSWORD="${POSTGRES_PASSWORD_A}" psql -w "${POSTGRES_DB_B}" <<<"ALTER SCHEMA public OWNER TO ${POSTGRES_USER_B};"
116118
timeout-minutes: 15
117119
- name: Checkout code
118-
uses: actions/checkout@v4
120+
uses: actions/checkout@v5
119121
- name: Run all tests
120-
run: swift test --sanitize=thread
122+
run: swift test

‎Package.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ let package = Package(
1313
.library(name: "FluentPostgresDriver", targets: ["FluentPostgresDriver"]),
1414
],
1515
dependencies: [
16-
.package(url: "https://github.com/vapor/fluent-kit.git", from: "1.49.0"),
17-
.package(url: "https://github.com/vapor/postgres-kit.git", from: "2.13.4"),
16+
.package(url: "https://github.com/vapor/fluent-kit.git", from: "1.52.2"),
17+
.package(url: "https://github.com/vapor/postgres-kit.git", from: "2.14.0"),
18+
.package(url: "https://github.com/vapor/async-kit.git", from: "1.21.0"),
1819
],
1920
targets: [
2021
.target(
@@ -23,6 +24,7 @@ let package = Package(
2324
.product(name: "FluentKit", package: "fluent-kit"),
2425
.product(name: "FluentSQL", package: "fluent-kit"),
2526
.product(name: "PostgresKit", package: "postgres-kit"),
27+
.product(name: "AsyncKit", package: "async-kit"),
2628
],
2729
swiftSettings: swiftSettings
2830
),
@@ -39,6 +41,7 @@ let package = Package(
3941

4042
var swiftSettings: [SwiftSetting] { [
4143
.enableUpcomingFeature("ExistentialAny"),
44+
.enableUpcomingFeature("MemberImportVisibility"),
4245
.enableUpcomingFeature("ConciseMagicFile"),
4346
.enableUpcomingFeature("ForwardTrailingClosures"),
4447
.enableUpcomingFeature("DisableOutwardActorInference"),
Lines changed: 17 additions & 13 deletions
Loading[フレーム]

‎Sources/FluentPostgresDriver/FluentPostgresConfiguration.swift

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,19 @@ extension DatabaseConfigurationFactory {
1515
/// - urlString: The URL describing the connection, as a string.
1616
/// - maxConnectionsPerEventLoop: Maximum number of connections to open per event loop.
1717
/// - connectionPoolTimeout: Maximum time to wait for a connection to become available per request.
18+
/// - pruneInterval: How often to check for and prune idle database connections. If `nil` (the default),
19+
/// no pruning is performed.
20+
/// - maxIdleTimeBeforePruning: How long a connection may remain idle before being pruned, if pruning is enabled.
21+
/// Defaults to 2 minutes. Ignored if `pruneInterval` is `nil`.
1822
/// - encodingContext: Encoding context to use for serializing data.
1923
/// - decodingContext: Decoding context to use for deserializing data.
2024
/// - sqlLogLevel: Level at which to log SQL queries.
2125
public static func postgres(
2226
url urlString: String,
2327
maxConnectionsPerEventLoop: Int = 1,
2428
connectionPoolTimeout: TimeAmount = .seconds(10),
29+
pruneInterval: TimeAmount? = nil,
30+
maxIdleTimeBeforePruning: TimeAmount = .seconds(120),
2531
encodingContext: PostgresEncodingContext<some PostgresJSONEncoder> = .default,
2632
decodingContext: PostgresDecodingContext<some PostgresJSONDecoder> = .default,
2733
sqlLogLevel: Logger.Level = .debug
@@ -30,6 +36,8 @@ extension DatabaseConfigurationFactory {
3036
configuration: try .init(url: urlString),
3137
maxConnectionsPerEventLoop: maxConnectionsPerEventLoop,
3238
connectionPoolTimeout: connectionPoolTimeout,
39+
pruneInterval: pruneInterval,
40+
maxIdleTimeBeforePruning: maxIdleTimeBeforePruning,
3341
encodingContext: encodingContext,
3442
decodingContext: decodingContext,
3543
sqlLogLevel: sqlLogLevel
@@ -44,13 +52,19 @@ extension DatabaseConfigurationFactory {
4452
/// - url: The URL describing the connection.
4553
/// - maxConnectionsPerEventLoop: Maximum number of connections to open per event loop.
4654
/// - connectionPoolTimeout: Maximum time to wait for a connection to become available per request.
55+
/// - pruneInterval: How often to check for and prune idle database connections. If `nil` (the default),
56+
/// no pruning is performed.
57+
/// - maxIdleTimeBeforePruning: How long a connection may remain idle before being pruned, if pruning is enabled.
58+
/// Defaults to 2 minutes. Ignored if `pruneInterval` is `nil`.
4759
/// - encodingContext: Encoding context to use for serializing data.
4860
/// - decodingContext: Decoding context to use for deserializing data.
4961
/// - sqlLogLevel: Level at which to log SQL queries.
5062
public static func postgres(
5163
url: URL,
5264
maxConnectionsPerEventLoop: Int = 1,
5365
connectionPoolTimeout: TimeAmount = .seconds(10),
66+
pruneInterval: TimeAmount? = nil,
67+
maxIdleTimeBeforePruning: TimeAmount = .seconds(120),
5468
encodingContext: PostgresEncodingContext<some PostgresJSONEncoder> = .default,
5569
decodingContext: PostgresDecodingContext<some PostgresJSONDecoder> = .default,
5670
sqlLogLevel: Logger.Level = .debug
@@ -59,6 +73,8 @@ extension DatabaseConfigurationFactory {
5973
configuration: try .init(url: url),
6074
maxConnectionsPerEventLoop: maxConnectionsPerEventLoop,
6175
connectionPoolTimeout: connectionPoolTimeout,
76+
pruneInterval: pruneInterval,
77+
maxIdleTimeBeforePruning: maxIdleTimeBeforePruning,
6278
encodingContext: encodingContext,
6379
decodingContext: decodingContext,
6480
sqlLogLevel: sqlLogLevel
@@ -71,13 +87,19 @@ extension DatabaseConfigurationFactory {
7187
/// - configuration: A ``PostgresKit/SQLPostgresConfiguration`` describing the connection.
7288
/// - maxConnectionsPerEventLoop: Maximum number of connections to open per event loop.
7389
/// - connectionPoolTimeout: Maximum time to wait for a connection to become available per request.
90+
/// - pruneInterval: How often to check for and prune idle database connections. If `nil` (the default),
91+
/// no pruning is performed.
92+
/// - maxIdleTimeBeforePruning: How long a connection may remain idle before being pruned, if pruning is enabled.
93+
/// Defaults to 2 minutes. Ignored if `pruneInterval` is `nil`.
7494
/// - encodingContext: Encoding context to use for serializing data.
7595
/// - decodingContext: Decoding context to use for deserializing data.
7696
/// - sqlLogLevel: Level at which to log SQL queries.
7797
public static func postgres(
7898
configuration: SQLPostgresConfiguration,
7999
maxConnectionsPerEventLoop: Int = 1,
80100
connectionPoolTimeout: TimeAmount = .seconds(10),
101+
pruneInterval: TimeAmount? = nil,
102+
maxIdleTimeBeforePruning: TimeAmount = .seconds(120),
81103
encodingContext: PostgresEncodingContext<some PostgresJSONEncoder>,
82104
decodingContext: PostgresDecodingContext<some PostgresJSONDecoder>,
83105
sqlLogLevel: Logger.Level = .debug
@@ -87,6 +109,8 @@ extension DatabaseConfigurationFactory {
87109
configuration: configuration,
88110
maxConnectionsPerEventLoop: maxConnectionsPerEventLoop,
89111
connectionPoolTimeout: connectionPoolTimeout,
112+
pruningInterval: pruneInterval,
113+
maxIdleTimeBeforePruning: maxIdleTimeBeforePruning,
90114
encodingContext: encodingContext,
91115
decodingContext: decodingContext,
92116
sqlLogLevel: sqlLogLevel
@@ -108,56 +132,68 @@ extension DatabaseConfigurationFactory {
108132
///
109133
/// _ = DatabaseConfigurationFactory.postgres(configuration: .init(unixDomainSocketPath: "", username: ""))
110134
extension DatabaseConfigurationFactory {
111-
/// ``postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:encodingContext:decodingContext:sqlLogLevel:)``
135+
/// ``postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:pruneInterval:maxIdleTimeBeforePruning:encodingContext:decodingContext:sqlLogLevel:)``
112136
/// with the `decodingContext` defaulted.
113137
public static func postgres(
114138
configuration: SQLPostgresConfiguration,
115139
maxConnectionsPerEventLoop: Int = 1,
116140
connectionPoolTimeout: TimeAmount = .seconds(10),
141+
pruneInterval: TimeAmount? = nil,
142+
maxIdleTimeBeforePruning: TimeAmount = .seconds(120),
117143
encodingContext: PostgresEncodingContext<some PostgresJSONEncoder>,
118144
sqlLogLevel: Logger.Level = .debug
119145
) -> DatabaseConfigurationFactory {
120146
.postgres(
121147
configuration: configuration,
122148
maxConnectionsPerEventLoop: maxConnectionsPerEventLoop,
123149
connectionPoolTimeout: connectionPoolTimeout,
150+
pruneInterval: pruneInterval,
151+
maxIdleTimeBeforePruning: maxIdleTimeBeforePruning,
124152
encodingContext: encodingContext,
125153
decodingContext: .default,
126154
sqlLogLevel: sqlLogLevel
127155
)
128156
}
129157

130-
/// ``postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:encodingContext:decodingContext:sqlLogLevel:)``
158+
/// ``postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:pruneInterval:maxIdleTimeBeforePruning:encodingContext:decodingContext:sqlLogLevel:)``
131159
/// with the `encodingContext` defaulted.
132160
public static func postgres(
133161
configuration: SQLPostgresConfiguration,
134162
maxConnectionsPerEventLoop: Int = 1,
135163
connectionPoolTimeout: TimeAmount = .seconds(10),
164+
pruneInterval: TimeAmount? = nil,
165+
maxIdleTimeBeforePruning: TimeAmount = .seconds(120),
136166
decodingContext: PostgresDecodingContext<some PostgresJSONDecoder>,
137167
sqlLogLevel: Logger.Level = .debug
138168
) -> DatabaseConfigurationFactory {
139169
.postgres(
140170
configuration: configuration,
141171
maxConnectionsPerEventLoop: maxConnectionsPerEventLoop,
142172
connectionPoolTimeout: connectionPoolTimeout,
173+
pruneInterval: pruneInterval,
174+
maxIdleTimeBeforePruning: maxIdleTimeBeforePruning,
143175
encodingContext: .default,
144176
decodingContext: decodingContext,
145177
sqlLogLevel: sqlLogLevel
146178
)
147179
}
148180

149-
/// ``postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:encodingContext:decodingContext:sqlLogLevel:)``
181+
/// ``postgres(configuration:maxConnectionsPerEventLoop:connectionPoolTimeout:pruneInterval:maxIdleTimeBeforePruning:encodingContext:decodingContext:sqlLogLevel:)``
150182
/// with both `encodingContext` and `decodingContext` defaulted.
151183
public static func postgres(
152184
configuration: SQLPostgresConfiguration,
153185
maxConnectionsPerEventLoop: Int = 1,
154186
connectionPoolTimeout: TimeAmount = .seconds(10),
187+
pruneInterval: TimeAmount? = nil,
188+
maxIdleTimeBeforePruning: TimeAmount = .seconds(120),
155189
sqlLogLevel: Logger.Level = .debug
156190
) -> DatabaseConfigurationFactory {
157191
.postgres(
158192
configuration: configuration,
159193
maxConnectionsPerEventLoop: maxConnectionsPerEventLoop,
160194
connectionPoolTimeout: connectionPoolTimeout,
195+
pruneInterval: pruneInterval,
196+
maxIdleTimeBeforePruning: maxIdleTimeBeforePruning,
161197
encodingContext: .default,
162198
decodingContext: .default,
163199
sqlLogLevel: sqlLogLevel
@@ -171,6 +207,8 @@ struct FluentPostgresConfiguration<E: PostgresJSONEncoder, D: PostgresJSONDecode
171207
fileprivate let configuration: SQLPostgresConfiguration
172208
let maxConnectionsPerEventLoop: Int
173209
let connectionPoolTimeout: TimeAmount
210+
let pruningInterval: TimeAmount?
211+
let maxIdleTimeBeforePruning: TimeAmount
174212
let encodingContext: PostgresEncodingContext<E>
175213
let decodingContext: PostgresDecodingContext<D>
176214
let sqlLogLevel: Logger.Level
@@ -181,6 +219,8 @@ struct FluentPostgresConfiguration<E: PostgresJSONEncoder, D: PostgresJSONDecode
181219
source: connectionSource,
182220
maxConnectionsPerEventLoop: self.maxConnectionsPerEventLoop,
183221
requestTimeout: self.connectionPoolTimeout,
222+
pruneInterval: self.pruningInterval,
223+
maxIdleTimeBeforePruning: self.maxIdleTimeBeforePruning,
184224
on: databases.eventLoopGroup
185225
)
186226

‎Sources/FluentPostgresDriver/FluentPostgresDatabase.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ extension _FluentPostgresDatabase: Database {
6161
}
6262
}
6363

64-
func transaction<T>(_ closure: @escaping @Sendable (any Database) -> EventLoopFuture<T>) -> EventLoopFuture<T> {
64+
func transaction<T:Sendable>(_ closure: @escaping @Sendable (any Database) -> EventLoopFuture<T>) -> EventLoopFuture<T> {
6565
guard !self.inTransaction else {
6666
return closure(self)
6767
}

‎Sources/FluentPostgresDriver/PostgresConverterDelegate.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ struct PostgresConverterDelegate: SQLConverterDelegate {
2020
case .dictionary:
2121
SQLRaw("JSONB")
2222
case .array(of: let type):
23-
if let type= type, let dataType = self.customDataType(type) {
23+
if let type, let dataType = self.customDataType(type) {
2424
SQLArrayDataType(dataType: dataType)
2525
} else {
2626
SQLRaw("JSONB")

‎Tests/FluentPostgresDriverTests/FluentPostgresDriverTests.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import FluentBenchmark
22
import FluentKit
33
import FluentPostgresDriver
4+
import FluentSQL
45
import Logging
56
import PostgresKit
67
import SQLKit
@@ -310,6 +311,8 @@ extension DatabaseConfigurationFactory {
310311
return .postgres(
311312
configuration: baseSubconfig,
312313
connectionPoolTimeout: .seconds(30),
314+
pruneInterval: .seconds(30),
315+
maxIdleTimeBeforePruning: .seconds(60),
313316
encodingContext: encodingContext,
314317
decodingContext: decodingContext
315318
)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /