Esempio n. 1
0
        public object OperateTask(string taskCode, int operation)
        {
            var     db   = Repository.GetDbContext();
            DmeTask task = db.Queryable <DmeTask>().Single(t => t.SysCode == taskCode);

            if (null == task)
            {
                throw new BusinessException((int)EnumSystemStatusCode.DME_FAIL, $"任务[{taskCode}]不存在");
            }
            DmeModel model = db.Queryable <DmeModel>().InSingle(task.ModelId);

            switch (operation)
            {
            case 0:
                LOG.Info($"停止任务[{taskCode}]");
                task.Status   = EnumUtil.GetEnumDisplayName(EnumSystemStatusCode.DME_STOP);
                task.LastTime = DateUtil.CurrentTimeMillis;
                db.Updateable <DmeTask>(task).UpdateColumns(t => new { task.Status, task.LastTime }).ExecuteCommand();
                DmeQuartzScheduler <TaskRunnerJob> .PauseJob(task.SysCode, model.ModelTypeCode);

                break;

            case 1:
                // @TODO 有待完成
                LOG.Info($"重启任务[{taskCode}]");
                task.Status   = EnumUtil.GetEnumDisplayName(EnumSystemStatusCode.DME_RUNNING);
                task.LastTime = DateUtil.CurrentTimeMillis;
                db.Updateable <DmeTask>(task).UpdateColumns(t => new { task.Status, task.LastTime }).ExecuteCommand();
                DmeQuartzScheduler <TaskRunnerJob> .ResumeJob(task.SysCode, model.ModelTypeCode);

                break;

            case -1:
                LOG.Info($"删除任务[{taskCode}]");
                // 删除与任务相关的步骤记录和结果记录
                int count = db.Deleteable <DmeTaskRuleStep>(trs => trs.TaskId == task.Id).ExecuteCommand();
                LOG.Info($"删除任务[{taskCode}]关联的[{count}]个步骤记录");
                count = db.Deleteable <DmeTaskResult>(tr => tr.TaskId == task.Id).ExecuteCommand();
                LOG.Info($"删除任务[{taskCode}]关联的[{count}]个结果记录");
                // 从mongo中获取
                var filter = Builders <TaskResultColl> .Filter.And(
                    Builders <TaskResultColl> .Filter.Eq("TaskId", task.Id));

                MongodbHelper <TaskResultColl> .DeleteMany(ServiceFactory.MongoDatabase, filter);

                db.Deleteable <DmeTask>(task).ExecuteCommand();
                DmeQuartzScheduler <TaskRunnerJob> .DeleteJob(task.SysCode, model.ModelTypeCode);

                break;

            default:
                break;
            }
            return(true);
        }
Esempio n. 2
0
        public object GetTask(string taskCode)
        {
            var     db   = base.Repository.GetDbContext();
            DmeTask task = db.Queryable <DmeTask>().Single(t => t.SysCode == taskCode);

            if (null == task)
            {
                throw new BusinessException((int)EnumSystemStatusCode.DME_FAIL, $"任务[{taskCode}]不存在");
            }
            return(task);
        }
Esempio n. 3
0
        /// <summary>
        /// 从缓存或者db中获取任务步骤信息
        /// </summary>
        /// <param name="db"></param>
        /// <param name="task"></param>
        /// <param name="ruleStep"></param>
        /// <param name="cacheKey"></param>
        /// <returns></returns>
        private DmeTaskRuleStep GetTaskRuleStep(SqlSugarClient db, DmeTask task, DmeRuleStep ruleStep, out string cacheKey)
        {
            // 先从缓存查找
            cacheKey = HashUtil.Hash_2_MD5_32($"{task.SysCode}_{ruleStep.SysCode}");
            DmeTaskRuleStep dmeTaskRuleStep = null;

            try
            {
                dmeTaskRuleStep = ServiceFactory.CacheService.Get <DmeTaskRuleStep>(cacheKey);
                if (dmeTaskRuleStep != null)
                {
                    LOG.Info($"缓存中获取到任务步骤信息,任务id[{dmeTaskRuleStep.TaskId}],步骤id[{dmeTaskRuleStep.RuleStepId}]");
                    return(dmeTaskRuleStep);
                }
            }
            catch (Exception ex)
            {
                LOG.Warn("从缓存中获取任务步骤信息失败,详情:" + ex.Message);
            }
            // 从数据库中查找
            dmeTaskRuleStep = db.Queryable <DmeTaskRuleStep>().Single(tr => tr.TaskId == task.Id && tr.RuleStepId == ruleStep.Id);
            return(dmeTaskRuleStep);
        }
 public AlgorithmInputStepData(IRepository repository, DmeTask task, DmeRuleStep step)
     : base(repository, task, step)
 {
     ruleStepMeta = new AlgorithmInputStepMeta(repository, step);
 }
