コード例 #1
0
 /// <summary>
 /// Handles the specified message.
 /// </summary>
 /// <param name="message">The message.</param>
 /// <param name="workerNotification">The worker notification.</param>
 /// <returns>
 /// an awaitable task
 /// </returns>
 public async Task Handle(IReceivedMessageInternal message, IWorkerNotification workerNotification)
 {
     using (_runCodeTimer.NewContext())
     {
         await _handler.Handle(message, workerNotification).ConfigureAwait(false);
     }
 }
コード例 #2
0
        private void HandleMessages(IReceivedMessage <SimpleMessage> message, IWorkerNotification notifications)
        {
            notifications.Log.LogDebug(
                $"Processing Message {message.MessageId} with run time {message.Body.RunTimeInMs}");

            if (message.Body.RunTimeInMs > 0)
            {
                var end = DateTime.Now + TimeSpan.FromMilliseconds(message.Body.RunTimeInMs);
                if (notifications.TransportSupportsRollback)
                {
                    Task.Delay(message.Body.RunTimeInMs, notifications.WorkerStopping.CancelWorkToken).Wait(notifications.WorkerStopping.CancelWorkToken);
                }
                else //no rollback possible; we will ignore cancel / stop requests
                {
                    Task.Delay(message.Body.RunTimeInMs);
                }

                if (DateTime.Now < end) //did we finish?
                {                       //nope - we probably are being canceled
                    if (notifications.TransportSupportsRollback && notifications.WorkerStopping.CancelWorkToken.IsCancellationRequested)
                    {
                        notifications.Log.LogDebug("Cancel has been requested - aborting");
                        notifications.WorkerStopping.CancelWorkToken.ThrowIfCancellationRequested();
                    }
                }
            }
            notifications.Log.LogDebug($"Processed message {message.MessageId}");
        }
コード例 #3
0
 /// <summary>
 /// Handles the specified message.
 /// </summary>
 /// <param name="message">The message.</param>
 /// <param name="workerNotification">The worker notification.</param>
 public void Handle(IReceivedMessageInternal message, IWorkerNotification workerNotification)
 {
     using (_runCodeTimer.NewContext())
     {
         _handler.Handle(message, workerNotification);
     }
 }
コード例 #4
0
 /// <summary>
 /// Handles the specified message.
 /// </summary>
 /// <param name="message">The message.</param>
 /// <param name="workerNotification">The worker notification.</param>
 public async Task HandleAsync(IReceivedMessageInternal message, IWorkerNotification workerNotification)
 {
     using (_runCodeTimer.NewContext())
     {
         await _handler.HandleAsync(message, workerNotification).ConfigureAwait(false);
     }
 }
コード例 #5
0
 public void HandleExecution(IReceivedMessage<MessageExpression> receivedMessage, IWorkerNotification workerNotification)
 {
     switch (receivedMessage.Body.PayLoad)
     {
         case MessageExpressionPayloads.Action:
             using (_runMethodCompiledCodeTimer.NewContext())
             {
                 _handler.HandleExecution(receivedMessage, workerNotification);
             }
             break;
         case MessageExpressionPayloads.ActionText:
             using (_runMethodDynamicCodeTimer.NewContext())
             {
                 _handler.HandleExecution(receivedMessage, workerNotification);
             }
             break;
         case MessageExpressionPayloads.Function:
             using (_runFunctionCompiledCodeTimer.NewContext())
             {
                 _handler.HandleExecution(receivedMessage, workerNotification);
             }
             break;
         case MessageExpressionPayloads.FunctionText:
             using (_runFunctionDynamicCodeTimer.NewContext())
             {
                 _handler.HandleExecution(receivedMessage, workerNotification);
             }
             break;
         default:
             throw new DotNetWorkQueueException($"Logic error - failed to handle type {receivedMessage.Body.PayLoad}");
     }
 }
