/// <summary> /// 执行该队列下所有任务 /// </summary> private void Executing(TaskschedNode task) { if (task.FinishTime.HasValue || task.Status != TaskschedStatus.Working) { return; } /*还没开始工作*/ if (task.NextTime.HasValue && task.NextTime.Value > DateTime.Now) { return; } if (task.PushMessage.IsNullOrEmpty()) { task.FinishTime = task.FinishTime.HasValue ? task.FinishTime.Value : DateTime.Now; task.Status = TaskschedStatus.Finish; this.executingRepository.Finish(task); return; } var nodes = this.executingRepository.GetAll(task.TaskId); if (nodes == null || nodes.Count() == 0) { task.FinishTime = task.FinishTime.HasValue ? task.FinishTime.Value : DateTime.Now; task.Status = TaskschedStatus.Finish; this.executingRepository.Finish(task); return; } /*准备好工作了*/ var context = new WorkContext() { TaskId = task.TaskId, TaskschedNode = task, JsonSerializer = this.engine.JsonSerializer, Strategy = this.engine.Strategy, }; var list = new List<ExecutingNode>(nodes.Length + 2); list.Add(new ExecutingNode { ResultMessage = task.PushMessage, StepCount = nodes.Length + 2, StartTime = DateTime.Now, StepCoordinationMode = CoordinationMode.Any, WaitTimes = 0, FailTimes = 0, FinishTime = DateTime.Now, OrderNo = 0, RowId = Guid.Empty, StepType = "aa1b00b7cf4e", TaskId = task.TaskId, ExecutingMessage = string.Empty, }); list.AddRange(nodes.OrderBy(ta => ta.OrderNo)); list.Add(new ExecutingNode { ResultMessage = task.PushMessage, StepCount = nodes.Length + 2, StartTime = DateTime.Now, StepCoordinationMode = CoordinationMode.Any, WaitTimes = 0, FailTimes = 0, FinishTime = DateTime.Now, OrderNo = nodes.Length + 1, RowId = Guid.Empty, StepType = "aa1b00b7d77f", TaskId = task.TaskId, ExecutingMessage = string.Empty, }); nodes = list.ToArray(); foreach (var node in nodes) { context.ExecutingNode = null; /*第一步*/ if (node.OrderNo == 0) { continue; } if (node.FinishTime.HasValue) { continue; } /*最后一步,应该要当完成*/ if (node.OrderNo == task.StepCount + 1 || task.FinishTime.HasValue) { task.FinishTime = task.FinishTime.HasValue ? task.FinishTime.Value : DateTime.Now; task.Status = TaskschedStatus.Finish; this.executingRepository.Finish(task); return; } var worksteps = new List<KeyValueTuple<IWorkStep, string>>(node.StepCount); var preMsg = default(IWorkStepMessage); try { if (!this.IsReady(this.engine.Strategy, task, nodes, node, worksteps, out preMsg)) { return; } } catch (Exception ex) { node.ExecutingMessage = ex.GetInnerException().GetFullMessage(); node.FailTimes++; var timeSpan = this.engine.Strategy.NextTime(task, node, ex); if (timeSpan != TimeSpan.Zero) { task.NextTime = task.NextTime.HasValue ? task.NextTime.Value.Add(timeSpan) : DateTime.Now.Add(timeSpan); this.executingRepository.Exception(task, node); return; } } context.RowId = node.RowId; context.ExecutingNode = node; if (preMsg is IWorkStepMessageValidator) { try { ((IWorkStepMessageValidator)preMsg).Validate(context); if (!context.ParamaterResult.IsValid) { var sb = new StringBuilder(200); foreach (var error in context.ParamaterResult.Errors) { sb.AppendFormat("the {0} step has error: paramater key is : {1} ,validate result is {2};", node.OrderNo, error.MemberName, error.ErrorMessage); } var finishNodes = new List<ExecutingNode>(nodes.Count()); foreach (var t in nodes.Where(t => t.OrderNo >= node.OrderNo)) { if (t.OrderNo == 0 || t.OrderNo == nodes.Length - 1) { continue; } t.ExecutingMessage = sb.ToString(); finishNodes.Add(t); } this.executingRepository.Abort(task, finishNodes.ToArray()); return; } } catch (Exception ex) { /*这里的导演应该是本引擎执行的异常了,因工作步骤的异常都会记录到每次的任务中*/ this.ResolveLoggerBuilder().Build(typeof(TaskschedEngine)).Error("验证消息参数出错", ex); } } try { switch (node.StepCoordinationMode) { default: case CoordinationMode.Any: { if (this.ExecuteAny(this.engine.Strategy, task, nodes, node, worksteps, context, preMsg)) { continue; } return; } case CoordinationMode.Meanwhile: { if (this.ExecuteMeanwhile(this.engine.Strategy, task, nodes, node, worksteps, context, preMsg)) { continue; } return; } } } catch (Exception ex) { /*这里的导演应该是本引擎执行的异常了,因工作步骤的异常都会记录到每次的任务中*/ this.ResolveLoggerBuilder().Build(typeof(TaskschedEngine)).Error("执行本地储存更新失败", ex); } } }
public static void MySetId<TWorkStepMessage>(IWorkStepMessage message, TaskschedNode task) { SetTaskId<TWorkStepMessage>.Register().Invoke((TWorkStepMessage)message, task.TaskId); }
/// <summary> /// 开始工作 /// </summary> private bool ExecuteMeanwhile(ITaskschedStrategy strategy, TaskschedNode task, ExecutingNode[] nodes, ExecutingNode node, IList<KeyValueTuple<IWorkStep, string>> worksteps, WorkContext context, IWorkStepMessage preMsg) { var finishNodes = new List<ExecutingNode>(nodes.Count()); var messages = new MeanwhileWorkStepMessage(); var msgs = new List<IWorkStepMessage>(nodes.Count()); messages.TaskId = task.TaskId; IWorkStepMessage msg = null; var timeSpan = TimeSpan.Zero; Exception lastException = null; foreach (var workstep in worksteps) { try { msg = workstep.Key.Execute(context, preMsg); if (msg != null) { task.AttachState = msg.AttachState; } } catch (Exception ex) { lastException = ex; node.ExecutingMessage = ex.GetInnerException().GetFullMessage(); node.FailTimes++; timeSpan = strategy.NextTime(task, node, ex); } if (msg is EmptyAndAbortedWorkStepMessage) { foreach (var t in nodes.Where(t => t.OrderNo >= node.OrderNo)) { if (t.OrderNo == 0 || t.OrderNo == nodes.Length - 1) { continue; } t.ExecutingMessage = string.Format("当前步骤{0}执行了中断行为,消息结果为:{1}", node.OrderNo, ((EmptyAndAbortedWorkStepMessage)msg).Message); finishNodes.Add(t); } this.executingRepository.Abort(task, finishNodes.ToArray()); if (this.MessagePublisher != null) { try { this.MessagePublisher.PublishMessageAsync(msg); } catch { } } return false; } if (msg is EmptyButWaitingWorkStepMessage) { var span = strategy.NextWorkTimeOnMessageIsWaiting(task, node); node.ExecutingMessage = ((EmptyButWaitingWorkStepMessage)msg).Message; task.NextTime = task.NextTime.HasValue ? task.NextTime.Value.Add(span) : DateTime.Now.Add(span); this.executingRepository.NextWork(task, node); if (this.MessagePublisher != null) { try { this.MessagePublisher.PublishMessageAsync(msg); } catch { } } return false; } if (lastException != null && this.MessagePublisher != null) { try { this.MessagePublisher.PublishMessageAsync(new ExecutingErrorWorkStepMessage() { TaskId = task.TaskId, CommandType = task.CommandType, UserSign = task.UserSign, Exception = lastException, PushMessage = task.PushMessage }); } finally { } } if (timeSpan != TimeSpan.Zero) { task.NextTime = task.NextTime.HasValue ? task.NextTime.Value.Add(timeSpan) : DateTime.Now.Add(timeSpan); this.executingRepository.Exception(task, node); return false; } if (msg == null) { timeSpan = strategy.NextWorkTimeOnMessageIsNull(task, node, node.WaitTimes + 1); if (timeSpan != TimeSpan.Zero) { node.WaitTimes++; task.NextTime = task.NextTime.HasValue ? task.NextTime.Value.Add(timeSpan) : DateTime.Now.Add(timeSpan); this.executingRepository.NextWork(task, node); return false; } foreach (var t in nodes.Where(t => t.OrderNo >= node.OrderNo)) { if (t.OrderNo == 0 || t.OrderNo == nodes.Length - 1) { continue; } t.ExecutingMessage = string.Format("当前步骤{0}协同方式为全部,但工作实例{1}返回空消息,执行中断", node.OrderNo, workstep.Value); finishNodes.Add(t); } this.executingRepository.Abort(task, finishNodes.ToArray()); return false; } if (msg.TaskId == Guid.Empty) { this.SetMessageTaskId(msg, task); } msgs.Add(msg); messages.Messages.Add(this.engine.JsonSerializer.Serialize(new Never.Messages.MessagePacket() { ContentType = Never.Messages.MessagePacket.GetContentType(msg), Body = this.engine.JsonSerializer.Serialize(msg) })); } var mulitePacket = new Never.Messages.MessagePacket() { ContentType = Never.Messages.MessagePacket.GetContentType(messages), Body = this.engine.JsonSerializer.Serialize(messages), }; context.StepClear(); node.ResultMessage = this.engine.JsonSerializer.Serialize(mulitePacket); node.FinishTime = DateTime.Now; task.ProcessPercent = task.StepCount <= 0 ? 100m : ((100 * (task.NextStep) / ((decimal)task.StepCount)).FormatR(2)); if (task.NextStep == task.StepCount) { task.FinishTime = DateTime.Now; this.executingRepository.AllDone(task, node); } else { task.NextStep = task.NextStep + 1; this.executingRepository.Done(task, node); } if (this.MessagePublisher != null) { try { foreach (var m in msgs) { this.MessagePublisher.PublishMessageAsync(m); } } catch { } } return true; }
/// <summary> /// /// </summary> /// <typeparam name="TWorkStepMessage"></typeparam> /// <param name="message"></param> /// <param name="task"></param> private void SetMessageTaskId<TWorkStepMessage>(TWorkStepMessage message, TaskschedNode task) where TWorkStepMessage : IWorkStepMessage { SetTaskId.SetId(message, task); }
/// <summary> /// 检查工作 /// </summary> /// <param name="strategy"></param> /// <param name="task"></param> /// <param name="nodes"></param> /// <param name="node"></param> /// <param name="worksteps"></param> /// <param name="preMsg"></param> /// <returns></returns> private bool IsReady(ITaskschedStrategy strategy, TaskschedNode task, ExecutingNode[] nodes, ExecutingNode node, IList<KeyValueTuple<IWorkStep, string>> worksteps, out IWorkStepMessage preMsg) { preMsg = null; /*获取前一个节点信息*/ var preNode = nodes.FirstOrDefault(o => o.OrderNo == node.OrderNo - 1); var finishNodes = new List<ExecutingNode>(nodes.Count()); if (preNode == null) { foreach (var t in nodes.Where(t => t.OrderNo >= node.OrderNo)) { if (t.OrderNo == 0 || t.OrderNo == nodes.Length - 1) { continue; } t.ExecutingMessage = string.Format("当前步骤{0}找不到上一步{1}信息,执行中断", node.OrderNo, node.OrderNo - 1); finishNodes.Add(t); } this.executingRepository.Abort(task, finishNodes.ToArray()); return false; } var prePacket = this.engine.JsonSerializer.Deserialize<Never.Messages.MessagePacket>(preNode.ResultMessage); if (prePacket == null) { foreach (var t in nodes.Where(t => t.OrderNo >= node.OrderNo)) { if (t.OrderNo == 0 || t.OrderNo == nodes.Length - 1) { continue; } t.ExecutingMessage = string.Format("当前步骤{0}消息类型不是Never.Messages.MessagePacket,执行中断", node.OrderNo); finishNodes.Add(t); } this.executingRepository.Abort(task, finishNodes.ToArray()); return false; } var preMsgType = Type.GetType(prePacket.ContentType); if (preMsgType == null) { foreach (var t in nodes.Where(t => t.OrderNo >= node.OrderNo)) { if (t.OrderNo == 0 || t.OrderNo == nodes.Length - 1) { continue; } t.ExecutingMessage = string.Format("当前步骤{0}消息类型{1}不能在当前环境中找到类型,执行中断", node.OrderNo, prePacket.ContentType); finishNodes.Add(t); } this.executingRepository.Abort(task, finishNodes.ToArray()); return false; } preMsg = this.engine.JsonSerializer.DeserializeObject(prePacket.Body, preMsgType) as IWorkStepMessage; if (preMsgType == typeof(MeanwhileWorkStepMessage)) { var multiplemsg = new MultipleWorkStepMessage(); multiplemsg.TaskId = ((MeanwhileWorkStepMessage)preMsg).TaskId; foreach (var msg in ((MeanwhileWorkStepMessage)preMsg).Messages) { var pck = this.engine.JsonSerializer.Deserialize<Never.Messages.MessagePacket>(msg); var pmsg = this.engine.JsonSerializer.DeserializeObject(pck.Body, Type.GetType(pck.ContentType)) as IWorkStepMessage; multiplemsg.Append(pmsg); } } if (preMsg == null) { foreach (var t in nodes.Where(t => t.OrderNo >= node.OrderNo)) { if (t.OrderNo == 0 || t.OrderNo == nodes.Length - 1) { continue; } t.ExecutingMessage = string.Format("当前步骤{0}消息类型{1}不是指定的IWorkStepMessage消息,执行中断", node.OrderNo, prePacket.ContentType); finishNodes.Add(t); } this.executingRepository.Abort(task, finishNodes.ToArray()); return false; } var stepTypes = node.StepType.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); string nullStepType = string.Empty; /*fix guid*/ foreach (var step in stepTypes) { var stepType = TemplateWorkStep.Find(step); if (stepType != null) { if (ContainerContext.Current == null) { var workstep = Activator.CreateInstance(stepType) as IWorkStep; worksteps.Add(new KeyValueTuple<IWorkStep, string>(workstep, step)); } else { var workstep = ContainerContext.Current.ServiceLocator.Resolve(stepType) as IWorkStep; worksteps.Add(new KeyValueTuple<IWorkStep, string>(workstep, step)); } } else { nullStepType = step; worksteps.Add(new KeyValueTuple<IWorkStep, string>(null, step)); } } if (worksteps.All(o => o.Key == null)) { foreach (var t in nodes.Where(t => t.OrderNo >= node.OrderNo)) { if (t.OrderNo == 0 || t.OrderNo == nodes.Length - 1) { continue; } t.ExecutingMessage = string.Format("当前步骤{0}所有工作实例不能在当前环境中实例化,执行中断", node.OrderNo); finishNodes.Add(t); } this.executingRepository.Abort(task, finishNodes.ToArray()); return false; } if (node.StepCoordinationMode == CoordinationMode.Meanwhile && nullStepType.IsNotNullOrEmpty()) { foreach (var t in nodes.Where(t => t.OrderNo >= node.OrderNo)) { if (t.OrderNo == 0 || t.OrderNo == nodes.Length - 1) { continue; } t.ExecutingMessage = string.Format("当前步骤{0}工作实例{1}不能在当前环境中找到类型,执行中断", node.OrderNo, nullStepType); finishNodes.Add(t); } this.executingRepository.Abort(task, finishNodes.ToArray()); return false; } return true; }