Esempio n. 5
0
 public DataSourceInputStepData(IRepository repository, DmeTask task, DmeRuleStep step) :
     base(repository, task, step)
 {
     ruleStepMeta = new DataSourceInputStepMeta(repository, step);
 }
Esempio n. 6
0
        /// <summary>
        /// 获取规则步骤数据操作类
        /// </summary>
        /// <param name="stepTypeCode">步骤类型唯一编码</param>
        /// <param name="repository"></param>
        /// <param name="taskId"></param>
        /// <param name="step"></param>
        /// <returns></returns>
        public static IRuleStepData GetRuleStepData(string stepTypeCode, IRepository repository, DmeTask task, DmeRuleStep step)
        {
            if (!Register.RuleStepPluginsMap.ContainsKey(stepTypeCode))
            {
                LOG.Warn($"没有找到步骤类型为[{stepTypeCode}]的插件信息");
                return(null);
            }
            RuleStepPluginRegisterDTO ruleStepPluginRegisterDTO = Register.RuleStepPluginsMap[stepTypeCode];
            String        baseDir      = AppDomain.CurrentDomain.BaseDirectory;
            string        assemblyPath = Path.Combine(baseDir, ruleStepPluginRegisterDTO.Assembly);
            Assembly      assembly     = Assembly.LoadFile(assemblyPath);
            IRuleStepData ruleStepData = (IRuleStepData)assembly.CreateInstance(ruleStepPluginRegisterDTO.ClassId, true, BindingFlags.CreateInstance, null
                                                                                , new object[] { repository, task, step }, null, null);

            return(ruleStepData);
        }