コード例 #6
0
        /// <summary>
        /// Handles processing of linq expression tree messages.
        /// </summary>
        /// <param name="receivedMessage">The received message.</param>
        /// <param name="workerNotification">The worker notification.</param>
        public void HandleExecution(IReceivedMessage<MessageExpression> receivedMessage, IWorkerNotification workerNotification)
        {
            ThrowIfDisposed();
            Guard.NotNull(() => receivedMessage, receivedMessage);
            Guard.NotNull(() => workerNotification, workerNotification);

            switch (receivedMessage.Body.PayLoad)
            {
                case MessageExpressionPayloads.Action:
                    HandleAction(receivedMessage, workerNotification);
                    break;
                case MessageExpressionPayloads.Function:
                    HandleFunction(receivedMessage, workerNotification);
                    break;
                case MessageExpressionPayloads.ActionText:
                    var targetMethod =
                        _linqCompiler.CompileAction(
                            _compositeSerialization.InternalSerializer.ConvertBytesTo<LinqExpressionToRun>(
                                receivedMessage.Body.SerializedExpression));

                    try
                    {
                        HandleAction(targetMethod, receivedMessage, workerNotification);
                    }
                    catch (Exception error) //throw the real exception if needed
                    {
                        if (error.Message == "Exception has been thrown by the target of an invocation." &&
                            error.InnerException != null)
                        {
                            throw error.InnerException;
                        }
                        throw;
                    }

                    break;
                case MessageExpressionPayloads.FunctionText:
                    var targetFunction =
                        _linqCompiler.CompileFunction(
                            _compositeSerialization.InternalSerializer.ConvertBytesTo<LinqExpressionToRun>(
                                receivedMessage.Body.SerializedExpression));

                    try
                    {
                        HandleFunction(targetFunction, receivedMessage, workerNotification);
                    }
                    catch (Exception error) //throw the real exception if needed
                    {
                        if (error.Message == "Exception has been thrown by the target of an invocation." &&
                            error.InnerException != null)
                        {
                            throw error.InnerException;
                        }
                        throw;
                    }

                    break;
                default:
                    throw new DotNetWorkQueueException($"The method type of {receivedMessage.Body.PayLoad} is not implemented");
            }
        }
コード例 #7
0
 public static void Run <TMessage>(IReceivedMessage <TMessage> message, IWorkerNotification notification, Guid queueId, int runTime)
     where TMessage : class
 {
     if (MethodIncrementWrapper.HasRollBack(queueId, (Guid)message.CorrelationId.Id.Value))
     {
         var counter = runTime / 3;
         for (var i = 0; i < counter; i++)
         {
             if (notification.WorkerStopping.StopWorkToken.IsCancellationRequested || notification.WorkerStopping.CancelWorkToken.IsCancellationRequested)
             {
                 MethodIncrementWrapper.IncreaseCounter(queueId);
                 return;
             }
             Thread.Sleep(1000);
         }
         MethodIncrementWrapper.IncreaseCounter(queueId);
     }
     else
     {
         var counter = runTime / 2;
         for (var i = 0; i < counter; i++)
         {
             Thread.Sleep(1000);
         }
         MethodIncrementWrapper.SetRollback(queueId, (Guid)message.CorrelationId.Id.Value);
         throw new OperationCanceledException("I don't feel like processing this message");
     }
 }
コード例 #8
0
 /// <summary>
 /// Handles the specified message.
 /// </summary>
 /// <param name="message">The message.</param>
 /// <param name="workerNotification">The worker notification.</param>
 public void Handle(IReceivedMessageInternal message, IWorkerNotification workerNotification)
 {
     using (_runCodeTimer.NewContext())
     {
         _handler.Handle(message, workerNotification);
     }
 }
コード例 #9
0
 /// <summary>
 /// Checks to see if the queue is stopping; if not, runs the user provided message processing delegate
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="message">The message.</param>
 /// <param name="notifications">The notifications.</param>
 /// <param name="functionToRun">The function to run.</param>
 private void WrappedFunction <T>(IReceivedMessage <T> message, IWorkerNotification notifications, Action <IReceivedMessage <T>, IWorkerNotification> functionToRun)
     where T : class
 {
     if (ShouldHandle(notifications))
     {
         functionToRun(message, notifications);
     }
 }
コード例 #10
0
        /// <inheritdoc />
        public void Handle(IReceivedMessageInternal message, IWorkerNotification workerNotification)
        {
            var ActivityContext = message.Extract(_tracer, _headers);

            using (var scope = _tracer.StartActivity("MessageHandler", ActivityKind.Internal, parentContext: ActivityContext))
            {
                _handler.Handle(message, workerNotification);
            }
        }
コード例 #11
0
        /// <summary>
        /// Handles the specified message.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="workerNotification">The worker notification.</param>
        /// <returns></returns>
        public async Task HandleAsync(IReceivedMessageInternal message, IWorkerNotification workerNotification)
        {
            var activityContext = message.Extract(_tracer, _headers.StandardHeaders);

            using (var scope = _tracer.StartActivity("MessageHandlerAsync", ActivityKind.Internal, activityContext))
            {
                scope?.AddMessageIdTag(message);
                await _handler.HandleAsync(message, workerNotification);
            }
        }
