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);
            }
        }
示例#2
0
        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);
        }
示例#3
0
 public RedisMultiBytes ExpectMultiDataBytes(RedisSocketContext context, bool throwException = true)
 {
     using (var response = ExecuteInternal(context, throwException))
     {
         return(ForMultiDataBytes(response, throwException));
     }
 }
示例#4
0
 public RedisNullableDouble ExpectNullableDouble(RedisSocketContext context, bool throwException = true)
 {
     using (var response = ExecuteInternal(context, throwException))
     {
         return(ForNullableDouble(response, throwException));
     }
 }
示例#5
0
 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)
             { }
         }
     }
 }
示例#6
0
 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);
     }
 }
示例#7
0
        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);
            }
        }
示例#8
0
        public RedisInteger ExpectInteger(RedisSocketContext context, bool throwException = true)
        {
            var result = ExpectNullableInteger(context, throwException);

            if (result == null)
            {
                return(long.MinValue);
            }
            return(result.Value);
        }
示例#9
0
        public RedisString ExpectBulkString(RedisSocketContext context, bool throwException = true)
        {
            var bytes = ExpectBulkStringBytes(context, throwException);

            if (ReferenceEquals(bytes, null))
            {
                return(null);
            }
            return(((byte[])bytes.RawData).ToUTF8String());
        }
示例#10
0
        private string ExpectSimpleStringInternal(RedisSocketContext context, bool throwException = true)
        {
            var bytes = ExpectSimpleStringBytes(context, throwException);

            if (ReferenceEquals(bytes, null))
            {
                return(null);
            }
            return(((byte[])bytes.RawData).ToUTF8String());
        }
示例#11
0
        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);
        }
示例#12
0
        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);
        }
示例#13
0
        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);
        }
示例#14
0
        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);
        }
示例#15
0
 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);
         }
     }
 }
示例#16
0
        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);
        }
示例#17
0
 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)));
     }
 }
示例#18
0
        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);
        }
示例#19
0
        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);
        }
示例#20
0
        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();
                }
            }
        }
示例#22
0
        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);
        }
示例#23
0
        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());
            }
        }
示例#24
0
        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);
        }
示例#25
0
        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);
            }
        }
示例#26
0
 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);
 }
示例#29
0
        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);
        }
示例#30
0
 protected virtual void OnFlush(IList <RedisRequest> requests, RedisSocketContext context, out bool success)
 {
     success = true;
 }