Esempio n. 7
0
        public object GetTaskResult(string taskCode, int ruleStepId)
        {
            SqlSugarClient db   = base.Repository.GetDbContext();
            DmeTask        task = db.Queryable <DmeTask>().Single(t => t.SysCode == taskCode);

            if (null == task)
            {
                throw new BusinessException((int)EnumSystemStatusCode.DME_FAIL, $"任务不存在[{taskCode}]");
            }
            // 查询任务的结果输出
            IList <DmeTaskResult> taskResults = null;

            if (-1 == ruleStepId)
            {
                // 全部步骤
                taskResults = db.Queryable <DmeTaskResult>().Where(tr => tr.TaskId == task.Id).ToList();
            }
            else
            {
                // 指定步骤
                taskResults = db.Queryable <DmeTaskResult>().Where(tr => tr.TaskId == task.Id && tr.RuleStepId == ruleStepId).ToList();
            }
            if (null == taskResults || 0 == taskResults.Count)
            {
                return(null);
            }
            IList <TaskResultRespDTO> taskResultRespDTOs = new List <TaskResultRespDTO>();
            TaskResultRespDTO         temp = null;

            foreach (var item in taskResults)
            {
                temp = new TaskResultRespDTO
                {
                    RuleStepId = item.RuleStepId,
                    Code       = item.ResultCode,
                    Type       = item.ResultType
                };
                // 解析步骤类型
                DmeRuleStep ruleStep = db.Queryable <DmeRuleStep>().Single(rs => rs.Id == item.RuleStepId);

                //   Value = item.ResultValue
                EnumValueMetaType @enum = EnumUtil.GetEnumObjByName <EnumValueMetaType>(temp.Type);
                switch (@enum)
                {
                case EnumValueMetaType.TYPE_UNKNOWN:
                case EnumValueMetaType.TYPE_NUMBER:
                case EnumValueMetaType.TYPE_STRING:
                case EnumValueMetaType.TYPE_INTEGER:
                case EnumValueMetaType.TYPE_BIGNUMBER:
                case EnumValueMetaType.TYPE_TIMESTAMP:
                case EnumValueMetaType.TYPE_INET:
                case EnumValueMetaType.TYPE_LOCAL_FILE:
                case EnumValueMetaType.TYPE_GDB_PATH:
                case EnumValueMetaType.TYPE_FOLDER:
                    temp.Value = item.ResultValue;
                    break;

                case EnumValueMetaType.TYPE_DATE:
                    // 要求格式:yyyy-MM-dd hh:mm:ss
                    temp.Value = Convert.ToDateTime(item.ResultValue?.ToString());
                    break;

                case EnumValueMetaType.TYPE_BOOLEAN:
                    temp.Value = Boolean.Parse(item.ResultValue?.ToString());
                    break;

                case EnumValueMetaType.TYPE_SERIALIZABLE:
                    break;

                case EnumValueMetaType.TYPE_BINARY:
                    break;

                case EnumValueMetaType.TYPE_MDB_FEATURECLASS:
                    break;

                case EnumValueMetaType.TYPE_STRING_LIST:
                    temp.Value = item.ResultValue?.ToString().Split(";");
                    break;

                case EnumValueMetaType.TYPE_SDE_FEATURECLASS:
                    break;

                case EnumValueMetaType.TYPE_FEATURECLASS:
                    break;

                case EnumValueMetaType.TYPE_JSON:
                    // 从mongo中获取
                    var filter = Builders <TaskResultColl> .Filter.And(
                        Builders <TaskResultColl> .Filter.Eq("TaskId", item.TaskId),
                        Builders <TaskResultColl> .Filter.Eq("RuleStepId", item.RuleStepId),
                        Builders <TaskResultColl> .Filter.Eq("Code", item.ResultCode));

                    IList <TaskResultColl> colls = MongodbHelper <TaskResultColl> .FindList(ServiceFactory.MongoDatabase, filter);

                    if (colls != null && colls.Count > 0)
                    {
                        temp.Value = colls[0].Value;
                    }
                    break;

                default:
                    break;
                }

                taskResultRespDTOs.Add(temp);
            }
            return(taskResultRespDTOs);
        }
Esempio n. 8
0
        public async Task RunTaskScheduleAsync(string taskCode)
        {
            var     db   = Repository.GetDbContext();
            DmeTask task = db.Queryable <DmeTask>().Single(t => t.SysCode == taskCode);

            if (null == task)
            {
                throw new BusinessException((int)EnumSystemStatusCode.DME_FAIL, $"任务[{taskCode}]不存在");
            }
            // 查询模型版本
            DmeModelVersion modelVersion = db.Queryable <DmeModelVersion>().InSingle(task.VersionId);//.Single(mv => mv.SysCode == dto.ModelVersionCode);

            if (null == modelVersion)
            {
                throw new BusinessException((int)EnumSystemStatusCode.DME_ERROR, $"模型的版本[{task.VersionId}]不存在");
            }
            // Single方法,如果查询数据库多条数据,会抛出异常
            DmeModel model = db.Queryable <DmeModel>().InSingle(task.ModelId);

            if (null == model)
            {
                throw new BusinessException((int)EnumSystemStatusCode.DME_ERROR, $"模型[{task.ModelId}]不存在");
            }
            // 查找关联的算法信息
            IList <DmeRuleStep> ruleSteps = db.Queryable <DmeRuleStep>().Where(rs => rs.ModelId == model.Id && rs.VersionId == modelVersion.Id).ToList();

            if (0 == ruleSteps?.Count)
            {
                LOG.Warn($"模型[{model.SysCode}]的版本[{modelVersion.SysCode}]下没有可执行步骤,停止运行");
                return;
            }
            try
            {
                // 清理掉任务之前的过程结果
                // 包括DME_TASK_RESULT、DME_TASK_RULESTEP和mongo TaskResultColl
                db.Ado.UseTran(() => {
                    int count = db.Deleteable <DmeTaskRuleStep>().Where(trs => trs.TaskId == task.Id).ExecuteCommand();
                    LOG.Info($"删除任务关联的步骤记录[{count}]条");
                    db.Deleteable <DmeTaskResult>().Where(tr => tr.TaskId == task.Id).ExecuteCommand();
                    LOG.Info($"删除任务结果记录[{count}]条");
                    var filter = Builders <TaskResultColl> .Filter.And(
                        Builders <TaskResultColl> .Filter.Eq("TaskCode", task.SysCode));
                    DeleteResult deleteResult = MongodbHelper <TaskResultColl> .DeleteMany(ServiceFactory.MongoDatabase, filter);
                    LOG.Info($"删除mongo记录[{deleteResult.DeletedCount}]条");

                    LOG.Info($"清理缓存计算数据");
                    IList <string> cacheKeys = new List <string>();
                    foreach (var item in ruleSteps)
                    {
                        cacheKeys.Add(HashUtil.Hash_2_MD5_32($"{task.SysCode}_{item.SysCode}"));
                    }
                    ServiceFactory.CacheService.RemoveAllAsync(cacheKeys);

                    // 修改任务状态为running
                    task.Status = EnumUtil.GetEnumDisplayName(EnumSystemStatusCode.DME_RUNNING);
                    db.Updateable <DmeTask>(task).UpdateColumns(t => t.Status).ExecuteCommand();
                });
                // 此时不阻塞,返回类型为Task,为了能捕获到线程异常信息
                await RunTaskAsyncEx(db, model, modelVersion, task, ruleSteps);
            }
            catch (Exception ex)
            {
                LOG.Error(ex, ex.Message);
                // 更改任务状态
                task.Status   = EnumUtil.GetEnumDisplayName(EnumSystemStatusCode.DME_ERROR);
                task.LastTime = DateUtil.CurrentTimeMillis;
                db.Updateable <DmeTask>(task).UpdateColumns(t => new { task.Status, task.LastTime }).ExecuteCommand();
            }
        }