コード例 #12
0
        public void RunMe(IWorkerNotification workNotification, string input1, int input2, SomeInput moreInput)
        {
            var sb = new StringBuilder();

            sb.Append(input1);
            sb.Append(" ");
            sb.Append(input2);
            sb.Append(" ");
            sb.AppendLine(moreInput.Message);
            workNotification.Log.LogInformation(sb.ToString());
        }
コード例 #13
0
        /// <inheritdoc />
        public void HandleExecution(IReceivedMessage <MessageExpression> receivedMessage,
                                    IWorkerNotification workerNotification)
        {
            var ActivityContext = receivedMessage.Headers.Extract(_tracer, _headers);

            using (var scope = _tracer.StartActivity("LinqExecution", ActivityKind.Internal, parentContext: ActivityContext))
            {
                scope?.SetTag("ActionType", receivedMessage.Body.PayLoad.ToString());
                _handler.HandleExecution(receivedMessage, workerNotification);
            }
        }
コード例 #14
0
 /// <summary>
 /// Runs a compiled linq expression.
 /// </summary>
 /// <param name="receivedMessage">The received message.</param>
 /// <param name="workerNotification">The worker notification.</param>
 private void HandleRawAction(IReceivedMessage <MessageExpression> receivedMessage,
                              IWorkerNotification workerNotification)
 {
     try
     {
         HandleAction(receivedMessage.Body.Method.Compile(), receivedMessage, workerNotification);
     }
     catch (Exception error) //throw the real exception if needed
     {
         if (error.Message == "Exception has been thrown by the target of an invocation." &&
             error.InnerException != null)
         {
             throw error.InnerException;
         }
         throw;
     }
 }
コード例 #15
0
        /// <summary>
        /// Checks to see if message processing should happen; will throw an exception if not
        /// </summary>
        /// <param name="notifications">The notifications.</param>
        /// <returns>Always true; exception is thrown for false</returns>
        /// <exception cref="System.OperationCanceledException"></exception>
        private bool ShouldHandle(IWorkerNotification notifications)
        {
            if (notifications.TransportSupportsRollback &&
                notifications.WorkerStopping.Tokens.Any(m => m.IsCancellationRequested))
            {
                _log.Info("System is preparing to stop - aborting");
                notifications.WorkerStopping.Tokens.Find(m => m.IsCancellationRequested).ThrowIfCancellationRequested();
            }

            if (notifications.TransportSupportsRollback && notifications.HeartBeat != null && notifications.HeartBeat.ExceptionHasOccured.IsCancellationRequested)
            {
                _log.Warn(
                    "The heartbeat worker has failed - aborting our work since another thread may pick up this item");
                notifications.HeartBeat.ExceptionHasOccured.ThrowIfCancellationRequested();
            }

            return(true);
        }
コード例 #16
0
        /// <summary>
        /// Handles the messages.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="notifications">The notifications.</param>
        private void HandleMessages(IReceivedMessage <SimpleMessage> message, IWorkerNotification notifications)
        {
            //if we have a connection, this is an rpc request
            var connection = message.GetHeader(notifications.HeaderNames.StandardHeaders.RpcConnectionInfo);

            notifications.Log.Debug(
                $"Processing Message {message.MessageId} with run time {message.Body.RunTimeInMs}");

            if (message.Body.RunTimeInMs > 0)
            {
                var end = DateTime.Now + TimeSpan.FromMilliseconds(message.Body.RunTimeInMs);
                if (notifications.TransportSupportsRollback)
                {
                    Task.Delay(message.Body.RunTimeInMs, notifications.WorkerStopping.CancelWorkToken).Wait(notifications.WorkerStopping.CancelWorkToken);
                }
                else //no rollback possible; we will ignore cancel / stop requests
                {
                    Task.Delay(message.Body.RunTimeInMs);
                }

                if (DateTime.Now < end) //did we finish?
                {                       //nope - we probably are being canceled
                    if (notifications.TransportSupportsRollback && notifications.WorkerStopping.CancelWorkToken.IsCancellationRequested)
                    {
                        notifications.Log.Debug("Cancel has been requested - aborting");
                        notifications.WorkerStopping.CancelWorkToken.ThrowIfCancellationRequested();
                    }
                }
            }
            notifications.Log.Debug($"Processed message {message.MessageId}");

            if (connection == null)
            {
                return;
            }

            var timeOut = message.GetHeader(notifications.HeaderNames.StandardHeaders.RpcTimeout).Timeout;

            CreateRpcModuleIfNeeded(connection.QueueName, connection.ConnectionString);
            RpcQueues[connection.QueueName].Send(new SimpleResponse {
                Message = DateTime.UtcNow.ToString(System.Globalization.CultureInfo.InvariantCulture)
            },
                                                 RpcQueues[connection.QueueName].CreateResponse(message.MessageId, timeOut));
        }
