Skip to content
This repository
Browse code

Touch&Gat implementation.

  • Loading branch information...
commit 9c574e67929fc7f89bbd18642be2cb4df50db020 1 parent 14ee46f
Attila Kiskó authored March 29, 2011
3  .gitignore
@@ -3,4 +3,5 @@
3 3
 TestResults/*
4 4
 *.suo
5 5
 *.user
6  
-build/output/*
  6
+build/output/*
  7
+_ReSharper*
3  Enyim.Caching/Memcached/Protocol/Binary/BinaryConverter.cs
@@ -3,7 +3,7 @@
3 3
 
4 4
 namespace Enyim.Caching.Memcached.Protocol.Binary
5 5
 {
6  
-	internal static class BinaryConverter
  6
+	public static class BinaryConverter
7 7
 	{
8 8
 		public static unsafe int DecodeInt16(byte* buffer, int offset)
9 9
 		{
@@ -26,6 +26,7 @@ public static unsafe int DecodeInt32(byte* buffer, int offset)
26 26
 
27 27
 			return (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
28 28
 		}
  29
+
29 30
 		public static unsafe ulong DecodeUInt64(byte[] buffer, int offset)
30 31
 		{
31 32
 			fixed (byte* ptr = buffer)
13  Enyim.Caching/Memcached/Protocol/Binary/BinaryRequest.cs
@@ -10,14 +10,17 @@ public class BinaryRequest
10 10
 		private static readonly Enyim.Caching.ILog log = Enyim.Caching.LogManager.GetLogger(typeof(BinaryRequest));
11 11
 		private static int InstanceCounter;
12 12
 
13  
-		public OpCode Operation;
  13
+		public byte Operation;
  14
+		public readonly int CorrelationId;
  15
+
14 16
 		public string Key;
15 17
 		public ulong Cas;
16  
-		public readonly int CorrelationId;
17 18
 
18  
-		public BinaryRequest(OpCode operation)
  19
+		public BinaryRequest(OpCode operation) : this((byte)operation) { }
  20
+
  21
+		public BinaryRequest(byte commandCode)
19 22
 		{
20  
-			this.Operation = operation;
  23
+			this.Operation = commandCode;
21 24
 			// session id
22 25
 			this.CorrelationId = Interlocked.Increment(ref InstanceCounter);
23 26
 		}
@@ -53,7 +56,7 @@ public unsafe IList<ArraySegment<byte>> CreateBuffer(IList<ArraySegment<byte>> a
53 56
 			fixed (byte* buffer = header)
54 57
 			{
55 58
 				buffer[0x00] = 0x80; // magic
56  
-				buffer[0x01] = (byte)this.Operation;
  59
+				buffer[0x01] = this.Operation;
57 60
 
58 61
 				// key length
59 62
 				buffer[0x02] = (byte)(keyLength >> 8);
6  Enyim.Caching/MemcachedClient.cs
@@ -833,10 +833,10 @@ private static void SafeWaitAllAndDispose(WaitHandle[] waitHandles)
833 833
 
834 834
 		#region [ Expiration helper            ]
835 835
 
836  
-		private const int MaxSeconds = 60 * 60 * 24 * 30;
837  
-		private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1);
  836
+		protected const int MaxSeconds = 60 * 60 * 24 * 30;
  837
+		protected static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1);
838 838
 
839  
-		private static uint GetExpiration(TimeSpan? validFor, DateTime? expiresAt)
  839
+		protected static uint GetExpiration(TimeSpan? validFor, DateTime? expiresAt)
840 840
 		{
841 841
 			if (validFor != null && expiresAt != null)
842 842
 				throw new ArgumentException("You cannot specify both validFor and expiresAt.");
39  Membase/BasicMembaseOperationFactory.cs
... ...
@@ -0,0 +1,39 @@
  1
+using System;
  2
+
  3
+namespace Membase
  4
+{
  5
+	internal class BasicMembaseOperationFactory : Enyim.Caching.Memcached.Protocol.Binary.BinaryOperationFactory, IMembaseOperationFactory
  6
+	{
  7
+		internal static readonly BasicMembaseOperationFactory Instance = new BasicMembaseOperationFactory();
  8
+
  9
+		ITouchOperation IMembaseOperationFactory.Touch(string key, uint newExpiration)
  10
+		{
  11
+			return new TouchOperation(null, key, newExpiration);
  12
+		}
  13
+
  14
+		IGetAndTouchOperation IMembaseOperationFactory.GetAndTouch(string key, uint newExpiration)
  15
+		{
  16
+			return new GetAndTouchOperation(null, key, newExpiration);
  17
+		}
  18
+	}
  19
+}
  20
+
  21
+#region [ License information          ]
  22
+/* ************************************************************
  23
+ * 
  24
+ *    Copyright (c) 2010 Attila Kiskó, enyim.com
  25
+ *    
  26
+ *    Licensed under the Apache License, Version 2.0 (the "License");
  27
+ *    you may not use this file except in compliance with the License.
  28
+ *    You may obtain a copy of the License at
  29
+ *    
  30
+ *        http://www.apache.org/licenses/LICENSE-2.0
  31
+ *    
  32
+ *    Unless required by applicable law or agreed to in writing, software
  33
+ *    distributed under the License is distributed on an "AS IS" BASIS,
  34
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  35
+ *    See the License for the specific language governing permissions and
  36
+ *    limitations under the License.
  37
+ *    
  38
+ * ************************************************************/
  39
