@@ -11,6 +11,7 @@ import protocol MacroCore.EnvironmentKey
11
11
import class http. IncomingMessage
12
12
import class http. ServerResponse
13
13
import struct Foundation. UUID
14
+ import struct NIOConcurrencyHelpers. NIOLock
14
15
15
16
fileprivate let sessionIdCookie = Cookie ( name: " NzSID " , maxAge: 3600 )
16
17
@@ -42,17 +43,19 @@ public func session(store s : SessionStore = InMemorySessionStore(),
42
43
return next ( )
43
44
}
44
45
46
+ // TODO: This should do a session-checkout.
45
47
// retrieve from store
46
48
s. get ( sessionID: sessionID) { err, session in
47
- guard err == nil else {
48
- console. log ( " could not retrieve session with ID \( sessionID) : \( err!) " )
49
+ if let rerr = err {
50
+ req. log
51
+ . notice ( " could not retrieve session with ID \( sessionID) : \( rerr) " )
49
52
ctx. configureNewSession ( )
50
53
return next ( )
51
54
}
52
55
53
56
guard let rsession = session else {
54
- console . log ( " No error, but could not retrieve session with ID " +
55
- " \( sessionID) " )
57
+ req . log. notice (
58
+ " No error, but could not retrieve session with ID \( sessionID) " )
56
59
ctx. configureNewSession ( )
57
60
return next ( )
58
61
}
@@ -61,9 +64,10 @@ public func session(store s : SessionStore = InMemorySessionStore(),
61
64
req. environment [ SessionKey . self] = rsession
62
65
ctx. pushSessionCookie ( )
63
66
_ = res. onceFinish {
67
+ // TODO: This should do the session-checkin.
64
68
s. set ( sessionID: sessionID, session: req. session) { err in
65
69
if let err = err {
66
- console . error ( " could not save session \( sessionID) : \( err) " )
70
+ req . log . error ( " could not save session \( sessionID) : \( err) " )
67
71
}
68
72
}
69
73
}
@@ -122,7 +126,7 @@ class SessionContext {
122
126
_ = res. onceFinish {
123
127
store. set ( sessionID: newSessionID, session: req. session) { err in
124
128
if let err = err {
125
- console . error ( " could not save new session \( newSessionID) : \( err) " )
129
+ req . log . error ( " could not save new session \( newSessionID) : \( err) " )
126
130
}
127
131
}
128
132
}
@@ -140,20 +144,24 @@ public class Session {
140
144
//
141
145
// req.session["a"] = 10
142
146
//
143
- // Think about it, kinda non-obvious ;-)
147
+ // kinda non-obvious.
144
148
149
+ // This should not be concurrent but use a checkin/checkout system.
150
+ fileprivate let lock = NIOLock ( )
145
151
public var values = Dictionary < String , Any > ( )
146
152
147
153
public subscript( key: String ) -> Any ? {
148
154
set {
149
- if let v = newValue { values [ key] = v }
150
- else { values. removeValue ( forKey: key) }
155
+ lock. withLock {
156
+ if let v = newValue { values [ key] = v }
157
+ else { _ = values. removeValue ( forKey: key) }
158
+ }
151
159
}
152
- get { return values [ key] }
160
+ get { return lock . withLock { values [ key] } }
153
161
}
154
162
155
163
public subscript( int key: String ) -> Int {
156
- guard let v = values [ key] else { return 0 }
164
+ guard let v = lock . withLock ( { values [ key] } ) else { return 0 }
157
165
if let iv = v as? Int { return iv }
158
166
#if swift(>=5.10)
159
167
if let i = ( v as? any BinaryInteger ) { return Int ( i) }
@@ -228,14 +236,16 @@ public extension SessionStore {
228
236
229
237
public class InMemorySessionStore : SessionStore {
230
238
239
+ // Well, there should be a checkout/checkin system?!
240
+ fileprivate let lock = NIOLock ( )
231
241
var store : [ String : Session ]
232
242
233
243
public init ( ) {
234
244
store = [ : ]
235
245
}
236
246
237
247
public func get( sessionID sid: String , _ cb: ( Error ? , Session ? ) -> Void ) {
238
- guard let session = store [ sid] else {
248
+ guard let session = lock . withLock ( { store [ sid] } ) else {
239
249
cb ( SessionStoreError . SessionNotFound, nil )
240
250
return
241
251
}
@@ -245,7 +255,7 @@ public class InMemorySessionStore : SessionStore {
245
255
public func set( sessionID sid: String , session: Session ,
246
256
_ cb: ( Error ? ) -> Void )
247
257
{
248
- store [ sid] = session
258
+ lock . withLock { store [ sid] = session }
249
259
cb ( nil )
250
260
}
251
261
@@ -256,21 +266,21 @@ public class InMemorySessionStore : SessionStore {
256
266
}
257
267
258
268
public func destroy( sessionID sid: String , _ cb: ( String ) -> Void ) {
259
- store. removeValue ( forKey: sid)
269
+ lock . withLock { _ = store. removeValue ( forKey: sid) }
260
270
cb ( sid)
261
271
}
262
272
263
273
public func clear( cb: ( Error ? ) -> Void ) {
264
- store. removeAll ( )
274
+ lock . withLock { store. removeAll ( ) }
265
275
cb ( nil )
266
276
}
267
277
268
278
public func length( cb: ( Error ? , Int ) -> Void ) {
269
- cb ( nil , store. count)
279
+ cb ( nil , lock . withLock { store. count } )
270
280
}
271
281
272
282
public func all( cb: ( Error ? , [ Session ] ) -> Void ) {
273
- let values = Array ( store. values)
283
+ let values = Array ( lock . withLock { store. values } )
274
284
cb ( nil , values)
275
285
}
276
286
}
0 commit comments