Пример #1
0
 public override void Send <T>(IOperation <T> operation)
 {
     try
     {
         _sslStream.BeginWrite(operation.WriteBuffer, 0, operation.WriteBuffer.Length, SendCallback, operation);
         if (!SendEvent.WaitOne(Configuration.SendTimeout))
         {
             var msg = ExceptionUtil.GetMessage(ExceptionUtil.RemoteHostTimeoutMsg, Configuration.SendTimeout);
             operation.HandleClientError(msg, ResponseStatus.ClientFailure);
             IsDead = true;
         }
     }
     catch (Exception e)
     {
         HandleException(e, operation);
     }
 }
Пример #2
0
 public override void Send <T>(IOperation <T> operation)
 {
     try
     {
         _sslStream.BeginWrite(operation.WriteBuffer, 0, operation.WriteBuffer.Length, SendCallback, operation);
         if (!SendEvent.WaitOne(Configuration.ConnectionTimeout))
         {
             const string msg =
                 "The connection has timed out while an operation was in flight. The default is 15000ms.";
             operation.HandleClientError(msg, ResponseStatus.ClientFailure);
             IsDead = true;
         }
     }
     catch (Exception e)
     {
         HandleException(e, operation);
     }
 }
Пример #3
0
        public override byte[] Send(byte[] buffer)
        {
            var state = new SocketAsyncState
            {
                Data   = new MemoryStream(),
                Opaque = Converter.ToUInt32(buffer, HeaderIndexFor.Opaque)
            };

            _sslStream.BeginWrite(buffer, 0, buffer.Length, SendCallback, state);
            if (!SendEvent.WaitOne(Configuration.SendTimeout))
            {
                //TODO refactor logic
                IsDead = true;
                var msg = ExceptionUtil.GetMessage(ExceptionUtil.RemoteHostTimeoutMsg, Configuration.SendTimeout);
                throw new RemoteHostTimeoutException(msg);
            }

            return(state.Data.ToArray());
        }
Пример #4
0
        public override byte[] Send(byte[] buffer)
        {
            var state = new SocketAsyncState
            {
                Data   = new MemoryStream(),
                Opaque = Converter.ToUInt32(buffer, HeaderIndexFor.Opaque)
            };

            _sslStream.BeginWrite(buffer, 0, buffer.Length, SendCallback, state);
            if (!SendEvent.WaitOne(Configuration.ConnectionTimeout))
            {
                //TODO refactor logic
                IsDead = true;
                const string msg =
                    "The connection has timed out while an operation was in flight. The default is 15000ms.";
                throw new IOException(msg);
            }

            return(state.Data.ToArray());
        }
