Exemplo n.º 1
0
        /// <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);
                }
            }
        }
Exemplo n.º 2
0
 public static void MySetId<TWorkStepMessage>(IWorkStepMessage message, TaskschedNode task)
 {
     SetTaskId<TWorkStepMessage>.Register().Invoke((TWorkStepMessage)message, task.TaskId);
 }
Exemplo n.º 3
0
        /// <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;
        }
Exemplo n.º 4
0
 /// <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);
 }
Exemplo n.º 5
0
        /// <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;
        }