55using Enyim . Caching ;
66using Enyim . Caching . Configuration ;
77using Enyim . Caching . Memcached ;
8+ using ServiceStack . Common . Extensions ;
89using ILog = ServiceStack . Logging . ILog ;
910using LogManager = ServiceStack . Logging . LogManager ;
1011
@@ -21,15 +22,16 @@ public class MemcachedClientCache
2122 {
2223 protected override ILog Log { get { return LogManager . GetLogger ( GetType ( ) ) ; } }
2324
24- private MemcachedClient client ;
25+ private MemcachedClient _client ;
2526
2627 public MemcachedClientCache ( IEnumerable < string > hosts )
2728 {
2829 const int defaultPort = 11211 ;
2930 const int ipAddressIndex = 0 ;
3031 const int portIndex = 1 ;
3132
32- this . client = new MemcachedClient ( ) ;
33+ _client = new MemcachedClient ( ) ;
34+
3335 var ipEndpoints = new List < IPEndPoint > ( ) ;
3436 foreach ( var host in hosts )
3537 {
@@ -67,7 +69,7 @@ private void LoadClient(IEnumerable<IPEndPoint> ipEndpoints)
6769 config . SocketPool . ConnectionTimeout = new TimeSpan ( 0 , 0 , 10 ) ;
6870 config . SocketPool . DeadTimeout = new TimeSpan ( 0 , 2 , 0 ) ;
6971
70- this . client = new MemcachedClient ( config ) ;
72+ _client = new MemcachedClient ( config ) ;
7173 }
7274
7375 public MemcachedClientCache ( MemcachedClient client )
@@ -76,22 +78,29 @@ public MemcachedClientCache(MemcachedClient client)
7678 {
7779 throw new ArgumentNullException ( "client" ) ;
7880 }
79- this . client = client ;
81+ _client = client ;
8082 }
8183
8284 public void Dispose ( )
8385 {
84- Execute ( ( ) => client . Dispose ( ) ) ;
85- }
86+ /*
87+ * DO NOTHING!!
88+ *
89+ * Calling _client.Dispose() breaks any call to a service that uses ICachClient
90+ * after a call to ServiceStack.ServiceInterface.ServiceExtension.GetSession.
91+ *
92+ * Enyim.Caching.MemcachedClient defines a destructor that handles all necessary cleanup (disposing is done there, we don't need to worry).
93+ */
94+ }
8695
8796 public bool Remove ( string key )
8897 {
89- return Execute ( ( ) => client . Remove ( key ) ) ;
98+ return Execute ( ( ) => _client . Remove ( key ) ) ;
9099 }
91100
92101 public object Get ( string key )
93102 {
94- return Execute ( ( ) => client . Get ( key ) ) ;
103+ return Execute ( ( ) => ( ( MemcachedValueWrapper ) _client . Get ( key ) ) . Value ) ;
95104 }
96105
97106 public object Get ( string key , out ulong ucas )
@@ -112,7 +121,13 @@ public object Get(string key, out ulong ucas)
112121
113122 public T Get < T > ( string key )
114123 {
115- return Execute ( ( ) => client . Get < T > ( key ) ) ;
124+ return Execute ( ( ) =>
125+ {
126+ var result = _client . Get < MemcachedValueWrapper > ( key ) ;
127+ if ( result != null )
128+ return ( T ) result . Value ;
129+ return default ( T ) ;
130+ } ) ;
116131 }
117132
118133 public T Get < T > ( string key , out ulong ucas )
@@ -133,110 +148,110 @@ public T Get<T>(string key, out ulong ucas)
133148
134149 public long Increment ( string key , uint amount )
135150 {
136- return Execute ( ( ) => ( long ) client . Increment ( key , 0 , amount ) ) ;
151+ return Execute ( ( ) => ( long ) _client . Increment ( key , 0 , amount ) ) ;
137152 }
138153
139154 public long Decrement ( string key , uint amount )
140155 {
141- return Execute ( ( ) => ( long ) client . Decrement ( key , 0 , amount ) ) ;
156+ return Execute ( ( ) => ( long ) _client . Decrement ( key , 0 , amount ) ) ;
142157 }
143158
144159 public bool Add < T > ( string key , T value )
145160 {
146- return Execute ( ( ) => client . Store ( StoreMode . Add , key , value ) ) ;
161+ return Execute ( ( ) => _client . Store ( StoreMode . Add , key , new MemcachedValueWrapper ( value ) ) ) ;
147162 }
148163
149164 public bool Set < T > ( string key , T value )
150165 {
151- return Execute ( ( ) => client . Store ( StoreMode . Set , key , value ) ) ;
166+ return Execute ( ( ) => _client . Store ( StoreMode . Set , key , new MemcachedValueWrapper ( value ) ) ) ;
152167 }
153168
154169 public bool Replace < T > ( string key , T value )
155170 {
156- return Execute ( ( ) => client . Store ( StoreMode . Replace , key , value ) ) ;
171+ return Execute ( ( ) => _client . Store ( StoreMode . Replace , key , new MemcachedValueWrapper ( value ) ) ) ;
157172 }
158173
159174 public bool Add < T > ( string key , T value , DateTime expiresAt )
160175 {
161- return Execute ( ( ) => client . Store ( StoreMode . Add , key , value , expiresAt ) ) ;
176+ return Execute ( ( ) => _client . Store ( StoreMode . Add , key , new MemcachedValueWrapper ( value ) , expiresAt ) ) ;
162177 }
163178
164179 public bool Set < T > ( string key , T value , DateTime expiresAt )
165180 {
166- return Execute ( ( ) => client . Store ( StoreMode . Set , key , value , expiresAt ) ) ;
181+ return Execute ( ( ) => _client . Store ( StoreMode . Set , key , new MemcachedValueWrapper ( value ) , expiresAt ) ) ;
167182 }
168183
169184 public bool Replace < T > ( string key , T value , DateTime expiresAt )
170185 {
171- return Execute ( ( ) => client . Store ( StoreMode . Replace , key , value , expiresAt ) ) ;
186+ return Execute ( ( ) => _client . Store ( StoreMode . Replace , key , new MemcachedValueWrapper ( value ) , expiresAt ) ) ;
172187 }
173188
174189 public bool Add < T > ( string key , T value , TimeSpan expiresIn )
175190 {
176- return Execute ( ( ) => client . Store ( StoreMode . Add , key , value , expiresIn ) ) ;
191+ return Execute ( ( ) => _client . Store ( StoreMode . Add , key , new MemcachedValueWrapper ( value ) , expiresIn ) ) ;
177192 }
178193
179194 public bool Set < T > ( string key , T value , TimeSpan expiresIn )
180195 {
181- return Execute ( ( ) => client . Store ( StoreMode . Set , key , value , expiresIn ) ) ;
196+ return Execute ( ( ) => _client . Store ( StoreMode . Set , key , new MemcachedValueWrapper ( value ) , expiresIn ) ) ;
182197 }
183198
184199 public bool Replace < T > ( string key , T value , TimeSpan expiresIn )
185200 {
186- return Execute ( ( ) => client . Store ( StoreMode . Replace , key , value , expiresIn ) ) ;
201+ return Execute ( ( ) => _client . Store ( StoreMode . Replace , key , new MemcachedValueWrapper ( value ) , expiresIn ) ) ;
187202 }
188203
189204 public bool Add ( string key , object value )
190205 {
191- return Execute ( ( ) => client . Store ( StoreMode . Add , key , value ) ) ;
206+ return Execute ( ( ) => _client . Store ( StoreMode . Add , key , new MemcachedValueWrapper ( value ) ) ) ;
192207 }
193208
194209 public bool Set ( string key , object value )
195210 {
196- return Execute ( ( ) => client . Store ( StoreMode . Set , key , value ) ) ;
211+ return Execute ( ( ) => _client . Store ( StoreMode . Set , key , new MemcachedValueWrapper ( value ) ) ) ;
197212 }
198213
199214 public bool Replace ( string key , object value )
200215 {
201- return Execute ( ( ) => client . Store ( StoreMode . Replace , key , value ) ) ;
216+ return Execute ( ( ) => _client . Store ( StoreMode . Replace , key , new MemcachedValueWrapper ( value ) ) ) ;
202217 }
203218
204219 public bool Add ( string key , object value , DateTime expiresAt )
205220 {
206- return Execute ( ( ) => client . Store ( StoreMode . Add , key , value , expiresAt ) ) ;
221+ return Execute ( ( ) => _client . Store ( StoreMode . Add , key , new MemcachedValueWrapper ( value ) , expiresAt ) ) ;
207222 }
208223
209224 public bool Set ( string key , object value , DateTime expiresAt )
210225 {
211- return Execute ( ( ) => client . Store ( StoreMode . Set , key , value , expiresAt ) ) ;
226+ return Execute ( ( ) => _client . Store ( StoreMode . Set , key , new MemcachedValueWrapper ( value ) , expiresAt ) ) ;
212227 }
213228
214229 public bool Replace ( string key , object value , DateTime expiresAt )
215230 {
216- return Execute ( ( ) => client . Store ( StoreMode . Replace , key , value , expiresAt ) ) ;
231+ return Execute ( ( ) => _client . Store ( StoreMode . Replace , key , new MemcachedValueWrapper ( value ) , expiresAt ) ) ;
217232 }
218233
219234 public bool CheckAndSet ( string key , object value , ulong cas )
220235 {
221- return Execute ( ( ) => client . Cas ( StoreMode . Replace , key , value , cas ) . Result ) ;
236+ return Execute ( ( ) => _client . Cas ( StoreMode . Replace , key , new MemcachedValueWrapper ( value ) , cas ) . Result ) ;
222237 }
223238
224239 public bool CheckAndSet ( string key , object value , ulong cas , DateTime expiresAt )
225240 {
226- return Execute ( ( ) => client . Cas ( StoreMode . Replace , key , value , expiresAt , cas ) . Result ) ;
241+ return Execute ( ( ) => _client . Cas ( StoreMode . Replace , key , new MemcachedValueWrapper ( value ) , expiresAt , cas ) . Result ) ;
227242 }
228243
229244 public void FlushAll ( )
230245 {
231- Execute ( ( ) => client . FlushAll ( ) ) ;
246+ Execute ( ( ) => _client . FlushAll ( ) ) ;
232247 }
233248
234249 public IDictionary < string , T > GetAll < T > ( IEnumerable < string > keys )
235250 {
236251 var results = new Dictionary < string , T > ( ) ;
237252 foreach ( var key in keys )
238253 {
239- var result = this . Get < T > ( key ) ;
254+ var result = Get < T > ( key ) ;
240255 results [ key ] = result ;
241256 }
242257
@@ -247,25 +262,29 @@ public void SetAll<T>(IDictionary<string, T> values)
247262 {
248263 foreach ( var entry in values )
249264 {
250- Set ( entry . Key , entry . Value ) ;
265+ Set ( entry . Key , new MemcachedValueWrapper ( entry . Value ) ) ;
251266 }
252267 }
253268
254269 public IDictionary < string , object > GetAll ( IEnumerable < string > keys )
255270 {
256- return Execute ( ( ) => client . Get ( keys ) ) ;
271+ var results = new Dictionary < string , object > ( ) ;
272+ foreach ( var key in keys )
273+ {
274+ var result = Get ( key ) ;
275+ results [ key ] = result ;
276+ }
277+
278+ return results ;
257279 }
258280
259281 public IDictionary < string , object > GetAll ( IEnumerable < string > keys , out IDictionary < string , ulong > casValues )
260282 {
261- //Can't call methods with 'out' params in anonymous method blocks
262- //Calling client directly instead - Add try{} if warranted.
263-
264283 var retVal = new Dictionary < string , object > ( ) ;
265284 casValues = new Dictionary < string , ulong > ( ) ;
266- foreach ( var casResult in client . GetWithCas ( keys ) )
285+ foreach ( var casResult in _client . GetWithCas ( keys ) )
267286 {
268- retVal . Add ( casResult . Key , casResult . Value . Result ) ;
287+ retVal . Add ( casResult . Key , ( ( MemcachedValueWrapper ) casResult . Value . Result ) . Value ) ;
269288 casValues . Add ( casResult . Key , casResult . Value . Cas ) ;
270289 }
271290 return retVal ;
@@ -277,14 +296,13 @@ public void RemoveAll(IEnumerable<string> keys)
277296 {
278297 try
279298 {
280- this . Remove ( key ) ;
299+ Remove ( key ) ;
281300 }
282301 catch ( Exception ex )
283302 {
284303 Log . Error ( string . Format ( "Error trying to remove {0} from memcached" , key ) , ex ) ;
285304 }
286305 }
287306 }
288-
289307 }
290308}
0 commit comments