Esempio n. 9
0
        /// <summary>
        /// 运行步骤节点
        /// </summary>
        /// <param name="db"></param>
        /// <param name="task"></param>
        /// <param name="node"></param>
        private void RunRuleStepNode(SqlSugarClient db, DmeTask task, RuleStepLinkedListNode <DmeRuleStep> node)
        {
            // 先计算前置节点
            if (node.Previous?.Count > 0)
            {
                foreach (var item in node.Previous)
                {
                    RunRuleStepNode(db, task, item);
                }
            }
            DmeTaskRuleStep dmeTaskRuleStep = null;

            try
            {
                // 先判断任务的状态,是否被停止
                DmeTask taskStatus = db.Queryable <DmeTask>().Single(t => t.SysCode == task.SysCode);
                if (null == taskStatus || taskStatus.Status.Equals(EnumUtil.GetEnumDisplayName(EnumSystemStatusCode.DME_STOP)))
                {
                    LOG.Info($"任务[{task.SysCode}]不存在或者已被停止");
                    return;
                }
                dmeTaskRuleStep = this.GetTaskRuleStep(db, task, node.Value, out string cacheKey);
                if (dmeTaskRuleStep != null && EnumUtil.GetEnumDisplayName(EnumSystemStatusCode.DME_SUCCESS).Equals(dmeTaskRuleStep.Status))
                {
                    // 释放
                    dmeTaskRuleStep = null;
                    LOG.Info($"任务[{task.SysCode}]下的步骤[{node.Value.SysCode}]已被计算过,并且状态为[success]");
                    return;
                }
                // 如果前置节点没有了,则计算当前节点内容
                DmeRuleStepType ruleStepTypeTemp = db.Queryable <DmeRuleStepType>().Single(rst => rst.Id == node.Value.StepTypeId);
                IRuleStepData   ruleStepData     = RuleStepFactory.GetRuleStepData(ruleStepTypeTemp.Code, this.Repository, task, node.Value);
                if (null == ruleStepData)
                {
                    throw new BusinessException((int)EnumSystemStatusCode.DME_ERROR, $"步骤工厂无法创建编码为[{ruleStepTypeTemp.Code}]的流程实例节点");
                }
                dmeTaskRuleStep = new DmeTaskRuleStep
                {
                    SysCode    = GuidUtil.NewGuid(),
                    TaskId     = task.Id,
                    RuleStepId = node.Value.Id,
                    Status     = EnumUtil.GetEnumDisplayName(EnumSystemStatusCode.DME_RUNNING),
                    CreateTime = DateUtil.CurrentTimeMillis,
                    LastTime   = DateUtil.CurrentTimeMillis
                };
                dmeTaskRuleStep = db.Insertable <DmeTaskRuleStep>(dmeTaskRuleStep).ExecuteReturnEntity();
                // 任务步骤创建成功后,把相关信息记录在缓存中
                ServiceFactory.CacheService.AddAsync(cacheKey, dmeTaskRuleStep, 60);
                Result stepResult = ruleStepData.Run();
                UpdateRuleStep(db, dmeTaskRuleStep, cacheKey, stepResult);
                // 然后计算下一个步骤
                if (node?.Next.Count > 0)
                {
                    foreach (var item in node.Next)
                    {
                        RunRuleStepNode(db, task, item);
                    }
                }
            }
            catch (Exception ex)
            {
                dmeTaskRuleStep.Status   = EnumUtil.GetEnumDisplayName(EnumSystemStatusCode.DME_ERROR);
                dmeTaskRuleStep.LastTime = DateUtil.CurrentTimeMillis;
                // 只更新状态和最后时间
                db.Updateable <DmeTaskRuleStep>(dmeTaskRuleStep).UpdateColumns(ts => new { ts.Status, ts.LastTime }).ExecuteCommand();
                this.LogService.AddLogAsync(Base.Common.Log.EnumLogType.ENTITY, EnumLogLevel.ERROR, nameof(DmeTaskRuleStep), dmeTaskRuleStep.SysCode, "", ex, "", NetAssist.GetLocalHost());
            }
        }