コード例 #17
0
        /// <inheritdoc />
        public void Handle(IReceivedMessageInternal message, IWorkerNotification workerNotification)
        {
            var spanContext = message.Extract(_tracer, _headers);

            if (spanContext != null)
            {
                using (IScope scope = _tracer.BuildSpan("MessageHandler").AddReference(References.FollowsFrom, spanContext).StartActive(finishSpanOnDispose: true))
                {
                    _handler.Handle(message, workerNotification);
                }
            }
            else
            {
                using (IScope scope = _tracer.BuildSpan("MessageHandler").StartActive(finishSpanOnDispose: true))
                {
                    _handler.Handle(message, workerNotification);
                }
            }
        }
コード例 #18
0
        /// <summary>
        /// De-serializes and runs a compiled linq func expression.
        /// </summary>
        /// <param name="receivedMessage">The received message.</param>
        /// <param name="workerNotification">The worker notification.</param>
        private void HandleFunction(IReceivedMessage <MessageExpression> receivedMessage,
                                    IWorkerNotification workerNotification)
        {
            var target = _serializer.ConvertBytesToFunction(receivedMessage.Body.SerializedExpression);

            try
            {
                HandleFunction(target.Compile(), receivedMessage, workerNotification);
            }
            catch (Exception error) //throw the real exception if needed
            {
                if (error.Message == "Exception has been thrown by the target of an invocation." &&
                    error.InnerException != null)
                {
                    throw error.InnerException;
                }
                throw;
            }
        }
コード例 #19
0
        private void HandleFakeMessages(IReceivedMessage <TTMessage> message, IWorkerNotification notifications, int runTime,
                                        IncrementWrapper processedCount, int messageCount, ManualResetEventSlim waitForFinish)
        {
            if (runTime > 0)
            {
                Thread.Sleep(runTime * 1000);
            }

            var timeOut = message.GetHeader(notifications.HeaderNames.StandardHeaders.RpcTimeout).Timeout;

            var connection = message.GetHeader(notifications.HeaderNames.StandardHeaders.RpcConnectionInfo);

            if (connection == null)
            {
                throw new DotNetWorkQueueException("response connection was not set");
            }

            if (!_queues.ContainsKey(connection))
            {
                lock (_createQueue)
                {
                    if (!_queues.ContainsKey(connection))
                    {
                        var queue = CreateResponseQueue(connection);
                        if (!_queues.TryAdd(connection, queue))
                        {
                            queue.Dispose();
                        }
                    }
                }
            }

            var response = new TTResponse();

            _queues[connection].Send(response, _queues[connection].CreateResponse(message.MessageId, timeOut));

            Interlocked.Increment(ref processedCount.ProcessedCount);
            if (Interlocked.Read(ref processedCount.ProcessedCount) == messageCount)
            {
                waitForFinish.Set();
            }
        }
コード例 #20
0
        /// <summary>
        /// Handles the specified message.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="workerNotification">The worker notification.</param>
        /// <returns></returns>
        public async Task HandleAsync(IReceivedMessageInternal message, IWorkerNotification workerNotification)
        {
            var spanContext = message.Extract(_tracer, _headers.StandardHeaders);

            if (spanContext != null)
            {
                using (IScope scope = _tracer.BuildSpan("MessageHandlerAsync").AddReference(References.FollowsFrom, spanContext).StartActive(finishSpanOnDispose: true))
                {
                    scope.Span.AddMessageIdTag(message);
                    await _handler.HandleAsync(message, workerNotification);
                }
            }
            else
            {
                using (IScope scope = _tracer.BuildSpan("MessageHandlerAsync").StartActive(finishSpanOnDispose: true))
                {
                    scope.Span.AddMessageIdTag(message);
                    await _handler.HandleAsync(message, workerNotification);
                }
            }
        }
