@@ -32,57 +32,62 @@ private actor LiveSessionManager {
3232 private var scheduledNextRefreshTask : Task < Void , Never > ?
3333
3434 func session( ) async throws -> Session {
35- guard let currentSession = try storage. getSession ( ) else {
36- throw AuthError . sessionNotFound
37- }
35+ try await trace ( using: logger) {
36+ guard let currentSession = try storage. getSession ( ) else {
37+ throw AuthError . sessionNotFound
38+ }
3839
39- if !currentSession. isExpired {
40- scheduleNextTokenRefresh ( currentSession)
40+ if !currentSession. isExpired {
41+ await scheduleNextTokenRefresh ( currentSession)
4142
42- return currentSession
43- }
43+ return currentSession
44+ }
4445
45- return try await refreshSession ( currentSession. refreshToken)
46+ return try await refreshSession ( currentSession. refreshToken)
47+ }
4648 }
4749
4850 func refreshSession( _ refreshToken: String ) async throws -> Session {
49- logger? . debug ( " begin " )
50- defer { logger? . debug ( " end " ) }
51-
52- if let inFlightRefreshTask {
53- logger? . debug ( " refresh already in flight " )
54- return try await inFlightRefreshTask. value
55- }
56-
57- inFlightRefreshTask = Task {
58- logger? . debug ( " refresh task started " )
59-
60- defer {
61- inFlightRefreshTask = nil
62- logger? . debug ( " refresh task ended " )
51+ try await SupabaseLoggerTaskLocal . $additionalContext. withValue (
52+ merging: [ " refreshID " : . string( UUID ( ) . uuidString) ]
53+ ) {
54+ try await trace ( using: logger) {
55+ if let inFlightRefreshTask {
56+ logger? . debug ( " refresh already in flight " )
57+ return try await inFlightRefreshTask. value
58+ }
59+
60+ inFlightRefreshTask = Task {
61+ logger? . debug ( " refresh task started " )
62+
63+ defer {
64+ inFlightRefreshTask = nil
65+ logger? . debug ( " refresh task ended " )
66+ }
67+
68+ let session = try await api. execute (
69+ HTTPRequest (
70+ url: configuration. url. appendingPathComponent ( " token " ) ,
71+ method: . post,
72+ query: [
73+ URLQueryItem ( name: " grant_type " , value: " refresh_token " ) ,
74+ ] ,
75+ body: configuration. encoder. encode ( UserCredentials ( refreshToken: refreshToken) )
76+ )
77+ )
78+ . decoded ( as: Session . self, decoder: configuration. decoder)
79+
80+ update ( session)
81+ eventEmitter. emit ( . tokenRefreshed, session: session)
82+
83+ await scheduleNextTokenRefresh ( session)
84+
85+ return session
86+ }
87+
88+ return try await inFlightRefreshTask!. value
6389 }
64-
65- let session = try await api. execute (
66- HTTPRequest (
67- url: configuration. url. appendingPathComponent ( " token " ) ,
68- method: . post,
69- query: [
70- URLQueryItem ( name: " grant_type " , value: " refresh_token " ) ,
71- ] ,
72- body: configuration. encoder. encode ( UserCredentials ( refreshToken: refreshToken) )
73- )
74- )
75- . decoded ( as: Session . self, decoder: configuration. decoder)
76-
77- update ( session)
78- eventEmitter. emit ( . tokenRefreshed, session: session)
79-
80- scheduleNextTokenRefresh ( session)
81-
82- return session
8390 }
84-
85- return try await inFlightRefreshTask!. value
8691 }
8792
8893 func update( _ session: Session ) {
@@ -101,32 +106,36 @@ private actor LiveSessionManager {
101106 }
102107 }
103108
104- private func scheduleNextTokenRefresh( _ refreshedSession: Session , source: StaticString = #function) {
105- logger? . debug ( " source: \( source) " )
109+ private func scheduleNextTokenRefresh( _ refreshedSession: Session , caller: StaticString = #function) async {
110+ await SupabaseLoggerTaskLocal . $additionalContext. withValue (
111+ merging: [ " caller " : . string( " \( caller) " ) ]
112+ ) {
113+ guard scheduledNextRefreshTask == nil else {
114+ logger? . debug ( " refresh task already scheduled " )
115+ return
116+ }
106117
107- guard scheduledNextRefreshTask == nil else {
108- logger? . debug ( " source: \( source) refresh task already scheduled " )
109- return
110- }
118+ scheduledNextRefreshTask = Task {
119+ await trace ( using: logger) {
120+ defer { scheduledNextRefreshTask = nil }
111121
112- scheduledNextRefreshTask = Task {
113- defer { scheduledNextRefreshTask = nil }
122+ let expiresAt = Date ( timeIntervalSince1970 : refreshedSession . expiresAt )
123+ let expiresIn = expiresAt . timeIntervalSinceNow
114124
115- let expiresAt = Date ( timeIntervalSince1970 : refreshedSession . expiresAt )
116- let expiresIn = expiresAt . timeIntervalSinceNow
125+ // if expiresIn < 0, it will refresh right away.
126+ let timeToRefresh = max ( expiresIn * 0.9 , 0 )
117127
118- // if expiresIn < 0, it will refresh right away.
119- let timeToRefresh = max ( expiresIn * 0.9 , 0 )
128+ logger? . debug ( " scheduled next token refresh in: \( timeToRefresh) s " )
120129
121- logger ? . debug ( " source: \( source ) scheduled next token refresh in: \ ( timeToRefresh) s " )
130+ try ? await Task . sleep ( nanoseconds : NSEC_PER_SEC * UInt64 ( timeToRefresh) )
122131
123- try ? await Task . sleep ( nanoseconds: NSEC_PER_SEC * UInt64( timeToRefresh) )
132+ if Task . isCancelled {
133+ return
134+ }
124135
125- if Task . isCancelled {
126- return
136+ _ = try ? await refreshSession ( refreshedSession . refreshToken )
137+ }
127138 }
128-
129- _ = try ? await refreshSession ( refreshedSession. refreshToken)
130139 }
131140 }
132141}
0 commit comments