+#endregion
14  Membase/IMembaseOperationFactory.cs
... ...
@@ -0,0 +1,14 @@
  1
+using System;
  2
+using System.Collections.Generic;
  3
+using System.Linq;
  4
+using System.Text;
  5
+using Enyim.Caching.Memcached;
  6
+
  7
+namespace Membase
  8
+{
  9
+	public interface IMembaseOperationFactory : IOperationFactory
  10
+	{
  11
+		ITouchOperation Touch(string key, uint newExpiration);
  12
+		IGetAndTouchOperation GetAndTouch(string key, uint newExpiration);
  13
+	}
  14
+}
13  Membase/IMembaseServerPool.cs
... ...
@@ -0,0 +1,13 @@
  1
+using System;
  2
+using System.Collections.Generic;
  3
+using System.Linq;
  4
+using System.Text;
  5
+using Enyim.Caching.Memcached;
  6
+
  7
+namespace Membase
  8
+{
  9
+	public interface IMembaseServerPool : IServerPool
  10
+	{
  11
+		IMembaseOperationFactory OperationFactory { get; }
  12
+	}
  13
+}
6  Membase/Membase.csproj
@@ -54,11 +54,17 @@
54 54
     <Compile Include="Configuration\UriElement.cs" />
55 55
     <Compile Include="Configuration\UriElementCollection.cs" />
56 56
     <Compile Include="Configuration\UriValidator.cs" />
  57
+    <Compile Include="Operations\GetAndTouchOperation.cs" />
  58
+    <Compile Include="BasicMembaseOperationFactory.cs" />
  59
+    <Compile Include="OperationInterfaces.cs" />
57 60
     <Compile Include="Deserialization.cs" />
  61
+    <Compile Include="IMembaseOperationFactory.cs" />
  62
+    <Compile Include="IMembaseServerPool.cs" />
58 63
     <Compile Include="MessageStreamListener.cs" />
59 64
     <Compile Include="MembaseClient.cs" />
60 65
     <Compile Include="MembasePool.cs" />
61 66
     <Compile Include="Properties\AssemblyInfo.cs" />
  67
+    <Compile Include="Operations\TouchOperation.cs" />
62 68
     <Compile Include="VBucketAwareOperationFactory.cs" />
63 69
     <Compile Include="WebClientWithTimeout.cs">
64 70
       <SubType>Component</SubType>
99  Membase/MembaseClient.cs
@@ -15,7 +15,7 @@ public class MembaseClient : MemcachedClient
15 15
 		private static readonly Enyim.Caching.ILog log = Enyim.Caching.LogManager.GetLogger(typeof(MembaseClient));
16 16
 		private static readonly IMembaseClientConfiguration DefaultConfig = (IMembaseClientConfiguration)ConfigurationManager.GetSection("membase");
17 17
 
18  
-		private MembasePool poolInstance;
  18
+		private IMembaseServerPool poolInstance;
19 19
 
20 20
 		/// <summary>
21 21
 		/// Initializes a new instance of the <see cref="T:Membase.MembaseClient" /> class using the default configuration and bucket.
@@ -60,7 +60,7 @@ public class MembaseClient : MemcachedClient
60 60
 					configuration.CreateTranscoder(),
61 61
 					configuration.CreatePerformanceMonitor())
