protected override void ProcessInternal(RedisSocketContext context, int timeoutMilliseconds = -1) { try { if (context == null || !context.Socket.IsConnected()) { Interlocked.Exchange(ref m_State, (long)RequestState.Canceled); } else { var command = Command; if (!command.IsAlive()) { Interlocked.Exchange(ref m_State, (long)RequestState.Canceled); return; } var queueResult = command.ExpectSimpleString(context, RedisConstants.QUEUED); if (!queueResult) { throw new RedisException("An error occured in transaction queue", RedisErrorCode.CorruptResponse); } } } catch (Exception e) { SetException(e); } }
public override bool Send(RedisSocketContext context, int timeoutMilliseconds = -1) { var tcs = CompletionSource; if (tcs != null && IsValidTask(tcs.Task)) { try { if (IsExpired(timeoutMilliseconds)) { tcs.TrySetException(new RedisException("Request Timeout", RedisErrorCode.SocketError)); return(false); } var command = Command; if (command == null || context == null || !context.Socket.IsConnected()) { tcs.TrySetCanceled(); } else { command.WriteTo(context.Socket); return(true); } } catch (Exception e) { tcs.TrySetException(e); } } return(false); }
public RedisMultiBytes ExpectMultiDataBytes(RedisSocketContext context, bool throwException = true) { using (var response = ExecuteInternal(context, throwException)) { return(ForMultiDataBytes(response, throwException)); } }
public RedisNullableDouble ExpectNullableDouble(RedisSocketContext context, bool throwException = true) { using (var response = ExecuteInternal(context, throwException)) { return(ForNullableDouble(response, throwException)); } }
protected virtual void Discard(IList <RedisRequest> requests, RedisSocketContext context, Exception exception = null) { if (requests != null) { var requestCount = requests.Count; for (var i = 0; i < requestCount; i++) { try { var request = requests[i]; if (request != null) { if (exception == null) { request.Cancel(); } else { request.SetException(exception); } } } catch (Exception) { } } } }
protected override void OnFlush(IList <RedisRequest> requests, RedisSocketContext context, out bool success) { success = Send(requests, context); if (success && context.Socket.IsConnected()) { success = Receive(requests, context); } }
public override void Process(RedisSocketContext context, int timeoutMilliseconds = -1) { ValidateNotDisposed(); if (Interlocked.CompareExchange(ref m_State, (long)RequestState.Initiated, (long)RequestState.Waiting) == (long)RequestState.Waiting) { ProcessInternal(context, timeoutMilliseconds); } }
public RedisInteger ExpectInteger(RedisSocketContext context, bool throwException = true) { var result = ExpectNullableInteger(context, throwException); if (result == null) { return(long.MinValue); } return(result.Value); }
public RedisString ExpectBulkString(RedisSocketContext context, bool throwException = true) { var bytes = ExpectBulkStringBytes(context, throwException); if (ReferenceEquals(bytes, null)) { return(null); } return(((byte[])bytes.RawData).ToUTF8String()); }
private string ExpectSimpleStringInternal(RedisSocketContext context, bool throwException = true) { var bytes = ExpectSimpleStringBytes(context, throwException); if (ReferenceEquals(bytes, null)) { return(null); } return(((byte[])bytes.RawData).ToUTF8String()); }
public RedisBool ExpectOK(RedisSocketContext context, bool throwException = true) { var result = ExpectSimpleStringInternal(context, throwException); if (!result.IsEmpty()) { return(result.Equals(RedisConstants.OK, StringComparison.OrdinalIgnoreCase)); } return(false); }
public RedisBool ExpectOne(RedisSocketContext context, bool throwException = true) { var result = ExpectNullableInteger(context, throwException); if (result != null) { var value = result.Value; return(value.HasValue && value.Value == RedisConstants.One); } return(false); }
private bool Receive(IList <RedisRequest> requests, RedisSocketContext context) { if (requests != null) { var requestCount = requests.Count; if (requestCount > 0) { var socket = context.Socket; if (socket.IsConnected()) { using (var reader = new RedisSingleResponseReader(context.Settings)) { for (var i = 0; i < requestCount; i++) { try { var request = requests[i]; if (ReferenceEquals(request, null)) { continue; } var execResult = reader.Execute(socket); if (ReferenceEquals(execResult, null)) { throw new RedisFatalException("Corrupted redis response data", RedisErrorCode.CorruptResponse); } execResult.HandleError(); var rawObj = RedisRawObject.ToObject(execResult); if (ReferenceEquals(rawObj, null)) { throw new RedisFatalException("Corrupted redis response data", RedisErrorCode.CorruptResponse); } request.ProcessResult(rawObj); } catch (Exception e) { SetException(requests, e, i); throw; } } } return(true); } } } return(false); }
private bool Send(IList <RedisRequest> requests, RedisSocketContext context) { if (requests != null) { var requestCount = requests.Count; if (requests.Count > 0) { var socket = context.Socket; if (socket.IsConnected()) { try { var anySend = false; var stream = socket.GetBufferedStream(); for (var i = 0; i < requestCount; i++) { try { var request = requests[i]; request.Command.WriteTo(stream, false); anySend = true; } catch (Exception) { Cancel(requests, i); break; } } if (anySend) { stream.Flush(); } return(anySend); } catch (Exception e) { if (e.IsSocketError()) { socket.DisposeSocket(); } throw; } } } } return(false); }
protected override void Discard(IList <RedisRequest> requests, RedisSocketContext context, Exception exception = null) { try { base.Discard(requests, context, exception); } finally { if (context.Socket.IsConnected()) { (new RedisCommand(DbIndex, RedisCommandList.Discard)).ExpectOK(context); } } }
private bool Exec(IList <RedisRequest> requests, RedisSocketContext context) { if (requests != null) { var exec = new RedisCommand(DbIndex, RedisCommandList.Exec); var execResult = exec.ExpectArray(context); if (!ReferenceEquals(execResult, null)) { return(ProcessResult(requests, execResult.Value)); } } return(false); }
public RedisRaw ExpectArray(RedisSocketContext context, bool throwException = true) { using (var response = ExecuteInternal(context, throwException)) { if (response == null) { if (throwException) { throw new RedisException("No data returned", RedisErrorCode.CorruptResponse); } return(null); } return(new RedisRaw(RedisRawObject.ToObject(response))); } }
private RedisRawResponse ExecuteInternal(RedisSocketContext context, bool throwException = true, bool sendNotReceive = false) { if (context == null) { if (throwException) { throw new RedisFatalException(new ArgumentNullException("context"), RedisErrorCode.MissingParameter); } return(null); } var socket = context.Socket; if (socket == null) { if (throwException) { throw new RedisFatalException(new ArgumentNullException("context.Socket"), RedisErrorCode.MissingParameter); } return(null); } RedisRawResponse response = RedisVoidResponse.Void; if (sendNotReceive || !m_CommandType.HasFlag(RedisCommandType.SendAndReceive)) { WriteTo(socket); } else { WriteTo(socket); using (var reader = new RedisSingleResponseReader(context.Settings)) response = reader.Execute(socket); if (ReferenceEquals(response, null) && throwException) { throw new RedisException("Corrupted redis response data", RedisErrorCode.CorruptResponse); } response.HandleError(); } return(response); }
public RedisBool ExpectSimpleString(RedisSocketContext context, string expectedResult, bool throwException = true) { var result = ExpectSimpleStringInternal(context, throwException); if (!result.IsEmpty()) { if (!expectedResult.IsEmpty()) { return(result.Equals(expectedResult, StringComparison.OrdinalIgnoreCase)); } if (result.StartsWith("-", StringComparison.Ordinal)) { return(false); } return(true); } return(false); }
public RedisBool ExpectSimpleStringBytes(RedisSocketContext context, byte[] expectedResult, bool throwException = true) { var result = ExpectSimpleStringBytesInternal(context, throwException); if (result == null) { return(expectedResult == null); } if (expectedResult != null) { return(result == expectedResult); } if (result.Length > 0 && result[0] == (byte)'-') { return(false); } return(false); }
protected override void DoProcessRequest(RedisAsyncRequest request, RedisSocketContext context) { var cancelRequest = true; try { if (Disposed) { return; } if (request.Send(context)) { if (Disposed) { return; } Interlocked.Exchange(ref m_CurrentContext, context); var receiveQ = m_ReceiveQ; if (receiveQ != null) { receiveQ.Enqueue(request); cancelRequest = false; m_ReceiveGate.Set(); } } } catch (Exception) { } finally { if (cancelRequest) { request.Cancel(); } } }
private bool Process(IList <RedisRequest> requests, RedisSocketContext context) { if (requests != null) { var requestCount = requests.Count; if (requestCount > 0) { var socket = context.Socket; var settings = context.Settings; for (var i = 0; i < requestCount; i++) { try { var request = requests[i]; request.Process(context); if (!request.IsStarted) { Discard(requests, context); return(false); } } catch (SocketException e) { Discard(requests, context, e); throw new RedisFatalException(e, RedisErrorCode.SocketError); } catch (Exception e) { Discard(requests, context, e); throw; } } return(true); } } return(false); }
public RedisBytes ExpectBulkStringBytes(RedisSocketContext context, bool throwException = true) { using (var response = ExecuteInternal(context, throwException)) { if (response == null) { if (throwException) { throw new RedisException("No data returned", RedisErrorCode.CorruptResponse); } return(null); } if (response.Type != RedisRawObjectType.BulkString) { if (throwException) { throw new RedisException("Invalid data returned", RedisErrorCode.CorruptResponse); } return(null); } return(response.ReleaseData()); } }
protected override void OnFlush(IList <RedisRequest> requests, RedisSocketContext context, out bool success) { var queue = Interlocked.Exchange(ref m_WatchQ, null); if (queue != null && queue.Count > 0) { var watchCommand = new RedisCommand(DbIndex, RedisCommandList.Watch, RedisCommandType.SendAndReceive, queue.ToArray().ToBytesArray()); var watchResult = watchCommand.ExpectOK(context); if (!watchResult) { success = false; return; } } var multiCommand = new RedisCommand(DbIndex, RedisCommandList.Multi); var multiResult = multiCommand.ExpectOK(context); success = multiResult; if (!success) { Cancel(requests); return; } success = Process(requests, context); if (!success) { Discard(requests, context); return; } success = Exec(requests, context); }
protected override void ProcessInternal(RedisSocketContext context, int timeoutMilliseconds = -1) { try { if (context == null || !context.Socket.IsConnected()) { Interlocked.Exchange(ref m_State, (long)RequestState.Canceled); } else { var command = Command; if (!command.IsAlive()) { Interlocked.Exchange(ref m_State, (long)RequestState.Canceled); return; } if (IsTransactional) { var queueResult = command.ExpectSimpleString(context, RedisConstants.QUEUED); if (!queueResult) { throw new RedisException("An error occured in transaction queue", RedisErrorCode.CorruptResponse); } return; } var result = CreateResult(); switch (Expectation) { case RedisCommandExpect.Response: { var expectation = command.Execute(context); (result as RedisResponse).TrySetResult(expectation); } break; case RedisCommandExpect.Array: { var expectation = command.ExpectArray(context); (result as RedisRaw).TrySetResult(expectation.Value); } break; case RedisCommandExpect.BulkString: { var expectation = command.ExpectBulkString(context); (result as RedisString).TrySetResult(expectation.Value); } break; case RedisCommandExpect.BulkStringBytes: { var expectation = command.ExpectBulkStringBytes(context); (result as RedisBytes).TrySetResult(expectation.Value); } break; case RedisCommandExpect.Double: { var expectation = command.ExpectDouble(context); (result as RedisDouble).TrySetResult(expectation.Value); } break; case RedisCommandExpect.GreaterThanZero: { var expectation = command.ExpectInteger(context); (result as RedisBool).TrySetResult(expectation.Value > RedisConstants.Zero); } break; case RedisCommandExpect.Integer: { var expectation = command.ExpectInteger(context); (result as RedisInteger).TrySetResult(expectation.Value); } break; case RedisCommandExpect.MultiDataBytes: { var expectation = command.ExpectMultiDataBytes(context); (result as RedisMultiBytes).TrySetResult(expectation.Value); } break; case RedisCommandExpect.MultiDataStrings: { var expectation = command.ExpectMultiDataStrings(context); (result as RedisMultiString).TrySetResult(expectation.Value); } break; case RedisCommandExpect.Nothing: { var expectation = command.ExpectNothing(context); (result as RedisVoid).TrySetResult(expectation.Value); } break; case RedisCommandExpect.NullableDouble: { var expectation = command.ExpectNullableDouble(context); (result as RedisNullableDouble).TrySetResult(expectation.Value); } break; case RedisCommandExpect.NullableInteger: { var expectation = command.ExpectNullableInteger(context); (result as RedisNullableInteger).TrySetResult(expectation.Value); } break; case RedisCommandExpect.OK: { var expectation = command.ExpectSimpleString(context, RedisConstants.OK); (result as RedisBool).TrySetResult(expectation.Value); } break; case RedisCommandExpect.One: { var expectation = command.ExpectInteger(context); (result as RedisBool).TrySetResult(expectation.Value == RedisConstants.One); } break; case RedisCommandExpect.SimpleString: { var expectation = command.ExpectSimpleString(context); (result as RedisString).TrySetResult(expectation.Value); } break; case RedisCommandExpect.SimpleStringBytes: { var expectation = command.ExpectSimpleStringBytes(context); (result as RedisBytes).TrySetResult(expectation.Value); } break; default: break; } Interlocked.CompareExchange(ref m_State, (long)RequestState.Completed, (long)RequestState.Initiated); } } catch (Exception e) { SetException(e); } }
public override bool Receive(RedisSocketContext context, int timeoutMilliseconds = -1) { throw new NotImplementedException("Receive is not supported by batch request."); }
protected virtual void ProcessQueue() { var queue = m_AsycRequestQ; if (queue == null) { return; } var context = (RedisSocketContext)null; try { var name = String.Format("{0}, {1}", typeof(RedisDbConnection).Name, Guid.NewGuid().ToString("N").ToUpper()); var idleTime = 0; var idleStart = DateTime.MinValue; var request = (RedisAsyncRequest)null; var onProcessRequest = m_OnProcessRequest; if (onProcessRequest == null) { onProcessRequest = DoProcessRequest; } var disposeRequest = DisposeRequestAfterProcess(); using (var connection = new RedisDbConnection(name, RedisRole.Master, Settings, null, OnReleaseSocket, -1, null, false)) { var commandDbIndex = -1; var contextDbIndex = connection.DbIndex; m_EnqueueGate.Reset(); var idleTimeout = IdleTimeout; while (Processing && !queue.Disposed) { try { if (!queue.TryDequeueOneOf(contextDbIndex, RedisConstants.UninitializedDbIndex, out request)) { if (m_EnqueueGate.Wait(SpinSleepTime)) { m_EnqueueGate.Reset(); } else { idleTime += SpinSleepTime; if (idleTime >= idleTimeout) { break; } if (idleTime > 0 && idleTime % 2000 == 0) { var beatCommand = new RedisCommand(RedisConstants.UninitializedDbIndex, RedisCommandList.Ping); beatCommand.IsHeartBeat = true; Enqueue <RedisBool>(beatCommand, RedisCommandExpect.OK, RedisConstants.PONG); } } continue; } try { var command = request.Command; if (ReferenceEquals(command, null) || !command.IsHeartBeat) { idleTime = 0; } if (!request.IsCompleted) { if (!context.IsAlive()) { try { context = new RedisSocketContext(connection.Connect(), connection.Settings); } catch (Exception e) { if (e.IsSocketError()) { break; } } } commandDbIndex = command.DbIndex; if (commandDbIndex != contextDbIndex && commandDbIndex > RedisConstants.UninitializedDbIndex && context.Socket.SelectDB(connection.Settings, commandDbIndex)) { contextDbIndex = context.DbIndex; connection.SelectDB(contextDbIndex); } onProcessRequest(request, context); } } catch (Exception) { request.Cancel(); } finally { if (disposeRequest && !ReferenceEquals(request, null)) { request.Dispose(); } } } catch (Exception) { } } } } catch (Exception) { } finally { if (queue != null) { queue.CancelRequests(); } if (context.IsAlive()) { context.Dispose(); } DoProcessCompleted(); } }
protected virtual void DoProcessRequest(RedisAsyncRequest request, RedisSocketContext context) { request.Process(context); }
protected virtual bool Flush() { ValidateNotDisposed(); if (Interlocked.CompareExchange(ref m_State, (long)RedisBatchState.Executing, (long)RedisBatchState.WaitingCommit) == (long)RedisBatchState.WaitingCommit) { var success = false; try { var requests = Interlocked.Exchange(ref m_RequestQ, null); if (requests == null) { return(false); } var requestCount = requests.Count; if (requestCount == 0) { return(false); } using (var connection = Owner.Connect(DbIndex, RedisRole.Master)) { if (connection == null) { Cancel(requests); return(false); } var socket = connection.Connect(); if (!socket.IsConnected()) { Cancel(requests); return(false); } try { var context = new RedisSocketContext(socket, connection.Settings ?? RedisPoolSettings.Default); OnFlush(requests, context, out success); if (!success || Interlocked.Read(ref m_State) != (long)RedisBatchState.Executing) { success = false; Discard(requests, context); return(false); } success = true; return(true); } catch (SocketException e) { connection.FreeAndNilSocket(); throw new RedisFatalException(e, RedisErrorCode.SocketError); } } } finally { Interlocked.Exchange(ref m_State, success ? (long)RedisBatchState.Ready : (long)RedisBatchState.Failed); } } return(false); }
protected virtual void OnFlush(IList <RedisRequest> requests, RedisSocketContext context, out bool success) { success = true; }