@@ -32,57 +32,62 @@ private actor LiveSessionManager {
32
32
private var scheduledNextRefreshTask : Task < Void , Never > ?
33
33
34
34
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
+ }
38
39
39
- if !currentSession. isExpired {
40
- scheduleNextTokenRefresh ( currentSession)
40
+ if !currentSession. isExpired {
41
+ await scheduleNextTokenRefresh ( currentSession)
41
42
42
- return currentSession
43
- }
43
+ return currentSession
44
+ }
44
45
45
- return try await refreshSession ( currentSession. refreshToken)
46
+ return try await refreshSession ( currentSession. refreshToken)
47
+ }
46
48
}
47
49
48
50
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
63
89
}
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
83
90
}
84
-
85
- return try await inFlightRefreshTask!. value
86
91
}
87
92
88
93
func update( _ session: Session ) {
@@ -101,32 +106,36 @@ private actor LiveSessionManager {
101
106
}
102
107
}
103
108
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
+ }
106
117
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 }
111
121
112
- scheduledNextRefreshTask = Task {
113
- defer { scheduledNextRefreshTask = nil }
122
+ let expiresAt = Date ( timeIntervalSince1970 : refreshedSession . expiresAt )
123
+ let expiresIn = expiresAt . timeIntervalSinceNow
114
124
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 )
117
127
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 " )
120
129
121
- logger ? . debug ( " source: \( source ) scheduled next token refresh in: \ ( timeToRefresh) s " )
130
+ try ? await Task . sleep ( nanoseconds : NSEC_PER_SEC * UInt64 ( timeToRefresh) )
122
131
123
- try ? await Task . sleep ( nanoseconds: NSEC_PER_SEC * UInt64( timeToRefresh) )
132
+ if Task . isCancelled {
133
+ return
134
+ }
124
135
125
- if Task . isCancelled {
126
- return
136
+ _ = try ? await refreshSession ( refreshedSession . refreshToken )
137
+ }
127
138
}
128
-
129
- _ = try ? await refreshSession ( refreshedSession. refreshToken)
130
139
}
131
140
}
132
141
}
0 commit comments