@@ -17,6 +17,10 @@ import NIOCore
1717import Dependencies
1818import DependenciesMacros
1919
20+ @globalActor
21+ actor RedisSingletonActor {
22+ static let shared = RedisSingletonActor ( )
23+ }
2024
2125@DependencyClient
2226struct 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
8084private 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