Esempio n. 10
0
 private Task RunTaskAsyncEx(SqlSugarClient db, DmeModel model, DmeModelVersion modelVersion, DmeTask task, IList <DmeRuleStep> ruleSteps)
 {
     return(Task.Run(() =>
     {
         return db.Ado.UseTran <DmeTask>(() =>
         {
             try
             {
                 // 查询步骤前后依赖关系
                 // 形成链表
                 IList <DmeRuleStepHop> hops = db.Queryable <DmeRuleStepHop>().Where(rsh => rsh.ModelId == model.Id && rsh.VersionId == modelVersion.Id).OrderBy("STEP_FROM_ID").ToList();
                 IList <RuleStepLinkedListNode <DmeRuleStep> > rulestepLinkedList = this.GetRuleStepNodeLinkedList(db, model, modelVersion, ruleSteps);
                 foreach (var item in rulestepLinkedList)
                 {
                     // 开始计算步骤
                     this.RunRuleStepNode(db, task, item);
                 }
                 // 完成模型计算
                 task.Status = EnumUtil.GetEnumDisplayName(EnumSystemStatusCode.DME_SUCCESS);
                 task.LastTime = DateUtil.CurrentTimeMillis;
                 db.Updateable <DmeTask>(task).ExecuteCommand();
                 // @TODO 发送模型计算成功的消息
                 KafkaProducer.Send(nameof(EnumMessageType.TASK), new MessageBody()
                 {
                     // 创建者一致
                     From = "123",
                     To = "123",
                     ChannelType = EnumChannelType.P2P,
                     MessageType = EnumMessageType.TASK,
                     Payload = $"模型[{task.SysCode}]计算完成,状态[{task.Status}]"
                 });
                 return task;
             }
             catch (Exception ex)
             {
                 // 更改任务执行的状态
                 if (ex is BusinessException)
                 {
                     task.Status = EnumUtil.GetEnumDisplayName(EnumUtil.GetEnumObjByValue <EnumSystemStatusCode>(((BusinessException)ex).Code));
                 }
                 else
                 {
                     task.Status = EnumUtil.GetEnumDisplayName(EnumSystemStatusCode.DME_ERROR);
                 }
                 task.LastTime = DateUtil.CurrentTimeMillis;
                 db.Updateable <DmeTask>(task).ExecuteCommand();
                 // 添加日志
                 this.LogService.AddLogAsync(Base.Common.Log.EnumLogType.ENTITY, Base.Common.Log.EnumLogLevel.ERROR, nameof(DmeTask), task.SysCode, "", ex, "", NetAssist.GetLocalHost());
                 throw ex;
             }
         });
     }));
 }
