private RedisResult ReadSingleResult() { byte b = ReadByteOrFail(); switch ((char)b) { case '+': return(RedisResult.Message(ReadBytesToCrlf())); case '-': return(RedisResult.Error(ReadStringToCrlf())); case ':': return(RedisResult.Integer(ReadInt64())); case '$': return(RedisResult.Bytes(ReadBulkBytes())); case '*': var count = (int)ReadInt64(); if (count == -1) { return(RedisResult.Multi(null)); } var inner = new RedisResult[count]; for (int i = 0; i < count; i++) { inner[i] = ReadSingleResult(); } return(RedisResult.Multi(inner)); default: throw new RedisException("Not expecting header: &x" + b.ToString("x2")); } }
protected virtual void ProcessError(RedisResult result, RedisMessage message, bool includeDetail) { var ex = result.Error(); if (message != null && includeDetail) { ex.Data.Add("redis-command", message.ToString()); } source.SafeSetException(ex); }
void IMessageResult.Complete(RedisResult result, RedisMessage message, bool includeDetail) { if (result.IsCancellation) { RedisConnectionBase.Trace("transaction", "cancelled"); SetInnerReplies(result); completion.TrySetCanceled(); } else if (result.IsError) { RedisConnectionBase.Trace("transaction", "error"); SetInnerReplies(result); completion.SafeSetException(result.Error()); } else { try { if (result.IsNil) { // aborted RedisConnectionBase.Trace("transaction", "aborted"); SetInnerReplies(RedisResult.Cancelled); completion.TrySetResult(false); } else { var items = result.ValueItems; if (items.Length != (queued == null ? 0 : queued.Length)) { throw new InvalidOperationException(string.Format("{0} results expected, {1} received", queued.Length, items.Length)); } RedisConnectionBase.Trace("transaction", "success"); for (int i = 0; i < items.Length; i++) { RedisResult reply = items[i]; RedisConnectionBase.CallbackMode callbackMode; var ctx = parent.ProcessReply(ref reply, queued[i].InnerMessage, out callbackMode); RedisConnectionBase.Trace("transaction", "{0} = {1}", ctx, reply); parent.ProcessCallbacks(ctx, reply, callbackMode); } completion.TrySetResult(true); } } catch (Exception ex) { completion.SafeSetException(ex); throw; } } }
protected override void ProcessError(RedisResult result, RedisMessage message, bool includeDetail) { try { var msg = result.Error().Message; if (msg.StartsWith("NOSCRIPT")) { // only way of unloading is to unload all ("SCRIPT FLUSH")... so our // existing cache is now completely toast connection.ResetScriptCache(); } } catch { /* best efforts only */ } base.ProcessError(result, message, includeDetail); }
void IMessageResult.Complete(RedisResult result) { if (result.IsCancellation) { completion.SetCanceled(); SetInnerReplies(result); } else if (result.IsError) { completion.SetException(result.Error()); SetInnerReplies(result); } else { try { if (result.IsNil) { // aborted SetInnerReplies(RedisResult.Cancelled); completion.SetResult(false); } else { RedisResult[] items = result.ValueItems; if (items.Length != (queued == null ? 0 : queued.Length)) { throw new InvalidOperationException(string.Format("{0} results expected, {1} received", queued.Length, items.Length)); } for (int i = 0; i < items.Length; i++) { RedisResult reply = items[i]; object ctx = parent.ProcessReply(ref reply, queued[i].InnerMessage); parent.ProcessCallbacks(ctx, reply); } completion.SetResult(true); } } catch (Exception ex) { completion.SetException(ex); throw; } } }
private void Outgoing() { try { OnOpened(); int db = 0; RedisMessage next; Trace.WriteLine("Redis send-pump is starting"); bool isHigh, shouldFlush; while (unsent.TryDequeue(false, out next, out isHigh, out shouldFlush)) { if (abort) { CompleteMessage(next, RedisResult.Error("The system aborted before this message was sent")); continue; } if (!next.ChangeState(MessageState.NotSent, MessageState.Sent)) { // already cancelled; not our problem any more... Interlocked.Increment(ref messagesCancelled); continue; } if (isHigh) { Interlocked.Increment(ref queueJumpers); } WriteMessage(ref db, next, null); Flush(shouldFlush); } Interlocked.CompareExchange(ref state, (int)ConnectionState.Closing, (int)ConnectionState.Open); if (redisStream != null) { RedisMessage quit = RedisMessage.Create(-1, RedisLiteral.QUIT).ExpectOk().Critical(); RecordSent(quit, !abort); quit.Write(outBuffer); outBuffer.Flush(); redisStream.Flush(); Interlocked.Increment(ref messagesSent); } Trace.WriteLine("Redis send-pump is exiting"); } catch (Exception ex) { OnError("Outgoing queue", ex, true); } }
internal override object ProcessReply(ref RedisResult result, RedisMessage message) { byte[] expected; if (!result.IsError && (expected = message.Expected) != null) { result = result.IsMatch(expected) ? RedisResult.Pass : RedisResult.Error(result.ValueString); } if (result.IsError && message.MustSucceed) { throw new RedisException("A critical operation failed: " + message); } return(message); }
/// <summary> /// Invoked when the server is terminating /// </summary> protected override void ShuttingDown(Exception error) { base.ShuttingDown(error); RedisMessage message; RedisResult result = null; lock (sent) { if (sent.Count > 0) { result = RedisResult.Error( error == null ? "The server terminated before a reply was received" : ("Error processing data: " + error.Message)); } while (sent.Count > 0) { // notify clients of things that just didn't happen message = sent.Dequeue(); CompleteMessage(message, result); } } }
void IMessageResult.Complete(RedisResult result, RedisMessage message, bool includeDetail) { if (result.IsCancellation) { RedisConnectionBase.Trace("transaction", "cancelled"); SetInnerReplies(result); completion.TrySetCanceled(); } else if (result.IsError) { RedisConnectionBase.Trace("transaction", "error"); SetInnerReplies(result); completion.SafeSetException(result.Error()); } else { try { if (result.IsNil) { // aborted RedisConnectionBase.Trace("transaction", "aborted"); SetInnerReplies(RedisResult.Cancelled); completion.TrySetResult(false); } else { var items = result.ValueItems; if (items.Length != (queued == null ? 0 : queued.Length)) throw new InvalidOperationException(string.Format("{0} results expected, {1} received", queued.Length, items.Length)); RedisConnectionBase.Trace("transaction", "success"); for (int i = 0; i < items.Length; i++) { RedisResult reply = items[i]; RedisConnectionBase.CallbackMode callbackMode; var ctx = parent.ProcessReply(ref reply, queued[i].InnerMessage, out callbackMode); RedisConnectionBase.Trace("transaction", "{0} = {1}", ctx, reply); parent.ProcessCallbacks(ctx, reply, callbackMode); } completion.TrySetResult(true); } } catch (Exception ex) { completion.SafeSetException(ex); throw; } } }
protected virtual void ProcessError(RedisResult result) { source.SetException(result.Error()); }
private void ReadReplyHeader(IAsyncResult asyncResult) { try { int bytesRead; try { bytesRead = ((NetworkStream)asyncResult.AsyncState).EndRead(asyncResult); } catch (ObjectDisposedException) { bytesRead = 0; // simulate EOF } catch (NullReferenceException) { bytesRead = 0; // simulate EOF } if (bytesRead <= 0 || redisStream == null) { // EOF Shutdown("End of stream", null); } else { bool isEof = false; bufferCount += bytesRead; while (bufferCount > 0) { RedisResult result = ReadSingleResult(); Interlocked.Increment(ref messagesReceived); object ctx = ProcessReply(ref result); if (result.IsError) { Interlocked.Increment(ref errorMessages); OnError("Redis server", result.Error(), false); } try { ProcessCallbacks(ctx, result); } catch (Exception ex) { OnError("Processing callbacks", ex, false); } isEof = false; NetworkStream tmp = redisStream; if (bufferCount == 0 && tmp != null && tmp.DataAvailable) { isEof = !ReadMoreSync(); } } if (isEof) { // EOF Shutdown("End of stream", null); } else { ReadMoreAsync(); } } } catch (Exception ex) { Shutdown("Invalid inbound stream", ex); } }
void IMessageResult.Complete(RedisResult result) { if (result.IsCancellation) { completion.SetCanceled(); } else if (result.IsError) { completion.SetException(result.Error()); } else { try { if (queued == null) throw new InvalidOperationException("Nothing was queued (null)!"); var items = result.ValueItems; if (items.Length != queued.Length) throw new InvalidOperationException(string.Format("{0} results expected, {1} received", queued.Length, items.Length)); for (int i = 0; i < items.Length; i++) { RedisResult reply = items[i]; var ctx = parent.ProcessReply(ref reply, queued[i].InnerMessage); parent.ProcessCallbacks(ctx, reply); } completion.SetResult(true); } catch (Exception ex) { completion.SetException(ex); throw; } } }
void IMessageResult.Complete(RedisResult result) { if (result.IsCancellation) { completion.SetCanceled(); SetInnerReplies(result); } else if (result.IsError) { completion.SetException(result.Error()); SetInnerReplies(result); } else { try { if (result.IsNil) { // aborted SetInnerReplies(RedisResult.Cancelled); completion.SetResult(false); } else { RedisResult[] items = result.ValueItems; if (items.Length != (queued == null ? 0 : queued.Length)) throw new InvalidOperationException(string.Format("{0} results expected, {1} received", queued.Length, items.Length)); for (int i = 0; i < items.Length; i++) { RedisResult reply = items[i]; object ctx = parent.ProcessReply(ref reply, queued[i].InnerMessage); parent.ProcessCallbacks(ctx, reply); } completion.SetResult(true); } } catch (Exception ex) { completion.SetException(ex); throw; } } }