2
2
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3
3
4
4
using System ;
5
+ using System . Collections ;
5
6
using System . Collections . Generic ;
6
7
using System . IO ;
7
8
using System . Linq ;
@@ -26,8 +27,8 @@ public class DistributedSession : ISession
26
27
private readonly string _sessionKey ;
27
28
private readonly TimeSpan _idleTimeout ;
28
29
private readonly Func < bool > _tryEstablishSession ;
29
- private readonly IDictionary < EncodedKey , byte [ ] > _store ;
30
30
private readonly ILogger _logger ;
31
+ private IDictionary < EncodedKey , byte [ ] > _store ;
31
32
private bool _isModified ;
32
33
private bool _loaded ;
33
34
private bool _isAvailable ;
@@ -86,27 +87,19 @@ public string Id
86
87
get
87
88
{
88
89
Load ( ) ;
89
- if ( _isAvailable )
90
+ if ( _sessionId == null )
90
91
{
91
- if ( _sessionId == null )
92
- {
93
- _sessionId = new Guid ( IdBytes ) . ToString ( ) ;
94
- }
95
- return _sessionId ;
96
- }
97
- else
98
- {
99
- return string . Empty ;
92
+ _sessionId = new Guid ( IdBytes ) . ToString ( ) ;
100
93
}
94
+ return _sessionId ;
101
95
}
102
96
}
103
97
104
98
private byte [ ] IdBytes
105
99
{
106
100
get
107
101
{
108
- Load ( ) ;
109
- if ( _isAvailable )
102
+ if ( IsAvailable )
110
103
{
111
104
if ( _sessionIdBytes == null )
112
105
{
@@ -127,29 +120,14 @@ public IEnumerable<string> Keys
127
120
get
128
121
{
129
122
Load ( ) ;
130
- if ( _isAvailable )
131
- {
132
- return _store . Keys . Select ( key => key . KeyString ) ;
133
- }
134
- else
135
- {
136
- return Enumerable . Empty < string > ( ) ;
137
- }
123
+ return _store . Keys . Select ( key => key . KeyString ) ;
138
124
}
139
125
}
140
126
141
127
public bool TryGetValue ( string key , out byte [ ] value )
142
128
{
143
129
Load ( ) ;
144
- if ( _isAvailable )
145
- {
146
- return _store . TryGetValue ( new EncodedKey ( key ) , out value ) ;
147
- }
148
- else
149
- {
150
- value = default ( byte [ ] ) ;
151
- return false ;
152
- }
130
+ return _store . TryGetValue ( new EncodedKey ( key ) , out value ) ;
153
131
}
154
132
155
133
public void Set ( string key , byte [ ] value )
@@ -159,16 +137,15 @@ public void Set(string key, byte[] value)
159
137
throw new ArgumentNullException ( nameof ( value ) ) ;
160
138
}
161
139
162
- var encodedKey = new EncodedKey ( key ) ;
163
- if ( encodedKey . KeyBytes . Length > KeyLengthLimit )
140
+ if ( IsAvailable )
164
141
{
165
- throw new ArgumentOutOfRangeException ( nameof ( key ) ,
166
- Resources . FormatException_KeyLengthIsExceeded ( KeyLengthLimit ) ) ;
167
- }
142
+ var encodedKey = new EncodedKey ( key ) ;
143
+ if ( encodedKey . KeyBytes . Length > KeyLengthLimit )
144
+ {
145
+ throw new ArgumentOutOfRangeException ( nameof ( key ) ,
146
+ Resources . FormatException_KeyLengthIsExceeded ( KeyLengthLimit ) ) ;
147
+ }
168
148
169
- Load ( ) ;
170
- if ( _isAvailable )
171
- {
172
149
if ( ! _tryEstablishSession ( ) )
173
150
{
174
151
throw new InvalidOperationException ( Resources . Exception_InvalidSessionEstablishment ) ;
@@ -183,20 +160,14 @@ public void Set(string key, byte[] value)
183
160
public void Remove ( string key )
184
161
{
185
162
Load ( ) ;
186
- if ( _isAvailable )
187
- {
188
- _isModified |= _store . Remove ( new EncodedKey ( key ) ) ;
189
- }
163
+ _isModified |= _store . Remove ( new EncodedKey ( key ) ) ;
190
164
}
191
165
192
166
public void Clear ( )
193
167
{
194
168
Load ( ) ;
195
- if ( _isAvailable )
196
- {
197
- _isModified |= _store . Count > 0 ;
198
- _store . Clear ( ) ;
199
- }
169
+ _isModified |= _store . Count > 0 ;
170
+ _store . Clear ( ) ;
200
171
}
201
172
202
173
private void Load ( )
@@ -220,6 +191,8 @@ private void Load()
220
191
{
221
192
_logger . SessionCacheReadException ( _sessionKey , exception ) ;
222
193
_isAvailable = false ;
194
+ _sessionId = string . Empty ;
195
+ _store = new EmptySessionStore ( ) ;
223
196
}
224
197
finally
225
198
{
@@ -228,8 +201,7 @@ private void Load()
228
201
}
229
202
}
230
203
231
- // TODO: This should throw if called directly, but most other places it should fail silently
232
- // (e.g. TryGetValue should just return null).
204
+ // This will throw if called directly and a failure occurs. The user is expected to handle the failures.
233
205
public async Task LoadAsync ( )
234
206
{
235
207
if ( ! _loaded )
@@ -268,7 +240,6 @@ public async Task CommitAsync()
268
240
return ;
269
241
}
270
242
}
271
- _isModified = false ;
272
243
273
244
var stream = new MemoryStream ( ) ;
274
245
Serialize ( stream ) ;
@@ -285,6 +256,8 @@ await _cache.SetAsync(
285
256
_logger . SessionCacheWriteException ( _sessionKey , Id , exception ) ;
286
257
return ;
287
258
}
259
+
260
+ _isModified = false ;
288
261
_logger . SessionStored ( _sessionKey , Id , _store . Count ) ;
289
262
}
290
263
else
@@ -329,7 +302,6 @@ private void Deserialize(Stream content)
329
302
{
330
303
if ( content == null || content . ReadByte ( ) != SerializationRevision )
331
304
{
332
- // TODO: Throw?
333
305
// Replace the un-readable format.
334
306
_isModified = true ;
335
307
return ;
@@ -489,5 +461,55 @@ public override string ToString()
489
461
return KeyString ;
490
462
}
491
463
}
464
+
465
+ private class EmptySessionStore : IDictionary < EncodedKey , byte [ ] >
466
+ {
467
+ public byte [ ] this [ EncodedKey key ]
468
+ {
469
+ get
470
+ {
471
+ return null ;
472
+ }
473
+
474
+ set
475
+ {
476
+
477
+ }
478
+ }
479
+
480
+ public int Count { get ; } = 0 ;
481
+
482
+ public bool IsReadOnly { get ; } = false ;
483
+
484
+ public ICollection < EncodedKey > Keys { get ; } = new EncodedKey [ 0 ] ;
485
+
486
+ public ICollection < byte [ ] > Values { get ; } = new byte [ 0 ] [ ] ;
487
+
488
+ public void Add ( KeyValuePair < EncodedKey , byte [ ] > item ) { }
489
+
490
+ public void Add ( EncodedKey key , byte [ ] value ) { }
491
+
492
+ public void Clear ( ) { }
493
+
494
+ public bool Contains ( KeyValuePair < EncodedKey , byte [ ] > item ) => false ;
495
+
496
+ public bool ContainsKey ( EncodedKey key ) => false ;
497
+
498
+ public void CopyTo ( KeyValuePair < EncodedKey , byte [ ] > [ ] array , int arrayIndex ) { }
499
+
500
+ public IEnumerator < KeyValuePair < EncodedKey , byte [ ] > > GetEnumerator ( ) => Enumerable . Empty < KeyValuePair < EncodedKey , byte [ ] > > ( ) . GetEnumerator ( ) ;
501
+
502
+ public bool Remove ( KeyValuePair < EncodedKey , byte [ ] > item ) => false ;
503
+
504
+ public bool Remove ( EncodedKey key ) => false ;
505
+
506
+ public bool TryGetValue ( EncodedKey key , out byte [ ] value )
507
+ {
508
+ value = null ;
509
+ return false ;
510
+ }
511
+
512
+ IEnumerator IEnumerable . GetEnumerator ( ) => GetEnumerator ( ) ;
513
+ }
492
514
}
493
515
}
0 commit comments