62 62
 		{
63  
-			this.poolInstance = (MembasePool)this.Pool;
  63
+			this.poolInstance = (IMembaseServerPool)this.Pool;
64 64
 		}
65 65
 
66 66
 		/// <summary>Obsolete. Use .ctor(bucket, password) to explicitly set the bucket password.</summary>
@@ -228,6 +228,101 @@ private bool ExecuteWithRedirect(IMemcachedNode startNode, ISingleItemOperation
228 228
 
229 229
 			return false;
230 230
 		}
  231
+
  232
+		public void Touch(string key, DateTime nextExpiration)
  233
+		{
  234
+			PerformTouch(key, GetExpiration(null, nextExpiration));
  235
+		}
  236
+
  237
+		public void Touch(string key, TimeSpan nextExpiration)
  238
+		{
  239
+			PerformTouch(key, GetExpiration(nextExpiration, null));
  240
+		}
  241
+
  242
+		protected void PerformTouch(string key, uint nextExpiration)
  243
+		{
  244
+			var hashedKey = this.KeyTransformer.Transform(key);
  245
+			var node = this.Pool.Locate(hashedKey);
  246
+
  247
+			if (node != null)
  248
+			{
  249
+				var command = this.poolInstance.OperationFactory.Touch(key, nextExpiration);
  250
+				var retval = ExecuteWithRedirect(node, command);
  251
+			}
  252
+		}
  253
+
  254
+		public object Get(string key, DateTime newExpiration)
  255
+		{
  256
+			object tmp;
  257
+
  258
+			return this.TryGet(key, newExpiration, out tmp) ? tmp : null;
  259
+		}
  260
+
  261
+		public T Get<T>(string key, DateTime newExpiration)
  262
+		{
  263
+			object tmp;
  264
+
  265
+			return TryGet(key, newExpiration, out tmp) ? (T)tmp : default(T);
  266
+		}
  267
+
  268
+		public bool TryGet(string key, DateTime newExpiration, out object value)
  269
+		{
  270
+			ulong cas = 0;
  271
+
  272
+			return this.PerformTryGetAndTouch(key, MemcachedClient.GetExpiration(null, newExpiration), out cas, out value);
  273
+		}
  274
+
  275
+		public CasResult<object> GetWithCas(string key, DateTime newExpiration)
  276
+		{
  277
+			return this.GetWithCas<object>(key, newExpiration);
  278
+		}
  279
+
  280
+		public CasResult<T> GetWithCas<T>(string key, DateTime newExpiration)
  281
+		{
  282
+			CasResult<object> tmp;
  283
+
  284
+			return this.TryGetWithCas(key, newExpiration, out tmp)
  285
+					? new CasResult<T> { Cas = tmp.Cas, Result = (T)tmp.Result }
  286
+					: new CasResult<T> { Cas = tmp.Cas, Result = default(T) };
  287
+		}
  288
+
  289
+		public bool TryGetWithCas(string key, DateTime newExpiration, out CasResult<object> value)
  290
+		{
  291
+			object tmp;
  292
+			ulong cas;
  293
+
  294
+			var retval = this.PerformTryGetAndTouch(key, MemcachedClient.GetExpiration(null, newExpiration), out cas, out tmp);
  295
+
  296
+			value = new CasResult<object> { Cas = cas, Result = tmp };
  297
+
  298
+			return retval;
  299
+		}
  300
+
  301
+		protected bool PerformTryGetAndTouch(string key, uint nextExpiration, out ulong cas, out object value)
  302
+		{
  303
+			var hashedKey = this.KeyTransformer.Transform(key);
  304
+			var node = this.Pool.Locate(hashedKey);
  305
+
  306
+			if (node != null)
  307
+			{
  308
+				var command = this.poolInstance.OperationFactory.GetAndTouch(hashedKey, nextExpiration);
  309
+
  310
+				if (this.ExecuteWithRedirect(node, command))
  311
+				{
  312
+					value = this.Transcoder.Deserialize(command.Result);
  313
+					cas = command.CasValue;
  314
+					if (this.PerformanceMonitor != null) this.PerformanceMonitor.Get(1, true);
  315
+
  316
+					return true;
  317
+				}
  318
+			}
  319
+
  320
+			value = null;
  321
+			cas = 0;
  322
+			if (this.PerformanceMonitor != null) this.PerformanceMonitor.Get(1, false);
  323
+
  324
+			return false;
  325
+		}
231 326
 	}
232 327
 }
233 328
 
