private async Task <ActivityExecuteResult> RecursiveExecuteActivity(ActivityWapper activityWapper) { var activityId = snowflakeIdGenerator.NextId(); activityWapper.Id = activityId; activityWapper.CancellationTokenSource = new System.Threading.CancellationTokenSource(activityWapper.TimeOutSeconds * 1000); try { var content = serializer.Serialize(activityWapper.DataObj, activityWapper.ActivityDataType); activityWapper.ActivityStatus = ActivityStatus.Executing; await eventSender.ActivityExecuting(activityId, activityWapper.Name, Id, content, activityWapper.Order, DateTime.UtcNow); var result = await activityWapper.InvokeExecute(); if (!result.IsSuccess) { activityWapper.ActivityStatus = ActivityStatus.Revoked; await eventSender.ActivityRevoked(activityId); await CompensateActivity(result, currentExecuteOrder); var expiresAt = DateTime.UtcNow.AddSeconds(poleSagasOption.CompeletedSagaExpiredAfterSeconds); await eventSender.SagaEnded(Id, expiresAt); return(result); } activityWapper.ActivityStatus = ActivityStatus.Executed; var executeActivity = GetNextExecuteActivity(); if (executeActivity == null) { var expiresAt = DateTime.UtcNow.AddSeconds(poleSagasOption.CompeletedSagaExpiredAfterSeconds); await eventSender.SagaEnded(Id, expiresAt); return(result); } else { return(await RecursiveExecuteActivity(executeActivity)); } } catch (Exception exception) { if (activityWapper.CancellationTokenSource.Token.IsCancellationRequested) { var errors = exception.InnerException != null ? exception.InnerException.Message + exception.StackTrace : exception.Message + exception.StackTrace; var result = new ActivityExecuteResult { IsSuccess = false, Errors = errors }; var bytesContent = serializer.SerializeToUtf8Bytes(activityWapper.DataObj, activityWapper.ActivityDataType); activityWapper.ActivityStatus = ActivityStatus.ExecutingOvertime; await eventSender.ActivityExecuteOvertime(activityId); // 超时的时候 需要首先补偿这个超时的操作 return(await CompensateActivity(result, currentExecuteOrder + 1)); } else { var errors = exception.InnerException != null ? exception.InnerException.Message + exception.StackTrace : exception.Message + exception.StackTrace; var result = new ActivityExecuteResult { IsSuccess = false, Errors = errors }; activityWapper.ActivityStatus = ActivityStatus.ExecuteAborted; await eventSender.ActivityExecuteAborted(activityId); // 出错的时候 需要首先补偿这个出错的操作 var executeResult = await CompensateActivity(result, currentExecuteOrder + 1); var expiresAt = DateTime.UtcNow.AddSeconds(poleSagasOption.CompeletedSagaExpiredAfterSeconds); if (IsCompensated) { await eventSender.SagaEnded(Id, expiresAt); } return(executeResult); } } }