forked from vapor/postgres-nio
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathConnectionRequest.swift
75 lines (62 loc) · 2.45 KB
/
ConnectionRequest.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
public struct ConnectionRequest<Connection: PooledConnection>: ConnectionRequestProtocol {
public typealias ID = Int
public var id: ID
@usableFromInline
private(set) var continuation: CheckedContinuation<Connection, any Error>
@inlinable
init(
id: Int,
continuation: CheckedContinuation<Connection, any Error>
) {
self.id = id
self.continuation = continuation
}
public func complete(with result: Result<Connection, ConnectionPoolError>) {
self.continuation.resume(with: result)
}
}
fileprivate let requestIDGenerator = _ConnectionPoolModule.ConnectionIDGenerator()
@available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *)
extension ConnectionPool where Request == ConnectionRequest<Connection> {
public convenience init(
configuration: ConnectionPoolConfiguration,
idGenerator: ConnectionIDGenerator = _ConnectionPoolModule.ConnectionIDGenerator(),
keepAliveBehavior: KeepAliveBehavior,
observabilityDelegate: ObservabilityDelegate,
clock: Clock = ContinuousClock(),
connectionFactory: @escaping ConnectionFactory
) {
self.init(
configuration: configuration,
idGenerator: idGenerator,
requestType: ConnectionRequest<Connection>.self,
keepAliveBehavior: keepAliveBehavior,
observabilityDelegate: observabilityDelegate,
clock: clock,
connectionFactory: connectionFactory
)
}
public func leaseConnection() async throws -> Connection {
let requestID = requestIDGenerator.next()
let connection = try await withTaskCancellationHandler {
if Task.isCancelled {
throw CancellationError()
}
return try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Connection, Error>) in
let request = Request(
id: requestID,
continuation: continuation
)
self.leaseConnection(request)
}
} onCancel: {
self.cancelLeaseConnection(requestID)
}
return connection
}
public func withConnection<Result>(_ closure: (Connection) async throws -> Result) async throws -> Result {
let connection = try await self.leaseConnection()
defer { self.releaseConnection(connection) }
return try await closure(connection)
}
}