Esempio n. 11
0
        public async Task <DmeTask> CreateTaskAsync(NewTaskReqDTO dto)
        {
            // 验证数据库是否存在指定模型版本信息
            SqlSugarClient db = base.Repository.GetDbContext();
            // 查询模型版本
            DmeModelVersion modelVersion = db.Queryable <DmeModelVersion>().Single(mv => mv.SysCode == dto.ModelVersionCode);

            if (null == modelVersion)
            {
                throw new BusinessException((int)EnumSystemStatusCode.DME_ERROR, $"模型的版本[{dto.ModelVersionCode}]不存在");
            }
            // Single方法,如果查询数据库多条数据,会抛出异常
            DmeModel model = db.Queryable <DmeModel>().Single(m => m.Id == modelVersion.ModelId);

            if (null == model)
            {
                throw new BusinessException((int)EnumSystemStatusCode.DME_ERROR, $"模型[{modelVersion.ModelId}]不存在");
            }
            // 获取模型类型
            DmeModelType modelType = db.Queryable <DmeModelType>().InSingle(model.ModelTypeId);
            // 查找关联的算法信息
            IList <DmeRuleStep> ruleSteps = db.Queryable <DmeRuleStep>().Where(rs => rs.ModelId == model.Id && rs.VersionId == modelVersion.Id).ToList();

            if (0 == ruleSteps?.Count)
            {
                LOG.Warn($"模型[{model.SysCode}]的版本[{dto.ModelVersionCode}]下没有可执行步骤,停止运行");
                return(null);
            }
            DmeTask newTask = db.Ado.UseTran <DmeTask>(() =>
            {
                // 每执行一次模型,生成一次任务
                newTask = new DmeTask
                {
                    SysCode    = GuidUtil.NewGuid(),
                    CreateTime = DateUtil.CurrentTimeMillis,
                    Status     = EnumUtil.GetEnumDisplayName(EnumSystemStatusCode.DME_WAITTING),
                    ModelId    = model.Id,
                    VersionId  = modelVersion.Id,
                    Remark     = dto.Remark,
                    NodeServer = NetAssist.GetLocalHost()
                };
                if (string.IsNullOrWhiteSpace(dto.Name))
                {
                    newTask.Name = "task-" + newTask.CreateTime;
                }
                else
                {
                    newTask.Name = dto.Name;
                }

                newTask.LastTime = newTask.CreateTime;
                newTask          = db.Insertable <DmeTask>(newTask).ExecuteReturnEntity();
                return(newTask);
            }).Data;

            // 创建job
            await DmeQuartzScheduler <TaskRunnerJob> .NewJob(
                newTask.SysCode,
                modelType.SysCode,
                dto.CronExpression,
                new Dictionary <string, object> {
                { TaskRunnerJob.TASK_CODE_KEY, newTask.SysCode }
            },
                1 == dto.StartNow,
                DateTimeOffset.Now.AddSeconds(dto.InSeconds),
                dto.Remark);

            return(newTask);
        }
Esempio n. 12
0
        //protected int modelId;
        //protected int versionId;
        //protected int ruleStepId;
        /// <summary>
        /// 真正运行的时候,taskId和step才被使用到
        /// </summary>
        /// <param name="repository"></param>
        /// <param name="taskId"></param>
        /// <param name="step"></param>
        //public BaseRuleStepData(IRepository repository, int taskId, DmeRuleStep step)
        //{
        //    this.repository = repository;
        //    this.taskId = taskId;
        //    this.step = step;
        //    //this.modelId = modelId;
        //    //this.versionId = versionId;
        //    //this.ruleStepId = ruleStepId;

        //}
        public BaseRuleStepData(IRepository repository, DmeTask task, DmeRuleStep step)
        {
            this.repository = repository;
            this.task       = task;
            this.step       = step;
        }
Esempio n. 13
0
 public MongoDBOutputStepData(IRepository repository, DmeTask task, DmeRuleStep step) :
     base(repository, task, step)
 {
     ruleStepMeta = new MongoDBOutputStepMeta(repository, step);
 }