protected override AsyncHandlerResult InternalExecute(AsyncEvent asyncEvent) { try { this.Init(); this.DoWork(); } catch (Exception exception) { // 异步作业不允许抛异常,只记录日志。 MyTrace.Write(ESB_TraceCategory.DataDistribution, TraceLevel.Error, "分发日志到业务系统时出现未捕获的异常,异常信息为【{0}】", exception.ToString()); } return new AsyncSucceededResult(); }
/// <summary> /// Executes the specified asynchronous event. /// </summary> /// <param name="asyncEvent">The asynchronous event.</param> /// <returns></returns> public AsyncHandlerResult Execute(AsyncEvent asyncEvent) { AsyncHandlerResult result = null; try { MyTrace.Write(TraceCategory.AsyncService, TraceLevel.Info, "正在执行异步作业。AsyncOperationId: {0} AsyncOperationType: {1} Command: {2}", asyncEvent.EventId, asyncEvent.OperationType, GetType().FullName); result = this.InternalExecute(asyncEvent); } catch (System.Exception ex) { MyTrace.Write(TraceCategory.AsyncService, TraceLevel.Error, "执行异步作业时遭遇异常。AsyncOperationId: {0} AsyncOperationType: {1} - {2}", asyncEvent.EventId, asyncEvent.OperationType, ex); throw; } return result; }
/// <summary> /// Tracks the begin outstanding operation. /// </summary> /// <param name="asyncEvent">The asynchronous event.</param> internal void TrackBeginOutstandingOperation(AsyncEvent asyncEvent) { lock (_outstandingOperations) { _outstandingOperations.Add(asyncEvent); Counters.TrackBeginOutstandingOperation(asyncEvent.OperationType); } }
/// <summary> /// Tracks the begin executing operation. /// </summary> /// <param name="asyncEvent">The asynchronous event.</param> internal void TrackBeginExecutingOperation(AsyncEvent asyncEvent) { lock (_executingOperations) { _executingOperations.Add(asyncEvent); if (Counters != null) { Counters.TrackBeginExecutingOperation(asyncEvent.OperationType); asyncEvent.BeginAsynchronousEventProcessing(); } } }
/// <summary> /// Sets the pause and exit request. /// </summary> /// <param name="asyncEvent">The asynchronous event.</param> internal void SetPauseAndExitRequest(AsyncEvent asyncEvent) { if (TryGetEventId(asyncEvent.EventId) == AsyncHandlerEarlyExitRequest.Continue) { SetEventState(asyncEvent.EventId, AsyncHandlerEarlyExitRequest.Pause); asyncEvent.AutoResumeFromPause = true; } }
/// <summary> /// Handles the special transition. /// </summary> /// <param name="asyncEvent">The asynchronous event.</param> /// <returns></returns> internal AsyncHandlerResult HandleSpecialTransition(AsyncEvent asyncEvent) { AsyncHandlerEarlyExitRequest asyncHandlerEarlyExitRequest = QueryForEarlyExitRequest(asyncEvent.EventId); if (asyncHandlerEarlyExitRequest != AsyncHandlerEarlyExitRequest.Continue) { return DoSpecialTransition(asyncEvent.EventId, asyncHandlerEarlyExitRequest, true, asyncEvent.AutoResumeFromPause, _dataAccessFactory.CreateInstance(this, Configuration.OrganizationConfiguration), asyncEvent.ExecutionTimeSeconds); } return null; }
/// <summary> /// Nexts the occurrence. /// </summary> /// <param name="asyncEvent">The asynchronous event.</param> /// <returns></returns> public DateTime NextOccurrence(AsyncEvent asyncEvent) { if (asyncEvent.RecurrenceEndTime.HasValue && asyncEvent.RecurrenceEndTime <= DateTime.Now) { return DateTime.MinValue; } try { return RecurrencePatternFactory.NextOccurrence(asyncEvent.RecurrencePattern, asyncEvent.RecurrenceStartTime); } catch (InvalidRecurrenceRuleException e) { MyTrace.Write(TraceCategory.AsyncService, TraceLevel.Error, "{0}: 作业{1}的重复规则错误。{2}", InstanceName, asyncEvent.EventId, e.Message); EventLog.WriteEntry(EventLogEntryType.Error, 0, e.Message); } return DateTime.MinValue; }
/// <summary> /// Internals the execute. /// 注意:如果方法体内抛出非WebException、TargetInvocationException、SqlException、SoapException、MyException、FaultException、 /// InvalidPluginExecutionException、TimeoutException、CommunicationException、EndpointNotFoundException类型,将会导致服务崩溃 /// </summary> /// <param name="asyncEvent">The asynchronous event.</param> /// <returns></returns> protected abstract AsyncHandlerResult InternalExecute(AsyncEvent asyncEvent);
/// <summary> /// Determines whether this instance [can clear data] the specified new state. /// </summary> /// <param name="newState">The new state.</param> /// <param name="asyncEvent">The asynchronous event.</param> /// <returns></returns> private bool CanClearData(int newState, AsyncEvent asyncEvent) { return newState == 3; }
/// <summary> /// Updates the state of the event. /// </summary> /// <param name="asyncEvent">The asynchronous event.</param> /// <param name="result">The result.</param> private void UpdateEventState(AsyncEvent asyncEvent, AsyncHandlerResult result) { var instance = this._dataAccessFactory.CreateInstance(this, Configuration.OrganizationConfiguration); var newStatus = result.ResultCode; int newState = 3; int errorCode = 0; string errorMessage = null; string friendlyMessage = null; bool retryOperation = false; var handlerResultWithError = result as AsyncHandlerResultWithError; if (handlerResultWithError != null) { errorCode = handlerResultWithError.ErrorCode; errorMessage = handlerResultWithError.ErrorMessage; friendlyMessage = handlerResultWithError.FriendlyMessage; } else { var resultWithMessage = result as AsyncHandlerResultWithMessage; if (resultWithMessage != null) friendlyMessage = resultWithMessage.Message; } var nextOccurrence = DateTime.MinValue; if (result is AsyncRetryResult) { if (asyncEvent.RetryCount < this.Configuration.MaximumRetries || errorCode == -2147180543) // -2147180543 = The server is busy and the request was not completed. Try again later. { retryOperation = true; } else { nextOccurrence = DateTime.MaxValue; LogEvent(EventLogEntryType.Error, 3221242897L, Environment.MachineName, asyncEvent.OperationType, errorCode.ToString("x", (IFormatProvider)CultureInfo.InvariantCulture), errorMessage); } } var asyncPausedResult = result as AsyncPausedResult; if (asyncPausedResult != null && asyncPausedResult.PostponeUntil != DateTime.MinValue) nextOccurrence = asyncPausedResult.PostponeUntil; switch (newStatus) { case 20: return; case 21: case 10: if (retryOperation && this.HandleSpecialTransition(asyncEvent) != null) return; newState = 1; newStatus = 10; break; case 22: case 32: newState = 3; newStatus = 32; break; case 0: AsyncServiceException.Assert(false, "错误状态: " + newStatus); break; } if (result is AsyncSystemPausedResult) nextOccurrence = DateTime.MaxValue; if (asyncEvent.IsRecurrenceEvent) { nextOccurrence = NextOccurrence(asyncEvent); if (nextOccurrence == DateTime.MinValue) { newState = 3; newStatus = 30; } else { newState = 1; newStatus = 10; } } if (newState == 1 && newStatus == 10 && asyncEvent.AutoResumeFromPause) nextOccurrence = DateTime.Now.AddMinutes(1.0); var newEventState = new AsyncEventState() { EventId = asyncEvent.EventId, NewState = newState, NewStatus = newStatus, NextOccurrence = nextOccurrence, RetryOperation = retryOperation, CurrentRetryCount = asyncEvent.RetryCount, ErrorCode = errorCode, ErrorMessage = errorMessage, FriendlyMessage = friendlyMessage, ClearData = this.CanClearData(newState, asyncEvent), ExecutionTime = asyncEvent.ExecutionTimeSeconds, CanRemoveEvent = this.CanRemoveEvent(asyncEvent, result), HandlerResult = result }; instance.UpdateStateAndStatus(newEventState); RemoveSpecialTransition(asyncEvent.EventId); }
/// <summary> /// Processes the asynchronous event. /// </summary> /// <param name="eventData">The event data.</param> /// <returns></returns> public AsyncHandlerResult ProcessAsyncEvent(AsyncEvent eventData) { AsyncServiceException.Assert(eventData != null, "异步服务池处理器只能处理异步事件。"); if (_queueManager.ShuttingDown) { _queueManager.TrackCompleteOutstandingOperation(eventData, null, false); return null; } MyTrace.Write(TraceCategory.AsyncService, TraceLevel.Info, "正在处理异步作业。Id: {0} 作业类型: {1}", eventData.EventId, eventData.OperationType); var result = _queueManager.HandleSpecialTransition(eventData); if (result != null) { _queueManager.TrackCompleteOutstandingOperation(eventData, result, false); } else { SemaphoreSlim semaphoreSlim = null; bool hasDone = false; if ( _queueManager.Configuration.OperationTypeThrottle.TryGetValue(eventData.OperationType, out semaphoreSlim) && !semaphoreSlim.Wait(0)) { var failure = new AsyncFailedResult(new AsyncServiceException("服务正忙且请求未被完成,请稍后重试。")) { FriendlyMessage = "服务正忙且请求未被完成,请稍后重试。" }; result = new AsyncRetryResult(failure); hasDone = true; } if (!hasDone) _queueManager.TrackBeginExecutingOperation(eventData); if (_queueManager.ShuttingDown) { _queueManager.TrackCompleteOutstandingOperation(eventData, result, false); return result; } try { if (!hasDone) result = _handler(eventData); } catch (Exception ex) { ErrorAction action = _errorHandler.Handle(ex); AsyncServiceException.Assert(action != null, "错误处理后的动作不应为null。"); string errorFormat = action.ErrorMessage == null ? string.Empty : action.ErrorMessage; result = new AsyncFailedResult(ex, action.ErrorCode, errorFormat); switch (action.Type) { case ErrorActionType.Retry: result = new AsyncRetryResult((AsyncFailedResult) result); break; case ErrorActionType.Fail: break; case ErrorActionType.Suspend: if (action.ErrorCode == -2147204743) { result = new AsyncPausedResult(DateTime.Now.AddMinutes(0)); break; } else { result = new AsyncSystemPausedResult(action.ErrorCode, "{0}", action.ErrorMessage); break; } default: result = new AsyncSystemPausedResult(ex); throw; } } finally { EndAsynchronousEventProcessing(eventData, result); } } return result; }
/// <summary> /// Events the handler. /// </summary> /// <param name="asyncEvent">The asynchronous event.</param> public void EventHandler(AsyncEvent asyncEvent) { _queueManager.TrackBeginOutstandingOperation(asyncEvent); _executionEngine.Enqueue(_queueManager.OperationsFactory.CreateAsyncEventOperation(asyncEvent, this)); }
/// <summary> /// Ends the asynchronous event processing. /// </summary> /// <param name="asyncEvent">The asynchronous event.</param> /// <param name="result">The result.</param> internal void EndAsynchronousEventProcessing(AsyncEvent asyncEvent, AsyncHandlerResult result) { _queueManager.EndAsynchronousEventProcessing(asyncEvent, result); }
/// <summary> /// Handles the specified asynchronous event. /// </summary> /// <param name="asyncEvent">The asynchronous event.</param> /// <returns></returns> public AsyncHandlerResult Handle(AsyncEvent asyncEvent) { AsyncOperationCommand operationCommand = this._operationFactory.GetOperationCommand(asyncEvent); return operationCommand.Execute(asyncEvent); }
/// <summary> /// Tracks the complete executing operation. /// </summary> /// <param name="asyncEvent">The asynchronous event.</param> /// <param name="result">The result.</param> internal void TrackCompleteExecutingOperation(AsyncEvent asyncEvent, AsyncHandlerResult result) { lock (_executingOperations) { if (result is AsyncInProgressResult) return; if (_executingOperations.Remove(asyncEvent)) { Counters.TrackCompleteExecutingOperation(asyncEvent.OperationType); SemaphoreSlim semaphoreSlim = null; if (Configuration.OperationTypeThrottle.TryGetValue(asyncEvent.OperationType, out semaphoreSlim)) { semaphoreSlim.Release(); } } if (_shutdownEvent != null && _executingOperations.Count == 0) { _shutdownEvent.Set(); } } }
/// <summary> /// Tracks the complete outstanding operation. /// </summary> /// <param name="asyncEvent">The asynchronous event.</param> /// <param name="result">The result.</param> /// <param name="executionStarted">if set to <c>true</c> [execution started].</param> internal void TrackCompleteOutstandingOperation(AsyncEvent asyncEvent, AsyncHandlerResult result, bool executionStarted) { lock (_outstandingOperations) { if (result is AsyncInProgressResult) return; if (!_outstandingOperations.Remove(asyncEvent)) return; Counters.TrackCompleteOutstandingOperation(asyncEvent.OperationType, result, asyncEvent.ExecutionTime); if (executionStarted) { _startThreadHandler(); } } }
/// <summary> /// Creates the one operation from recurrence pattern. /// </summary> /// <param name="asyncEvent">The asynchronous event.</param> public void CreateOneOperationFromRecurrencePattern(AsyncEvent asyncEvent) { var queueDataAccess = _dataAccessFactory.CreateInstance(this, Configuration.OrganizationConfiguration); queueDataAccess.CreateOneOperationFromRecurrencePattern(asyncEvent); }
/// <summary> /// Determines whether this instance [can remove event] the specified asynchronous event. /// </summary> /// <param name="asyncEvent">The asynchronous event.</param> /// <param name="result">The result.</param> /// <returns></returns> private bool CanRemoveEvent(AsyncEvent asyncEvent, AsyncHandlerResult result) { var asyncRemoveEventResult = result as AsyncRemoveEventResult; return asyncRemoveEventResult != null; }
/// <summary> /// Ends the asynchronous event processing. /// </summary> /// <param name="asyncEvent">The asynchronous event.</param> /// <param name="result">The result.</param> public void EndAsynchronousEventProcessing(AsyncEvent asyncEvent, AsyncHandlerResult result) { UpdateEventState(asyncEvent, result); TrackCompleteExecutingOperation(asyncEvent, result); TrackCompleteOutstandingOperation(asyncEvent, result, true); }