コード例 #21
0
 /// <summary>
 /// Handles the specified message.
 /// </summary>
 /// <param name="message">The message.</param>
 /// <param name="workerNotification">The worker notification.</param>
 /// <returns>
 /// A task
 /// </returns>
 public async Task HandleAsync(IReceivedMessageInternal message, IWorkerNotification workerNotification)
 {
     await _messageHandlerAsync.HandleAsync(message, workerNotification).ConfigureAwait(false);
 }
コード例 #22
0
 /// <summary>
 /// Handles the specified message.
 /// </summary>
 /// <param name="message">The message.</param>
 /// <param name="workerNotification">The worker notification.</param>
 /// <returns>
 /// A task if async mode; null if sync mode
 /// </returns>
 public void Handle(IReceivedMessageInternal message, IWorkerNotification workerNotification)
 {
     _messageHandler.Handle(message, workerNotification);
 }
コード例 #23
0
 /// <inheritdoc />
 public Task HandleAsync <T>(IWorkGroup workGroup, IReceivedMessage <T> message, IWorkerNotification notifications, Action <IReceivedMessage <T>, IWorkerNotification> functionToRun, ITaskFactory taskFactory) where T : class
 {
     using (IScope scope = _tracer.BuildSpan("SchedulerMessageHandler").StartActive(finishSpanOnDispose: true))
     {
         return(_handler.HandleAsync(workGroup, message, notifications, functionToRun, taskFactory));
     }
 }
コード例 #24
0
        /// <inheritdoc />
        public void HandleExecution(IReceivedMessage <MessageExpression> receivedMessage, IWorkerNotification workerNotification)
        {
            var spanContext = receivedMessage.Headers.Extract(_tracer, _headers);

            if (spanContext != null)
            {
                using (IScope scope = _tracer.BuildSpan("LinqExecution").AddReference(References.FollowsFrom, spanContext).StartActive(finishSpanOnDispose: true))
                {
                    scope.Span.SetTag("ActionType", receivedMessage.Body.PayLoad.ToString());
                    _handler.HandleExecution(receivedMessage, workerNotification);
                }
            }
            else
            {
                using (IScope scope = _tracer.BuildSpan("LinqExecution").StartActive(finishSpanOnDispose: true))
                {
                    scope.Span.SetTag("ActionType", receivedMessage.Body.PayLoad.ToString());
                    _handler.HandleExecution(receivedMessage, workerNotification);
                }
            }
        }
コード例 #25
0
        public void HandleExecution(IReceivedMessage <MessageExpression> receivedMessage, IWorkerNotification workerNotification)
        {
            switch (receivedMessage.Body.PayLoad)
            {
            case MessageExpressionPayloads.Action:
            case MessageExpressionPayloads.ActionRaw:
                using (_runMethodCompiledCodeTimer.NewContext())
                {
                    _handler.HandleExecution(receivedMessage, workerNotification);
                }
                break;

            case MessageExpressionPayloads.ActionText:
                using (_runMethodDynamicCodeTimer.NewContext())
                {
                    _handler.HandleExecution(receivedMessage, workerNotification);
                }
                break;

            default:
                throw new DotNetWorkQueueException($"Logic error - failed to handle type {receivedMessage.Body.PayLoad}");
            }
        }
コード例 #26
0
 /// <summary>
 /// Handles the specified message.
 /// </summary>
 /// <param name="message">The message.</param>
 /// <param name="workerNotification">The worker notification.</param>
 /// <returns></returns>
 public Task Handle(IReceivedMessageInternal message, IWorkerNotification workerNotification)
 {
     Guard.NotNull(() => message, message);
     Guard.NotNull(() => workerNotification, workerNotification);
     return _messageHandlerRegistration.GetHandler().Invoke(_messageHandlerRegistration.GenerateMessage(message), workerNotification);
 }