Пример #5
0
        public override IOperationResult <T> Send <T>(IOperation <T> operation)
        {
            try
            {
                operation.Reset();
                var buffer = operation.Write();

                _sslStream.BeginWrite(buffer, 0, buffer.Length, SendCallback, operation);
                if (!SendEvent.WaitOne(Configuration.OperationTimeout))
                {
                    const string msg = "Operation timed out: the timeout can be configured by changing the PoolConfiguration.OperationTimeout property. The default is 2500ms.";
                    operation.HandleClientError(msg);
                }
            }
            catch (Exception e)
            {
                HandleException(e, operation);
            }

            return(operation.GetResult());
        }
        public override IOperationResult <T> Send <T>(IOperation <T> operation)
        {
            try
            {
                operation.Reset();
                var buffer = operation.Write();
                var index  = operation.VBucket == null ? 0 : operation.VBucket.Index;
                Log.Info(m => m("Sending key {0} using {1} on {2}", operation.Key, index, Socket.RemoteEndPoint));
                _networkStream.BeginWrite(buffer, 0, buffer.Length, SendCallback, operation);

                if (!SendEvent.WaitOne(Configuration.OperationTimeout))
                {
                    const string msg = "Operation timed out: the timeout can be configured by changing the PoolConfiguration.OperationTimeout property. The default is 2500ms.";
                    operation.HandleClientError(msg);
                }
            }
            catch (Exception e)
            {
                HandleException(e, operation);
            }

            return(operation.GetResult());
        }
        public async Task SendingThread(CancellationToken cancellationToken)
        {
            try {
                var lastResult  = TransferResult.Succeeded;
                var timeToDelay = TimeSpan.Zero;
                var rand        = new Random();
                while (!cancellationToken.IsCancellationRequested)
                {
                    bool shouldWait = false;

                    if (timeToDelay != TimeSpan.Zero)
                    {
                        try {
                            await Task.Delay(timeToDelay, cancellationToken);
                        }
                        catch (OperationCanceledException) {
                            break;
                        }
                    }

                    lock (QueueLock) {
                        shouldWait = Queue.Count == 0;
                    }

                    if (shouldWait)
                    {
                        try {
                            SendEvent.WaitOne();
                        }
                        catch (Exception ex) {
                            this.FatalError(this, new FatalErrorEventArgs("Failed to wait event for sending data. Stopping sending.", ex));
                            break;
                        }
                    }

                    if (cancellationToken.IsCancellationRequested)
                    {
                        break;
                    }

                    lock (QueueLock) {
                        if (Queue.Count == 0)
                        {
                            continue;
                        }
                    }

                    var itemsToSend = new List <QueueItem>();
                    lock (QueueLock) {
                        if (DataSender.SupportsMultiPost)
                        {
                            itemsToSend.AddRange(Queue.Take(MaxChunkSize));
                        }
                        else
                        {
                            itemsToSend.Add(Queue.Peek());
                        }
                    }

                    if (!itemsToSend.Any())
                    {
                        continue;
                    }

                    var dataArray   = itemsToSend.Select(x => x.ApiData).ToArray();
                    var trackingIds = itemsToSend.Select(x => x.TrackingId).ToArray();
                    try {
                        this.ApiDataSending?.Invoke(this, new ApiDataSendingEventArgs(trackingIds, dataArray));

                        ISentApiData sentApiData = null;
                        if (DataSender.SupportsMultiPost)
                        {
                            sentApiData = await DataSender.SendData(dataArray);
                        }
                        else
                        {
                            sentApiData = await DataSender.SendData(dataArray[0]);
                        }

                        lastResult  = TransferResult.Succeeded;
                        timeToDelay = TimeSpan.Zero;

                        this.ApiDataSent?.Invoke(this, new ApiDataSentEventArgs(trackingIds, dataArray, sentApiData));
                    }
                    catch (DataSendingException ex) {
                        this.SendingError?.Invoke(this, new SendingErrorEventArgs(trackingIds, "Failed sending API data.", dataArray, ex));
                        switch (ex.Reason)
                        {
                        case SendingErrorReason.ServerError:
                            if (lastResult == TransferResult.ServerError)
                            {
                                timeToDelay += ServerErrorDelayIncrement;
                                if (timeToDelay > MaxDelayAfterServerkError)
                                {
                                    timeToDelay = MaxDelayAfterServerkError;
                                }
                            }
                            else
                            {
                                timeToDelay = MinDelayAfterServerkError;
                            }
                            lastResult = TransferResult.ServerError;
                            break;

                        case SendingErrorReason.HttpProtocolError:
                        case SendingErrorReason.NetworkError:
                        case SendingErrorReason.Unknown:
                            if (lastResult == TransferResult.NetworkError)
                            {
                                timeToDelay += NetworkErrorDelayIncrement;
                                if (timeToDelay > MaxDelayAfterNetworkError)
                                {
                                    timeToDelay = MaxDelayAfterNetworkError;
                                }
                            }
                            else
                            {
                                timeToDelay = MinDelayAfterNetworkError;
                            }
                            lastResult = TransferResult.NetworkError;
                            break;
                        }
                        continue;
                    }
                    catch (OperationCanceledException) {
                        break;
                    }
                    catch (Exception ex) {
                        this.InternalError?.Invoke(this, new InternalErrorEventArgs(trackingIds, "Failed to something before sending API data.", ex, dataArray));
                        continue;
                    }

                    lock (QueueLock) {
                        for (int i = 0; i < itemsToSend.Count && Queue.Count > 0; i++)
                        {
                            Queue.Dequeue();
                        }
                    }
                }
            }
            catch (Exception ex) {
                FatalError?.Invoke(this, new FatalErrorEventArgs("Sending thread aborted. API data will no longer be sent from now.", ex));
            }
        }