private async Task DispatchErrorMessage(SqlConnection dbconnection, SSSBMessage message, ErrorMessage msgerr, CancellationToken token) { try { // для каждого типа сообщения можно добавить нестандартную обработку // которое не может быть обработано // например: сохранить тело сообщения в логе IMessageHandler <ErrorMessageEventArgs> errorMessageHandler; if (_errorMessageHandlers.TryGetValue(message.MessageType, out errorMessageHandler)) { using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled)) { ErrorMessageEventArgs errArgs = new ErrorMessageEventArgs(message, this._sssbService, msgerr.FirstError, token); errArgs = await errorMessageHandler.HandleMessage(this._sssbService, errArgs).ConfigureAwait(continueOnCapturedContext: false); transactionScope.Complete(); } } await _standardMessageHandlers.EndDialogMessageWithErrorHandler(dbconnection, message, msgerr.FirstError.Message, 4); string error = string.Format("Message {0} caused MAX Number of errors '{1}'. Dialog aborted!", message.MessageType, msgerr.FirstError.Message); _logger.LogError(error); } catch (Exception ex) { _logger.LogCritical(ErrorHelper.GetFullMessage(ex)); } }
public override async Task Execute(SqlConnection dbconnection, SSSBMessage message, CancellationToken token) { foreach (var handler in _resultHandlers) { await handler.Execute(dbconnection, message, token); } }
public ErrorMessageEventArgs(SSSBMessage message, ISSSBService svc, Exception processingException, CancellationToken cancellation) { this._message = message; this._service = svc; this._processingException = processingException; this._cancellation = cancellation; }
public ServiceMessageEventArgs(SSSBMessage message, ISSSBService svc, CancellationToken cancellation, IServiceScope serviceScope) { _message = message; _service = svc; _token = cancellation; _taskID = -1; _serviceScope = serviceScope; _tcs = new TaskCompletionSource <HandleMessageResult>(); _completion = _tcs.Task; _services = _serviceScope.ServiceProvider; }
public override async Task Execute(SqlConnection dbconnection, SSSBMessage message, CancellationToken token) { Guid conversationHandle = _conversationHandle.HasValue ? _conversationHandle.Value : message.ConversationHandle; if (!string.IsNullOrEmpty(_error)) { await _serviceBrokerHelper.EndConversationWithError(dbconnection, conversationHandle, _errorCode.HasValue?_errorCode.Value : 1, _error); } else { await _serviceBrokerHelper.EndConversation(dbconnection, conversationHandle); } }
protected virtual async Task HandleAsyncProcessingResult(SSSBMessage message, CancellationToken token, Task <HandleMessageResult> completionTask) { token.ThrowIfCancellationRequested(); var connectionManager = _services.GetRequiredService <IConnectionManager>(); using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.RequiresNew, TransactionScopeAsyncFlowOption.Enabled)) using (var dbconnection = await connectionManager.CreateSSSBConnectionAsync(token)) { await HandleSyncProcessingResult(dbconnection, message, token, completionTask); transactionScope.Complete(); } }
Task _HandleProcessingResult(SqlConnection dbconnection, SSSBMessage message, CancellationToken token, ServiceMessageEventArgs serviceArgs, bool isSync) { Task processTask = serviceArgs.Completion.ContinueWith(async(antecedent) => { try { if (isSync) { await this.HandleSyncProcessingResult(dbconnection, message, token, antecedent); } else { await this.HandleAsyncProcessingResult(message, token, antecedent); } } catch (OperationCanceledException) { // NOOP } catch (PPSException) { // Already Logged } catch (Exception ex) { _logger.LogError(ErrorHelper.GetFullMessage(ex)); } }, isSync? TaskContinuationOptions.ExecuteSynchronously: TaskContinuationOptions.None).Unwrap(); var disposeTask = processTask.ContinueWith((antecedent) => { try { serviceArgs.Dispose(); } catch (Exception ex) { _logger.LogError(ErrorHelper.GetFullMessage(ex)); } }, TaskContinuationOptions.ExecuteSynchronously); return(processTask); }
public override Task Execute(SqlConnection dbconnection, SSSBMessage message, CancellationToken token) { return Task.CompletedTask; }
public abstract Task Execute(SqlConnection dbconnection, SSSBMessage message, CancellationToken token);
public override Task Execute(SqlConnection dbconnection, SSSBMessage message, CancellationToken token) { Guid conversationHandle = _conversationHandle.HasValue ? _conversationHandle.Value : message.ConversationHandle; return(_standardMessageHandlers.SendEmptyMessage(dbconnection, conversationHandle)); }
public static XElement GetMessageXML(this SSSBMessage message) { return(GetMessageXML(message.Body)); }
public override Task Execute(SqlConnection dbconnection, SSSBMessage message, CancellationToken token) { return(_serviceBrokerHelper.SendPendingMessage(dbconnection, message, _fromService, _lifeTime, false, _activationTime, null, _attemptNumber)); }
private async Task <bool> _DispatchMessage(SqlConnection dbconnection, SSSBMessage message, CancellationToken token) { // возвратить ли сообщение назад в очередь? bool rollBack = false; IMessageHandler <ServiceMessageEventArgs> messageHandler; // if we registered custom handlers for predefined message types if (_messageHandlers.TryGetValue(message.MessageType, out messageHandler)) { ServiceMessageEventArgs serviceArgs = this.CreateServiceMessageEventArgs(message, token); try { bool isSync = true; Task processTask = Task.FromException(new Exception($"The message: {message.MessageType} ConversationHandle: {message.ConversationHandle} is not handled")); try { using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Suppress, TransactionScopeAsyncFlowOption.Enabled)) { serviceArgs = await messageHandler.HandleMessage(this._sssbService, serviceArgs).ConfigureAwait(continueOnCapturedContext: false); transactionScope.Complete(); } isSync = serviceArgs.Completion.IsCompleted; } catch (Exception handleEx) { if (!serviceArgs.TaskCompletionSource.TrySetException(handleEx)) { _logger.LogError(ErrorHelper.GetFullMessage(handleEx)); } } finally { processTask = this._HandleProcessingResult(dbconnection, message, token, serviceArgs, isSync); } if (isSync) { await processTask; } } catch (Exception ex) { if (!serviceArgs.TaskCompletionSource.TrySetException(ex)) { _logger.LogError(ErrorHelper.GetFullMessage(ex)); } } } else if (message.MessageType == SSSBMessage.EndDialogMessageType) { await _standardMessageHandlers.EndDialogMessageHandler(dbconnection, message); } else if (message.MessageType == SSSBMessage.ErrorMessageType) { await _standardMessageHandlers.ErrorMessageHandler(dbconnection, message); } else if (message.MessageType == SSSBMessage.EchoMessageType && message.ContractName == EchoContractName) { await _standardMessageHandlers.EchoMessageHandler(dbconnection, message); } else if (message.MessageType == SSSBMessage.PPS_EmptyMessageType) { await _standardMessageHandlers.EndDialogMessageHandler(dbconnection, message); } else if (message.MessageType == SSSBMessage.PPS_StepCompleteMessageType) { //just awake from sleep } else { throw new Exception(string.Format(ServiceBrokerResources.UnknownMessageTypeErrMsg, message.MessageType)); } return(rollBack); }
protected virtual ServiceMessageEventArgs CreateServiceMessageEventArgs(SSSBMessage message, CancellationToken cancellation) { ServiceMessageEventArgs args = new ServiceMessageEventArgs(message, this._sssbService, cancellation, _services.CreateScope()); return(args); }
async Task <MessageProcessingResult> IMessageDispatcher <SSSBMessage, SqlConnection> .DispatchMessage(SSSBMessage message, long taskId, CancellationToken token, SqlConnection dbconnection) { bool rollBack = false; ErrorMessage msgerr = null; bool end_dialog_with_error = false; // определяем сообщение по ConversationHandle // оканчивалась ли ранее обработка этого сообщения с ошибкой? msgerr = _sssbService.GetError(message.ConversationHandle); if (msgerr != null) { end_dialog_with_error = msgerr.ErrorCount >= MAX_MESSAGE_ERROR_COUNT; } if (end_dialog_with_error) { await this.DispatchErrorMessage(dbconnection, message, msgerr, token).ConfigureAwait(continueOnCapturedContext: false); } else { rollBack = await this._DispatchMessage(dbconnection, message, token).ConfigureAwait(continueOnCapturedContext: false); } return(new MessageProcessingResult() { isRollBack = rollBack }); }
protected virtual async Task HandleSyncProcessingResult(SqlConnection dbconnection, SSSBMessage message, CancellationToken token, Task <HandleMessageResult> completionTask) { HandleMessageResult handleMessageResult = null; try { handleMessageResult = await completionTask; await handleMessageResult.Execute(dbconnection, message, token); } catch (OperationCanceledException) { await _standardMessageHandlers.EndDialogMessageWithErrorHandler(dbconnection, message, $"Operation on Service: '{message.ServiceName}', MessageType: '{message.MessageType}', ConversationHandle: '{message.ConversationHandle}', is Cancelled", 1); } catch (PPSException ex) { await _standardMessageHandlers.EndDialogMessageWithErrorHandler(dbconnection, message, $"Operation on Service: '{message.ServiceName}', MessageType: '{message.MessageType}', ConversationHandle: '{message.ConversationHandle}', ended with Error: {ex.Message}", 2); } catch (Exception ex) { try { _logger.LogError(new EventId(0, message.ServiceName), ErrorHelper.GetFullMessage(ex)); } finally { await _standardMessageHandlers.EndDialogMessageWithErrorHandler(dbconnection, message, $"Operation on Service: '{message.ServiceName}', MessageType: '{message.MessageType}', ConversationHandle: '{message.ConversationHandle}', ended with Error: {ex.Message}", 3); } } }