コード例 #27
0
        /// <summary>
        /// De-serializes and runs a compiled linq func expression.
        /// </summary>
        /// <param name="function">The function.</param>
        /// <param name="receivedMessage">The received message.</param>
        /// <param name="workerNotification">The worker notification.</param>
        private void HandleFunction(Func <IReceivedMessage <MessageExpression>, IWorkerNotification, object> function, IReceivedMessage <MessageExpression> receivedMessage, IWorkerNotification workerNotification)
        {
            var result = function.DynamicInvoke(receivedMessage, workerNotification);

            if (result == null)
            {
                return;
            }

            //if we have a connection, this is an rpc request
            var connection =
                receivedMessage.GetHeader(workerNotification.HeaderNames.StandardHeaders.RpcConnectionInfo);

            //if no connection, then this was not RPC
            if (connection == null)
            {
                return;
            }

            var timeOut =
                receivedMessage.GetHeader(workerNotification.HeaderNames.StandardHeaders.RpcTimeout).Timeout;

            //if we don't have an RPC queue for this queue, create one
            CreateRpcModuleIfNeeded(connection);

            //send the response
            var response =
                _rpcQueues[connection].Send(
                    result,
                    _rpcQueues[connection].CreateResponse(receivedMessage.MessageId, timeOut));

            if (response.HasError)
            {
                _log.ErrorException("Failed to send a response for message {0}", response.SendingException, receivedMessage.MessageId.Id.Value);
            }
        }
コード例 #28
0
        /// <inheritdoc />
        public void HandleExecution(IReceivedMessage <MessageExpression> receivedMessage, IWorkerNotification workerNotification)
        {
            ThrowIfDisposed();
            Guard.NotNull(() => receivedMessage, receivedMessage);
            Guard.NotNull(() => workerNotification, workerNotification);

            switch (receivedMessage.Body.PayLoad)
            {
            case MessageExpressionPayloads.Action:
                HandleAction(receivedMessage, workerNotification);
                break;

            case MessageExpressionPayloads.ActionRaw:
                HandleRawAction(receivedMessage, workerNotification);
                break;

            case MessageExpressionPayloads.Function:
                HandleFunction(receivedMessage, workerNotification);
                break;

            case MessageExpressionPayloads.ActionText:
                var targetMethod =
                    _linqCompiler.CompileAction(
                        _compositeSerialization.InternalSerializer.ConvertBytesTo <LinqExpressionToRun>(
                            receivedMessage.Body.SerializedExpression));

                try
                {
                    HandleAction(targetMethod, receivedMessage, workerNotification);
                }
                catch (Exception error)     //throw the real exception if needed
                {
                    if (error.Message == "Exception has been thrown by the target of an invocation." &&
                        error.InnerException != null)
                    {
                        throw error.InnerException;
                    }
                    throw;
                }

                break;

            case MessageExpressionPayloads.FunctionText:
                var targetFunction =
                    _linqCompiler.CompileFunction(
                        _compositeSerialization.InternalSerializer.ConvertBytesTo <LinqExpressionToRun>(
                            receivedMessage.Body.SerializedExpression));

                try
                {
                    HandleFunction(targetFunction, receivedMessage, workerNotification);
                }
                catch (Exception error)     //throw the real exception if needed
                {
                    if (error.Message == "Exception has been thrown by the target of an invocation." &&
                        error.InnerException != null)
                    {
                        throw error.InnerException;
                    }
                    throw;
                }

                break;

            default:
                throw new DotNetWorkQueueException($"The method type of {receivedMessage.Body.PayLoad} is not implemented");
            }
        }
コード例 #29
0
 /// <summary>
 /// Runs a compiled linq expression.
 /// </summary>
 /// <param name="action">The action.</param>
 /// <param name="receivedMessage">The received message.</param>
 /// <param name="workerNotification">The worker notification.</param>
 private void HandleAction(Action <IReceivedMessage <MessageExpression>, IWorkerNotification> action, IReceivedMessage <MessageExpression> receivedMessage, IWorkerNotification workerNotification)
 {
     action.DynamicInvoke(receivedMessage, workerNotification);
 }
コード例 #30
0
 /// <summary>
 /// Handles the specified message.
 /// </summary>
 /// <param name="message">The message.</param>
 /// <param name="workerNotification">The worker notification.</param>
 /// <returns></returns>
 public Task HandleAsync(IReceivedMessageInternal message, IWorkerNotification workerNotification)
 {
     Guard.NotNull(() => message, message);
     Guard.NotNull(() => workerNotification, workerNotification);
     return(_messageHandlerRegistration.GetHandler().Invoke(_messageHandlerRegistration.GenerateMessage(message), workerNotification));
 }
コード例 #31
0
 /// <inheritdoc />
 public Task HandleAsync <T>(IWorkGroup workGroup, IReceivedMessage <T> message, IWorkerNotification notifications, Action <IReceivedMessage <T>, IWorkerNotification> functionToRun, ITaskFactory taskFactory) where T : class
 {
     using (var scope = _tracer.StartActivity("SchedulerMessageHandler"))
     {
         return(_handler.HandleAsync(workGroup, message, notifications, functionToRun, taskFactory));
     }
 }