11  Membase/MembasePool.cs
@@ -13,7 +13,7 @@ namespace Membase
13 13
 	/// <summary>
14 14
 	/// Socket pool using the Membase server's dynamic node list
15 15
 	/// </summary>
16  
-	internal class MembasePool : IServerPool
  16
+	internal class MembasePool : IMembaseServerPool
17 17
 	{
18 18
 		private static readonly Enyim.Caching.ILog log = Enyim.Caching.LogManager.GetLogger(typeof(MembasePool));
19 19
 
@@ -236,7 +236,7 @@ private InternalState InitBasic(ClusterConfig config, ISaslAuthenticationProvide
236 236
 			{
237 237
 				CurrentNodes = tmp.ToArray(),
238 238
 				Locator = this.configuration.CreateNodeLocator() ?? new KetamaNodeLocator(),
239  
-				OpFactory = new Enyim.Caching.Memcached.Protocol.Binary.BinaryOperationFactory()
  239
+				OpFactory = BasicMembaseOperationFactory.Instance
240 240
 			};
241 241
 		}
242 242
 
@@ -421,6 +421,11 @@ IOperationFactory IServerPool.OperationFactory
421 421
 			get { return this.state.OpFactory; }
422 422
 		}
423 423
 
  424
+		IMembaseOperationFactory IMembaseServerPool.OperationFactory
  425
+		{
  426
+			get { return this.state.OpFactory; }
  427
+		}
  428
+
424 429
 		IEnumerable<IMemcachedNode> IServerPool.GetWorkingNodes()
