diff --git a/Enyim.Caching/IMemcachedResultsClient.cs b/Enyim.Caching/IMemcachedResultsClient.cs
index 32cec69f..cc85b327 100644
--- a/Enyim.Caching/IMemcachedResultsClient.cs
+++ b/Enyim.Caching/IMemcachedResultsClient.cs
@@ -2,55 +2,57 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
+using System.Threading.Tasks;
using Enyim.Caching.Memcached;
using Enyim.Caching.Memcached.Results;
namespace Enyim.Caching
{
- ///
- /// Interface for API methods that return detailed operation results
- ///
- public interface IMemcachedResultsClient
- {
- IGetOperationResult ExecuteGet(string key);
- IGetOperationResult ExecuteGet(string key);
- IDictionary ExecuteGet(IEnumerable keys);
+ ///
+ /// Interface for API methods that return detailed operation results
+ ///
+ public interface IMemcachedResultsClient
+ {
+ IGetOperationResult ExecuteGet(string key);
+ IGetOperationResult ExecuteGet(string key);
+ IDictionary ExecuteGet(IEnumerable keys);
- IGetOperationResult ExecuteTryGet(string key, out object value);
-
- IStoreOperationResult ExecuteStore(StoreMode mode, string key, object value);
- IStoreOperationResult ExecuteStore(StoreMode mode, string key, object value, DateTime expiresAt);
- IStoreOperationResult ExecuteStore(StoreMode mode, string key, object value, TimeSpan validFor);
+ IGetOperationResult ExecuteTryGet(string key, out object value);
- IStoreOperationResult ExecuteCas(StoreMode mode, string key, object value);
- IStoreOperationResult ExecuteCas(StoreMode mode, string key, object value, ulong cas);
- IStoreOperationResult ExecuteCas(StoreMode mode, string key, object value, DateTime expiresAt, ulong cas);
- IStoreOperationResult ExecuteCas(StoreMode mode, string key, object value, TimeSpan validFor, ulong cas);
+ IStoreOperationResult ExecuteStore(StoreMode mode, string key, object value);
+ IStoreOperationResult ExecuteStore(StoreMode mode, string key, object value, DateTime expiresAt);
+ IStoreOperationResult ExecuteStore(StoreMode mode, string key, object value, TimeSpan validFor);
- IMutateOperationResult ExecuteDecrement(string key, ulong defaultValue, ulong delta);
- IMutateOperationResult ExecuteDecrement(string key, ulong defaultValue, ulong delta, DateTime expiresAt);
- IMutateOperationResult ExecuteDecrement(string key, ulong defaultValue, ulong delta, TimeSpan validFor);
+ IStoreOperationResult ExecuteCas(StoreMode mode, string key, object value);
+ IStoreOperationResult ExecuteCas(StoreMode mode, string key, object value, ulong cas);
+ IStoreOperationResult ExecuteCas(StoreMode mode, string key, object value, DateTime expiresAt, ulong cas);
+ IStoreOperationResult ExecuteCas(StoreMode mode, string key, object value, TimeSpan validFor, ulong cas);
- IMutateOperationResult ExecuteDecrement(string key, ulong defaultValue, ulong delta, ulong cas);
- IMutateOperationResult ExecuteDecrement(string key, ulong defaultValue, ulong delta, DateTime expiresAt, ulong cas);
- IMutateOperationResult ExecuteDecrement(string key, ulong defaultValue, ulong delta, TimeSpan validFor, ulong cas);
-
- IMutateOperationResult ExecuteIncrement(string key, ulong defaultValue, ulong delta);
- IMutateOperationResult ExecuteIncrement(string key, ulong defaultValue, ulong delta, DateTime expiresAt);
- IMutateOperationResult ExecuteIncrement(string key, ulong defaultValue, ulong delta, TimeSpan validFor);
+ IMutateOperationResult ExecuteDecrement(string key, ulong defaultValue, ulong delta);
+ IMutateOperationResult ExecuteDecrement(string key, ulong defaultValue, ulong delta, DateTime expiresAt);
+ IMutateOperationResult ExecuteDecrement(string key, ulong defaultValue, ulong delta, TimeSpan validFor);
- IMutateOperationResult ExecuteIncrement(string key, ulong defaultValue, ulong delta, ulong cas);
- IMutateOperationResult ExecuteIncrement(string key, ulong defaultValue, ulong delta, DateTime expiresAt, ulong cas);
- IMutateOperationResult ExecuteIncrement(string key, ulong defaultValue, ulong delta, TimeSpan validFor, ulong cas);
+ IMutateOperationResult ExecuteDecrement(string key, ulong defaultValue, ulong delta, ulong cas);
+ IMutateOperationResult ExecuteDecrement(string key, ulong defaultValue, ulong delta, DateTime expiresAt, ulong cas);
+ IMutateOperationResult ExecuteDecrement(string key, ulong defaultValue, ulong delta, TimeSpan validFor, ulong cas);
- IConcatOperationResult ExecuteAppend(string key, ArraySegment data);
- IConcatOperationResult ExecuteAppend(string key, ulong cas, ArraySegment data);
-
- IConcatOperationResult ExecutePrepend(string key, ArraySegment data);
- IConcatOperationResult ExecutePrepend(string key, ulong cas, ArraySegment data);
+ IMutateOperationResult ExecuteIncrement(string key, ulong defaultValue, ulong delta);
+ IMutateOperationResult ExecuteIncrement(string key, ulong defaultValue, ulong delta, DateTime expiresAt);
+ IMutateOperationResult ExecuteIncrement(string key, ulong defaultValue, ulong delta, TimeSpan validFor);
- IRemoveOperationResult ExecuteRemove(string key);
- }
+ IMutateOperationResult ExecuteIncrement(string key, ulong defaultValue, ulong delta, ulong cas);
+ IMutateOperationResult ExecuteIncrement(string key, ulong defaultValue, ulong delta, DateTime expiresAt, ulong cas);
+ IMutateOperationResult ExecuteIncrement(string key, ulong defaultValue, ulong delta, TimeSpan validFor, ulong cas);
+
+ IConcatOperationResult ExecuteAppend(string key, ArraySegment data);
+ IConcatOperationResult ExecuteAppend(string key, ulong cas, ArraySegment data);
+
+ IConcatOperationResult ExecutePrepend(string key, ArraySegment data);
+ IConcatOperationResult ExecutePrepend(string key, ulong cas, ArraySegment data);
+
+ IRemoveOperationResult ExecuteRemove(string key);
+ Task ExecuteRemoveAsync(string key);
+ }
}
#region [ License information ]
diff --git a/Enyim.Caching/Memcached/Protocol/Text/TextSocketHelper.cs b/Enyim.Caching/Memcached/Protocol/Text/TextSocketHelper.cs
index 5da403e6..421c5028 100644
--- a/Enyim.Caching/Memcached/Protocol/Text/TextSocketHelper.cs
+++ b/Enyim.Caching/Memcached/Protocol/Text/TextSocketHelper.cs
@@ -1,126 +1,130 @@
-using System;
+using System;
using System.IO;
using System.Text;
using System.Collections.Generic;
namespace Enyim.Caching.Memcached.Protocol.Text
{
- internal static class TextSocketHelper
- {
- private const string GenericErrorResponse = "ERROR";
- private const string ClientErrorResponse = "CLIENT_ERROR ";
- private const string ServerErrorResponse = "SERVER_ERROR ";
- private const int ErrorResponseLength = 13;
-
- public const string CommandTerminator = "\r\n";
-
- private static readonly Enyim.Caching.ILog log = Enyim.Caching.LogManager.GetLogger(typeof(TextSocketHelper));
-
- ///
- /// Reads the response of the server.
- ///
- /// The data sent by the memcached server.
- /// The server did not sent a response or an empty line was returned.
- /// The server did not specified any reason just returned the string ERROR. - or - The server returned a SERVER_ERROR, in this case the Message of the exception is the message returned by the server.
- /// The server did not recognize the request sent by the client. The Message of the exception is the message returned by the server.
- public static string ReadResponse(PooledSocket socket)
- {
- string response = TextSocketHelper.ReadLine(socket);
-
- if (log.IsDebugEnabled)
- log.Debug("Received response: " + response);
-
- if (String.IsNullOrEmpty(response))
- throw new MemcachedClientException("Empty response received.");
-
- if (String.Compare(response, GenericErrorResponse, StringComparison.Ordinal) == 0)
- throw new NotSupportedException("Operation is not supported by the server or the request was malformed. If the latter please report the bug to the developers.");
-
- if (response.Length >= ErrorResponseLength)
- {
- if (String.Compare(response, 0, ClientErrorResponse, 0, ErrorResponseLength, StringComparison.Ordinal) == 0)
- {
- throw new MemcachedClientException(response.Remove(0, ErrorResponseLength));
- }
- else if (String.Compare(response, 0, ServerErrorResponse, 0, ErrorResponseLength, StringComparison.Ordinal) == 0)
- {
- throw new MemcachedException(response.Remove(0, ErrorResponseLength));
- }
- }
-
- return response;
- }
-
-
- ///
- /// Reads a line from the socket. A line is terninated by \r\n.
- ///
- ///
- private static string ReadLine(PooledSocket socket)
- {
- MemoryStream ms = new MemoryStream(50);
-
- bool gotR = false;
- //byte[] buffer = new byte[1];
-
- int data;
-
- while (true)
- {
- data = socket.ReadByte();
-
- if (data == 13)
- {
- gotR = true;
- continue;
- }
-
- if (gotR)
- {
- if (data == 10)
- break;
-
- ms.WriteByte(13);
-
- gotR = false;
- }
-
- ms.WriteByte((byte)data);
- }
-
- string retval = Encoding.ASCII.GetString(ms.ToArray(), 0, (int)ms.Length);
-
- if (log.IsDebugEnabled)
- log.Debug("ReadLine: " + retval);
-
- return retval;
- }
-
- ///
- /// Gets the bytes representing the specified command. returned buffer can be used to streamline multiple writes into one Write on the Socket
- /// using the
- ///
- /// The command to be converted.
- /// The buffer containing the bytes representing the command. The command must be terminated by \r\n.
- /// The Nagle algorithm is disabled on the socket to speed things up, so it's recommended to convert a command into a buffer
- /// and use the to send the command and the additional buffers in one transaction.
- public unsafe static IList> GetCommandBuffer(string value)
- {
- var data = new ArraySegment(Encoding.ASCII.GetBytes(value));
-
- return new ArraySegment[] { data };
- }
-
- public unsafe static IList> GetCommandBuffer(string value, IList> list)
- {
- var data = new ArraySegment(Encoding.ASCII.GetBytes(value));
-
- list.Add(data);
-
- return list;
- }
-
- }
+ internal static class TextSocketHelper
+ {
+ private const string GenericErrorResponse = "ERROR";
+ private const string ClientErrorResponse = "CLIENT_ERROR ";
+ private const string ServerErrorResponse = "SERVER_ERROR ";
+ private const int ErrorResponseLength = 13;
+
+ public const string CommandTerminator = "\r\n";
+
+ private static readonly Enyim.Caching.ILog log = Enyim.Caching.LogManager.GetLogger(typeof(TextSocketHelper));
+
+ ///
+ /// Reads the response of the server.
+ ///
+ /// The data sent by the memcached server.
+ /// The server did not sent a response or an empty line was returned.
+ /// The server did not specified any reason just returned the string ERROR. - or - The server returned a SERVER_ERROR, in this case the Message of the exception is the message returned by the server.
+ /// The server did not recognize the request sent by the client. The Message of the exception is the message returned by the server.
+ public static string ReadResponse(PooledSocket socket)
+ {
+ string response = TextSocketHelper.ReadLine(socket);
+
+ if (log.IsDebugEnabled)
+ log.Debug("Received response: " + response);
+
+ if (String.IsNullOrEmpty(response))
+ throw new MemcachedClientException("Empty response received.");
+
+ if (String.Compare(response, GenericErrorResponse, StringComparison.Ordinal) == 0)
+ throw new NotSupportedException("Operation is not supported by the server or the request was malformed. If the latter please report the bug to the developers.");
+
+ if (response.Length >= ErrorResponseLength)
+ {
+ if (String.Compare(response, 0, ClientErrorResponse, 0, ErrorResponseLength, StringComparison.Ordinal) == 0)
+ {
+ throw new MemcachedClientException(response.Remove(0, ErrorResponseLength));
+ }
+ else if (String.Compare(response, 0, ServerErrorResponse, 0, ErrorResponseLength, StringComparison.Ordinal) == 0)
+ {
+ throw new MemcachedException(response.Remove(0, ErrorResponseLength));
+ }
+ }
+
+ return response;
+ }
+
+ ///
+ /// Reads a line from the socket. A line is terninated by \r\n.
+ ///
+ ///
+ private static string ReadLine(PooledSocket socket)
+ {
+ var ms = new MemoryStream(50);
+
+ bool gotR = false;
+ //byte[] buffer = new byte[1];
+
+ int data;
+
+ while (true)
+ {
+ data = socket.ReadByte();
+
+ if (data == -1)
+ {
+ return string.Empty;
+ }
+
+ if (data == 13)
+ {
+ gotR = true;
+ continue;
+ }
+
+ if (gotR)
+ {
+ if (data == 10)
+ break;
+
+ ms.WriteByte(13);
+
+ gotR = false;
+ }
+
+ ms.WriteByte((byte)data);
+ }
+
+ string retval = Encoding.ASCII.GetString(ms.ToArray(), 0, (int)ms.Length);
+
+ if (log.IsDebugEnabled)
+ log.Debug("ReadLine: " + retval);
+
+ return retval;
+ }
+
+ ///
+ /// Gets the bytes representing the specified command. returned buffer can be used to streamline multiple writes into one Write on the Socket
+ /// using the
+ ///
+ /// The command to be converted.
+ /// The buffer containing the bytes representing the command. The command must be terminated by \r\n.
+ /// The Nagle algorithm is disabled on the socket to speed things up, so it's recommended to convert a command into a buffer
+ /// and use the to send the command and the additional buffers in one transaction.
+ public unsafe static IList> GetCommandBuffer(string value)
+ {
+ var data = new ArraySegment(Encoding.ASCII.GetBytes(value));
+
+ return new ArraySegment[] { data };
+ }
+
+ public unsafe static IList> GetCommandBuffer(string value, IList> list)
+ {
+ var data = new ArraySegment(Encoding.ASCII.GetBytes(value));
+
+ list.Add(data);
+
+ return list;
+ }
+
+ }
}
#region [ License information ]