Skip to content

Commit 0f56fd5

Browse files
committed
Fix Swift 6.2 concurrency error
1 parent 8e8d0e3 commit 0f56fd5

File tree

1 file changed

+26
-25
lines changed

1 file changed

+26
-25
lines changed

Sources/App/Core/Dependencies/RedisClient.swift

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ import NIOCore
1717
import Dependencies
1818
import DependenciesMacros
1919

20+
@globalActor
21+
actor RedisSingletonActor {
22+
static let shared = RedisSingletonActor()
23+
}
2024

2125
@DependencyClient
2226
struct RedisClient {
@@ -42,11 +46,11 @@ extension RedisClient: DependencyKey {
4246
static var liveValue: RedisClient {
4347
.init(
4448
set: { key, value, expiresIn in
45-
try await Redis.shared.set(key: key, value: value, expiresIn: expiresIn)
49+
try await Redis.shared().set(key: key, value: value, expiresIn: expiresIn)
4650
},
47-
get: { key in try await Redis.shared.get(key: key) },
48-
expire: { key, ttl in try await Redis.shared.expire(key: key, after: ttl) },
49-
increment: { key, value in try await Redis.shared.increment(key: key, by: value) }
51+
get: { key in try await Redis.shared().get(key: key) },
52+
expire: { key, ttl in try await Redis.shared().expire(key: key, after: ttl) },
53+
increment: { key, value in try await Redis.shared().increment(key: key, by: value) }
5054
)
5155
}
5256
}
@@ -79,30 +83,27 @@ extension RedisClient {
7983

8084
private actor Redis {
8185
var client: RediStack.RedisClient
82-
static private var task: Task<Redis, Swift.Error>?
86+
@RedisSingletonActor private static var _shared: Redis?
8387

84-
static var shared: Redis {
85-
get async throws {
86-
if let task {
87-
return try await task.value
88-
}
89-
let task = Task<Redis, Swift.Error> {
90-
var attemptsLeft = maxConnectionAttempts
91-
while attemptsLeft > 0 {
92-
do {
93-
return try await Redis()
94-
} catch {
95-
attemptsLeft -= 1
96-
@Dependency(\.logger) var logger
97-
logger.warning("Redis connection failed, \(attemptsLeft) attempts left. Error: \(error)")
98-
try? await Task.sleep(for: .milliseconds(500))
99-
}
100-
}
101-
throw Error.unavailable
88+
@RedisSingletonActor
89+
static func shared() async throws -> Redis {
90+
if let existing = _shared {
91+
return existing
92+
}
93+
var attemptsLeft = maxConnectionAttempts
94+
while attemptsLeft > 0 {
95+
do {
96+
let instance = try await Redis()
97+
_shared = instance
98+
return instance
99+
} catch {
100+
attemptsLeft -= 1
101+
@Dependency(\.logger) var logger
102+
logger.warning("Redis connection failed, \(attemptsLeft) attempts left. Error: \(error)")
103+
try? await Task.sleep(for: .milliseconds(500))
102104
}
103-
self.task = task
104-
return try await task.value
105105
}
106+
throw Error.unavailable
106107
}
107108

108109
enum Error: Swift.Error {

0 commit comments

Comments
 (0)