425 430
 		{
426 431
 			return this.state.Locator.GetWorkingNodes();
@@ -456,7 +461,7 @@ private class InternalState
456 461
 
457 462
 			public IMemcachedNodeLocator Locator;
458 463
 			public VBucketNodeLocator ForwardLocator;
459  
-			public IOperationFactory OpFactory;
  464
+			public IMembaseOperationFactory OpFactory;
460 465
 			public IMemcachedNode[] CurrentNodes;
461 466
 
462 467
 			// if this is false, it's safe to reinitialize/recreate the locator when a server goes offline
11  Membase/OperationInterfaces.cs
... ...
@@ -0,0 +1,11 @@
  1
+using System;
  2
+using System.Collections.Generic;
  3
+using System.Linq;
  4
+using System.Text;
  5
+using Enyim.Caching.Memcached;
  6
+
  7
+namespace Membase
  8
+{
  9
+	public interface ITouchOperation : ISingleItemOperation { }
  10
+	public interface IGetAndTouchOperation : IGetOperation { }
  11
+}
88  Membase/Operations/GetAndTouchOperation.cs
... ...
@@ -0,0 +1,88 @@
  1
+using System;
  2
+using System.Collections.Generic;
  3
+using System.Linq;
  4
+using System.Text;
  5
+using Enyim.Caching.Memcached.Protocol.Binary;
  6
+using Enyim.Caching.Memcached;
  7
+using System.IO;
  8
+using System.Threading;
  9
+using Enyim.Caching;
  10
+
  11
+namespace Membase
  12
+{
  13
+	internal class GetAndTouchOperation : GetOperation, IGetAndTouchOperation, IOperationWithState
  14
+	{
  15
+		private static readonly Enyim.Caching.ILog log = Enyim.Caching.LogManager.GetLogger(typeof(GetAndTouchOperation));
  16
+
  17
+		private uint newExpiration;
  18
+		private OperationState state;
  19
+		private VBucketNodeLocator locator;
  20
+
  21
+		public GetAndTouchOperation(VBucketNodeLocator locator, string key, uint newExpiration)
  22
+			: base(key)
  23
+		{
  24
+			this.locator = locator;
  25
+			this.newExpiration = newExpiration;
  26
+		}
  27
+
  28
+		protected override BinaryRequest Build()
  29
+		{
  30
+			var retval = base.Build();
  31
+			retval.Operation = 0x1d;
  32
+
  33
+			if (this.locator != null)
  34
+			{
  35
+				retval.Reserved = (ushort)locator.GetIndex(this.Key);
  36
+
  37
+				if (log.IsDebugEnabled) log.DebugFormat("Key {0} was mapped to {1}", this.Key, retval.Reserved);
  38
+			}
  39
+
  40
+			var extra = new byte[4];
  41
+
  42
+			BinaryConverter.EncodeUInt32(this.newExpiration, extra, 0);
  43
+			retval.Extra = new ArraySegment<byte>(extra);
  44
+
  45
+			return retval;
  46
+		}
  47
+
  48
+		protected override bool ProcessResponse(BinaryResponse response)
  49
+		{
  50
+			var r = base.ProcessResponse(response);
  51
+
  52
+			if (this.locator != null &&
  53
+				!VBucketAwareOperationFactory.GuessResponseState(response, out this.state))
  54
+				return false;
  55
+
  56
+			return r;
  57
+		}
  58
+
  59
+		#region [ IOperationWithState          ]
  60
+
  61
+		OperationState IOperationWithState.State
  62
+		{
  63
+			get { return this.state; }
  64
+		}
  65
+
  66
+		#endregion
  67
+	}
  68
+}
  69
+
  70
+#region [ License information          ]
  71
+/* ************************************************************
  72
+ * 
  73
+ *    Copyright (c) 2010 Attila Kiskó, enyim.com
  74
+ *    
  75
+ *    Licensed under the Apache License, Version 2.0 (the "License");
  76
+ *    you may not use this file except in compliance with the License.
  77
+ *    You may obtain a copy of the License at
  78
+ *    
  79
+ *        http://www.apache.org/licenses/LICENSE-2.0
  80
+ *    
  81
+ *    Unless required by applicable law or agreed to in writing, software
  82
+ *    distributed under the License is distributed on an "AS IS" BASIS,
  83
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  84
+ *    See the License for the specific language governing permissions and
  85
+ *    limitations under the License.
  86
+ *    
  87
+ * ************************************************************/
  88
+#endregion
65  Membase/Operations/TouchOperation.cs
... ...
@@ -0,0 +1,65 @@
  1
+using System;
  2
+using System.Collections.Generic;
  3
+using System.Linq;
  4
+using System.Text;
  5
+using Enyim.Caching.Memcached.Protocol.Binary;
  6
+using Enyim.Caching.Memcached;
  7
+
  8
+namespace Membase
  9
+{
  10
+	internal class TouchOperation : BinarySingleItemOperation, IOperationWithState, ITouchOperation
  11
+	{
  12
+		private static readonly Enyim.Caching.ILog log = Enyim.Caching.LogManager.GetLogger(typeof(TouchOperation));
  13
+
  14
+		private uint expires;
  15
+		private OperationState state;
  16
+		private VBucketNodeLocator locator;
  17
+
  18
+		public TouchOperation(VBucketNodeLocator locator, string key, uint expires)
  19
+			: base(key)
  20
+		{
  21
+			this.locator = locator;
  22
+			this.expires = expires;
  23
+		}
  24
+
  25
+		protected override BinaryRequest Build()
  26
+		{
  27
+			var retval = new BinaryRequest(0x1c);
  28
+
  29
+			retval.Key = this.Key;
  30
+
  31
+			if (this.locator != null)
  32
+			{
  33
+				retval.Reserved = (ushort)locator.GetIndex(this.Key);
  34
+				if (log.IsDebugEnabled) log.DebugFormat("Key {0} was mapped to {1}", this.Key, retval.Reserved);
  35
+			}
  36
+
  37
+			var extra = new byte[4];
  38
+
  39
+			BinaryConverter.EncodeUInt32(this.expires, extra, 0);
  40
+			retval.Extra = new ArraySegment<byte>(extra);
  41
+
  42
+			return retval;
  43
+		}
  44
+
  45
+		protected override bool ProcessResponse(BinaryResponse response)
  46
+		{
  47
+			var r = response.StatusCode == 0;
  48
+
  49
+			if (this.locator != null &&
  50
+				!VBucketAwareOperationFactory.GuessResponseState(response, out this.state))
  51
+				return false;
  52
+
  53
+			return r;
  54
+		}
  55
+
  56
+		#region [ IOperationWithState          ]
  57
+
  58
+		OperationState IOperationWithState.State
  59
+		{
  60
+			get { return this.state; }
  61
+		}
  62
+
  63
+		#endregion
  64
+	}
  65
+}
90  Membase/VBucketAwareOperationFactory.cs
@@ -6,13 +6,14 @@
6 6
 using Enyim.Caching.Memcached;
7 7
 using System.IO;
8 8
 using System.Threading;
  9
+using Enyim.Caching;
9 10
 
10 11
 namespace Membase
11 12
 {
12 13
 	/// <summary>
13 14
 	/// Membase requires each item operation to have a vbucket index set in the request's "reserved" field. (This is used for replicatiom and failover.) This op factory provides customized operations handling these indexes.
14 15
 	/// </summary>
15  
-	internal class VBucketAwareOperationFactory : IOperationFactory
  16
+	internal class VBucketAwareOperationFactory : IMembaseOperationFactory
16 17
 	{
17 18
 		private VBucketNodeLocator locator;
18 19
 
@@ -21,6 +22,21 @@ public VBucketAwareOperationFactory(VBucketNodeLocator locator)
21 22
 			this.locator = locator;
22 23
 		}
23 24
 
  25
+		internal static bool GuessResponseState(BinaryResponse response, out OperationState state)
  26
+		{
  27
+			switch (response.StatusCode)
  28
+			{
  29
+				case 0: state = OperationState.Success;
  30
+					return true;
  31
+				case 7: state = OperationState.InvalidVBucket;
  32
+					break;
  33
+				default: state = OperationState.Failure;
  34
+					break;
  35
+			}
  36
+
  37
+			return false;
  38
+		}
  39
+
24 40
 		IGetOperation IOperationFactory.Get(string key)
25 41
 		{
26 42
 			return new VBGet(locator, key);
@@ -61,9 +77,17 @@ IFlushOperation IOperationFactory.Flush()
61 77
 			return new FlushOperation();
62 78
 		}
63 79
 
64  
-		#region [ Custom operations            ]
  80
+		ITouchOperation IMembaseOperationFactory.Touch(string key, uint newExpiration)
  81
+		{
  82
+			return new TouchOperation(this.locator, key, newExpiration);
  83
+		}
65 84
 
66  
-		private const string NotMyVBucket = "I'm not responsible for this vbucket";
  85
+		IGetAndTouchOperation IMembaseOperationFactory.GetAndTouch(string key, uint newExpiration)
  86
+		{
  87
+			return new GetAndTouchOperation(this.locator, key, newExpiration);
  88
+		}
  89
+
  90
+		#region [ Custom operations            ]
67 91
 
68 92
 		private class VBStore : StoreOperation, IOperationWithState
69 93
 		{
@@ -91,16 +115,10 @@ protected override bool ProcessResponse(BinaryResponse response)
91 115
 			{
92 116
 				base.ProcessResponse(response);
93 117
 
94  
-				var r = response.StatusCode == 0;
95  
-				this.state = r ? OperationState.Success : OperationState.Failure;
96  
-
97  
-				if (!r)
98  
-				{
99  
-					if (response.GetStatusMessage() == NotMyVBucket)
100  
-						this.state = OperationState.InvalidVBucket;
101  
-				}
  118
+				if (!GuessResponseState(response, out this.state))
  119
+					return false;
102 120
 
103  
-				return r;
  121
+				return true;
104 122
 			}
105 123
 
106 124
 			#region [ IOperationWithState          ]
@@ -139,16 +157,10 @@ protected override bool ProcessResponse(BinaryResponse response)
139 157
 			{
140 158
 				base.ProcessResponse(response);
141 159
 
142  
-				var r = response.StatusCode == 0;
143  
-				this.state = r ? OperationState.Success : OperationState.Failure;
  160
+				if (!GuessResponseState(response, out this.state))
  161
+					return false;
144 162
 
145  
-				if (!r)
146  
-				{
147  
-					if (response.GetStatusMessage() == NotMyVBucket)
148  
-						this.state = OperationState.InvalidVBucket;
149  
-				}
150  
-
151  
-				return r;
  163
+				return true;
152 164
 			}
153 165
 
154 166
 			#region [ IOperationWithState          ]
@@ -187,16 +199,10 @@ protected override bool ProcessResponse(BinaryResponse response)
187 199
 			{
188 200
 				base.ProcessResponse(response);
189 201
 
190  
-				var r = response.StatusCode == 0;
191  
-				this.state = r ? OperationState.Success : OperationState.Failure;
192  
-
193  
-				if (!r)
194  
-				{
195  
-					if (response.GetStatusMessage() == NotMyVBucket)
196  
-						this.state = OperationState.InvalidVBucket;
197  
-				}
  202
+				if (!GuessResponseState(response, out this.state))
  203
+					return false;
198 204
 
199  
-				return r;
  205
+				return true;
200 206
 			}
201 207
 
202 208
 			#region [ IOperationWithState          ]
@@ -257,16 +263,10 @@ protected override bool ProcessResponse(BinaryResponse response)
257 263
 			{
258 264
 				base.ProcessResponse(response);
259 265
 
260  
-				var r = response.StatusCode == 0;
261  
-				this.state = r ? OperationState.Success : OperationState.Failure;
  266
+				if (!GuessResponseState(response, out this.state))
  267
+					return false;
262 268
 
263  
-				if (!r)
264  
-				{
265  
-					if (response.GetStatusMessage() == NotMyVBucket)
266  
-						this.state = OperationState.InvalidVBucket;
267  
-				}
268  
-
269  
-				return r;
  269
+				return true;
270 270
 			}
271 271
 
272 272
 			#region [ IOperationWithState          ]
@@ -306,16 +306,10 @@ protected override bool ProcessResponse(BinaryResponse response)
306 306
 			{
307 307
 				base.ProcessResponse(response);
308 308
 
309  
-				var r = response.StatusCode == 0;
310  
-				this.state = r ? OperationState.Success : OperationState.Failure;
311  
-
312  
-				if (!r)
313  
-				{
314  
-					if (response.GetStatusMessage() == NotMyVBucket)
315  
-						this.state = OperationState.InvalidVBucket;
316  
-				}
  309
+				if (!GuessResponseState(response, out this.state))
  310
+					return false;
317 311
 
318  
-				return r;
  312
+				return true;
319 313
 			}
320 314
 
321 315
 			#region [ IOperationWithState          ]
21  TestApp/Program.cs
@@ -29,18 +29,29 @@ static void Main(string[] args)
29 29
 			//nscc.Bucket = "content";
30 30
 			//nscc.BucketPassword = "content";
31 31
 
32  
-			new MembaseClient(nscc).Store(StoreMode.Set, "4q", 1);
  32
+			var client = new MembaseClient(nscc);
  33
+			Console.WriteLine("Store = " + client.Store(StoreMode.Set, "4q", 1, new TimeSpan(0, 0, 4)));
33 34
 
34  
-			new MembaseClient(nscc, "data", "data").Store(StoreMode.Set, "q4", 2);
35  
-			new MembaseClient(nscc, "feedback", null).Store(StoreMode.Set, "q4", 2);
  35
+			Console.WriteLine("Setting expiration to the far future.");
  36
+			//Console.ReadLine();
  37
+
  38
+			client.Touch("4q", DateTime.Now.AddDays(1));
  39
+
  40
+			Console.WriteLine("Wait for 4 sec.");
  41
+			Console.ReadLine();
  42
+
  43
+			Console.WriteLine(client.Get("4q") ?? "<null>");
  44
+
  45
+			//new MembaseClient(nscc, "data", "data").Store(StoreMode.Set, "q4", 2);
  46
+			//new MembaseClient(nscc, "feedback", null).Store(StoreMode.Set, "q4", 2);
36 47
 
37 48
 			Console.ReadLine();
38 49
 
39 50
 			//nscc.PerformanceMonitorFactory = new Membase.Configuration.DefaultPerformanceMonitorFactory();
40 51
 			//nscc.BucketPassword = "pass";
41 52
 
42  
-			ThreadPool.QueueUserWorkItem(o => StressTest(new MembaseClient(nscc), "TesT_A_"));
43  
-			ThreadPool.QueueUserWorkItem(o => StressTest(new MembaseClient("content", "content"), "TesT_B_"));
  53
+			//ThreadPool.QueueUserWorkItem(o => StressTest(new MembaseClient(nscc), "TesT_A_"));
  54
+			//ThreadPool.QueueUserWorkItem(o => StressTest(new MembaseClient("content", "content"), "TesT_B_"));
44 55
 
45 56
 			//ThreadPool.QueueUserWorkItem(o => StressTest(new MembaseClient(nscc, "default"), "TesT_B_"));
46 57
 			//ThreadPool.QueueUserWorkItem(o => StressTest(new MembaseClient(nscc, "default"), "TesT_C_"));

3 notes on commit 9c574e6

Andrew Lane

Looking forward to trying this out...

Attila Kiskó
Owner
enyim commented on 9c574e6 June 08, 2011

You already can: http://www.couchbase.org/products/membase/1-7-series (it's a beta tho)

Attila Kiskó
Owner
enyim commented on 9c574e6 June 08, 2011

Actually it seems to be the final version.

Please sign in to comment.
Something went wrong with that request. Please try again.