コード例 #32
0
 /// <summary>
 /// Runs a compiled linq expression.
 /// </summary>
 /// <param name="action">The action.</param>
 /// <param name="receivedMessage">The received message.</param>
 /// <param name="workerNotification">The worker notification.</param>
 private void HandleAction(Action<IReceivedMessage<MessageExpression>, IWorkerNotification> action, IReceivedMessage<MessageExpression> receivedMessage, IWorkerNotification workerNotification)
 {
     action.DynamicInvoke(receivedMessage, workerNotification);
 }
コード例 #33
0
        /// <summary>
        /// Handles the specified message.
        /// </summary>
        /// <typeparam name="T">the type of the message.</typeparam>
        /// <param name="workGroup">The work group.</param>
        /// <param name="message">The message.</param>
        /// <param name="notifications">The notifications.</param>
        /// <param name="functionToRun">The function to run.</param>
        /// <param name="taskFactory">The task factory.</param>
        /// <returns></returns>
        public Task HandleAsync <T>(IWorkGroup workGroup, IReceivedMessage <T> message, IWorkerNotification notifications, Action <IReceivedMessage <T>, IWorkerNotification> functionToRun, ITaskFactory taskFactory)
            where T : class
        {
            Guard.NotNull(() => message, message);
            Guard.NotNull(() => notifications, notifications);
            Guard.NotNull(() => functionToRun, functionToRun);
            Guard.NotNull(() => taskFactory, taskFactory);

            while (true)
            {
                //verify that we are not canceling or stopping before trying to queue the item
                //however, the transport must support rollbacks
                if (!ShouldHandle(notifications))
                {
                    return(null);
                }

                if (taskFactory.TryStartNew(state => { WrappedFunction(message, notifications, functionToRun); }, new StateInformation(workGroup), task =>
                {
                    if (task.IsFaulted && task.Exception?.InnerException is OperationCanceledException)
                    {
                        //bubble the cancel exception; the queue will rollback the message if possible
                        throw new OperationCanceledException("user canceled", task.Exception.InnerException); //explicitly throw this
                    }

                    if (task.IsFaulted && task.Exception != null)
                    {
                        //need to throw it
                        throw new DotNetWorkQueueException("Message processing exception", task.Exception.InnerException);
                    }
                }, out var start).Success())
                {
                    try
                    {
                        return(start);
                    }
                    finally
                    {
                        //block here if the scheduler is full
                        try
                        {
                            _waitingOnFreeThreadCounter.Increment();
                            taskFactory.Scheduler.WaitForFreeThread.Wait(workGroup);
                        }
                        finally
                        {
                            _waitingOnFreeThreadCounter.Decrement();
                        }
                    }
                }

                //block if the scheduler is full
                try
                {
                    _waitingOnFreeThreadCounter.Increment();
                    taskFactory.Scheduler.WaitForFreeThread.Wait(workGroup);
                }
                finally
                {
                    _waitingOnFreeThreadCounter.Decrement();
                }
            }
        }
コード例 #34
0
 /// <summary>
 /// De-serializes and runs a compiled linq func expression.
 /// </summary>
 /// <param name="receivedMessage">The received message.</param>
 /// <param name="workerNotification">The worker notification.</param>
 private void HandleFunction(IReceivedMessage<MessageExpression> receivedMessage,
     IWorkerNotification workerNotification)
 {
     var target = _serializer.ConvertBytesToFunction(receivedMessage.Body.SerializedExpression);
     try
     {
         HandleFunction(target.Compile(), receivedMessage, workerNotification);
     }
     catch (Exception error) //throw the real exception if needed
     {
         if (error.Message == "Exception has been thrown by the target of an invocation." &&
             error.InnerException != null)
         {
             throw error.InnerException;
         }
         throw;
     }
 }
