/// <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); } }
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}"); }
/// <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); } }
/// <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); } }
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}"); } }
/// <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"); } }
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"); } }
/// <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); } }
/// <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); } }
/// <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); } }
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()); }
/// <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); } }
/// <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; } }
/// <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); }
/// <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)); }
/// <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); } } }
/// <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; } }
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(); } }
/// <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); } } }
/// <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); }
/// <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); }
/// <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)); } }
/// <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); } } }
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}"); } }
/// <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); }
/// <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); } }
/// <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"); } }
/// <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); }
/// <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)); }
/// <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)); } }
/// <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); }
/// <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(); } } }
/// <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; } }
/// <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); } }
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"); }
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"); }