コード例 #35
0
        /// <summary>
        /// De-serializes and runs a compiled linq func expression.
        /// </summary>
        /// <param name="function">The function.</param>
        /// <param name="receivedMessage">The received message.</param>
        /// <param name="workerNotification">The worker notification.</param>
        private void HandleFunction(Func<IReceivedMessage<MessageExpression>, IWorkerNotification, object> function, IReceivedMessage<MessageExpression> receivedMessage, IWorkerNotification workerNotification)
        {
            var result = function.DynamicInvoke(receivedMessage, workerNotification);
            if (result == null) return;

            //if we have a connection, this is an rpc request
            var connection =
                receivedMessage.GetHeader(workerNotification.HeaderNames.StandardHeaders.RpcConnectionInfo);

            //if no connection, then this was not RPC
            if (connection == null) return;

            var timeOut =
                receivedMessage.GetHeader(workerNotification.HeaderNames.StandardHeaders.RpcTimeout).Timeout;

            //if we don't have an RPC queue for this queue, create one
            CreateRpcModuleIfNeeded(connection);

            //send the response
            var response =
                _rpcQueues[connection].Send(
                    result,
                    _rpcQueues[connection].CreateResponse(receivedMessage.MessageId, timeOut));

            if (response.HasError)
            {
                _log.ErrorException("Failed to send a response for message {0}", response.SendingException, receivedMessage.MessageId.Id.Value);
            }
        }
コード例 #36
0
        public static void HandleMessages(IReceivedMessage <SimpleMessage> arg1, IWorkerNotification arg2)
        {
            arg2.Log.LogInformation($"Processing message {arg1.MessageId.Id.Value.ToString()} - Processing time is {arg1.Body.ProcessingTime}");

            if (arg1.Body.Error == ErrorTypes.Error)
            {
                //simulate some processing
                System.Threading.Thread.Sleep(100);

                var i      = 9 - 9;
                var result = 100 / i;
                arg2.Log.LogInformation(result.ToString());
            }
            else if (arg1.Body.Error == ErrorTypes.RetryableErrorFail)
            {
                foreach (var error in arg1.PreviousErrors)
                {
                    arg2.Log.LogInformation($"previous error {error.Key}, count {error.Value}");
                }

                //simulate some processing
                System.Threading.Thread.Sleep(100);
                throw new InvalidDataException("the data is invalid. We will retry a few times and then give up because this error will happen over and over");
            }
            else if (arg1.Body.Error == ErrorTypes.RetryableError)
            {
                //simulate some processing
                System.Threading.Thread.Sleep(100);

                if (!RetryErrorCount.ContainsKey(arg1.MessageId.Id.Value.ToString()))
                {
                    RetryErrorCount.TryAdd(arg1.MessageId.Id.Value.ToString(), 1);
                    throw new InvalidDataException("the data is invalid");
                }
                else if (RetryErrorCount[arg1.MessageId.Id.Value.ToString()] > 2)
                {
                    //complete
                    foreach (var error in arg1.PreviousErrors)
                    {
                        arg2.Log.LogInformation($"previous error {error.Key}, count {error.Value}");
                    }
                }
                else
                {
                    RetryErrorCount[arg1.MessageId.Id.Value.ToString()] = RetryErrorCount[arg1.MessageId.Id.Value.ToString()] + 1;
                    foreach (var error in arg1.PreviousErrors)
                    {
                        arg2.Log.LogInformation($"previous error {error.Key}, count {error.Value}");
                    }
                    throw new InvalidDataException("the data is invalid");
                }
            }

            //allow canceling if the transport supports rolling back
            if (arg2.TransportSupportsRollback)
            {
                //NOTE - there are two tokens
                //Stop - the queue is asking you stop soon if possible. Eventually, the cancel token will be fired
                //Cancel - the queue is requesting that you stop ASAP
                //you can check either token or both
                //to check both, create a composite toke
                //https://docs.microsoft.com/en-us/dotnet/standard/threading/how-to-listen-for-multiple-cancellation-requests

                var canceled =
                    arg2.WorkerStopping.StopWorkToken.WaitHandle.WaitOne(
                        TimeSpan.FromMilliseconds(arg1.Body.ProcessingTime));

                if (canceled)
                {
                    throw new OperationCanceledException("We have been asked to stop working");           //force a requeue
                }
            }
            else
            {
                System.Threading.Thread.Sleep(arg1.Body.ProcessingTime);
            }

            arg2.Log.LogInformation($"Message {arg1.MessageId.Id.Value.ToString()} complete");
        }
コード例 #37
0
 public void HandleExecution(IReceivedMessage <MessageExpression> receivedMessage,
                             IWorkerNotification notification)
 {
     MethodIncrementWrapper.SetRollback(_queueId, (Guid)receivedMessage.CorrelationId.Id.Value);
     throw new OperationCanceledException("I don't feel like processing this message");
 }