public async Task <IWorkflowResult <AssigneeWorkflowResult> > RejectAsync(ApproveHolidayViewModel model) { var holiday = await FindOrCreate(model.Id); var triggerParam = new TriggerParam(HolidayApprovalWorkflow.REJECT_TRIGGER, holiday) .AddVariableWithKey <ApproveHolidayViewModel>(model); var triggerResult = await this._workflowEngine.TriggerAsync(triggerParam); var info = await this._workflowEngine.ToWorkflowTriggerInfo(holiday, triggerResult); var viewModel = new AssigneeWorkflowResult(holiday.Assignee); return(new WorkflowResult <Holiday, AssigneeWorkflowResult>(info, holiday, viewModel)); }
public async Task <IWorkflowResult <AssigneeWorkflowResult> > ProcessAsync(IssueViewModel model) { var issue = await FindOrCreate(model.Id); var triggerParam = new TriggerParam(model.Trigger, issue) .AddVariableWithKey <IssueViewModel>(model); var triggerResult = await this._workflowEngine.TriggerAsync(triggerParam); var info = await this._workflowEngine.ToWorkflowTriggerInfo(issue, triggerResult); var viewModel = new AssigneeWorkflowResult(issue.Assignee); return(new WorkflowResult <Issue, AssigneeWorkflowResult>(info, issue, viewModel)); }
public async Task <IWorkflowResult <ApplyHolidayViewModel> > NewAsync() { var holiday = Holiday.Create(_userContext.UserName); var triggerParam = new TriggerParam(HolidayApprovalWorkflow.APPLY_TRIGGER, holiday); var triggerResult = await this._workflowEngine.CanTriggerAsync(triggerParam); var info = await this._workflowEngine.ToWorkflowTriggerInfo(holiday, triggerResult); var viewModel = new ApplyHolidayViewModel(); var result = new WorkflowResult <Holiday, ApplyHolidayViewModel>(info, holiday, viewModel); return(await Task.FromResult <IWorkflowResult <ApplyHolidayViewModel> >(result)); }
public async Task <IWorkflowResult <IssueViewModel> > NewAsync() { var issue = Issue.Create(_userContext.UserName); var triggerParam = new TriggerParam(IssueTrackingWorkflow.ASSIGN_TRIGGER, issue); var triggerResult = await this._workflowEngine.CanTriggerAsync(triggerParam); var info = await this._workflowEngine.ToWorkflowTriggerInfo(issue, triggerResult); var viewModel = new IssueViewModel(); var result = new WorkflowResult <Issue, IssueViewModel>(info, issue, viewModel); return(await Task.FromResult <IWorkflowResult <IssueViewModel> >(result)); }
public async Task WorkflowEngine_TriggerAsync_ReturnsTriggerResult() { // Arrange var instance = new Switcher(); var param = new TriggerParam("SwitchOn", instance); // Act var triggerResult = await this.WorkflowEngine.TriggerAsync(param); // Assert Assert.IsNotNull(triggerResult); Assert.IsFalse(triggerResult.HasErrors); Assert.AreEqual(instance.State, triggerResult.CurrentState); Assert.AreEqual("On", triggerResult.CurrentState); }
private ReturnT PushJobQueue(TriggerParam triggerParam, ITaskExecutor executor) { if (RUNNING_QUEUE.TryGetValue(triggerParam.JobId, out var jobQueue)) { return(jobQueue.Push(triggerParam)); } //NewJobId jobQueue = new JobTaskQueue(executor, this._jobLogger, this._jobQueueLogger); jobQueue.CallBack += TriggerCallback; if (RUNNING_QUEUE.TryAdd(triggerParam.JobId, jobQueue)) { return(jobQueue.Push(triggerParam)); } return(ReturnT.Failed("add running queue executor error")); }
public ReturnT PushTriggerQueue(TriggerParam triggerParam) { // avoid repeat if (_triggerLogIdSet.ContainsKey(triggerParam.logId)) { _logger.LogInformation("repeate trigger job, logId:{logId}", triggerParam.logId); return(ReturnT.CreateFailedResult("repeate trigger job, logId:" + triggerParam.logId)); } _logger.LogInformation("repeate trigger job, logId:{logId}", triggerParam.logId); _triggerLogIdSet[triggerParam.jobId] = 0; _triggerQueue.Enqueue(triggerParam); _queueHasDataEvent.Set(); return(ReturnT.SUCCESS); }
private async Task PersistWorkflow(Workflow workflow, TriggerParam triggerParam) { if (workflow == null) { throw new ArgumentNullException(nameof(workflow)); } // persisting workflow variables if (triggerParam.HasVariables) { foreach (var v in triggerParam.Variables) { var variable = workflow.WorkflowVariables .FirstOrDefault(variables => variables.Type == v.Key); if (variable != null) { variable.Content = JsonConvert.SerializeObject(v.Value); } else { workflow.AddVariable(v.Value); } } } // keeping workflow entity nsync var entityWorkflow = triggerParam.Instance as IEntityWorkflow; if (entityWorkflow != null) { #region Fix _context.Entry(entityWorkflow).State = EntityState.Modified; #endregion Fix workflow.Type = entityWorkflow.Type; workflow.Assignee = entityWorkflow.Assignee; workflow.AddHistoryItem(workflow.State, entityWorkflow.State, _userContext.UserName); workflow.State = entityWorkflow.State; } if (await WorkflowIsCompleted(triggerParam)) { workflow.Completed = SystemTime.Now(); } }
private ReturnT ChangeJobQueue(TriggerParam triggerParam, ITaskExecutor executor) { if (RUNNING_QUEUE.TryRemove(triggerParam.JobId, out var oldJobTask)) { oldJobTask.CallBack -= TriggerCallback; oldJobTask.Dispose(); //释放原来的资源 } JobTaskQueue jobQueue = new JobTaskQueue(executor, this._jobLogger, this._jobQueueLogger); jobQueue.CallBack += TriggerCallback; if (RUNNING_QUEUE.TryAdd(triggerParam.JobId, jobQueue)) { return(jobQueue.Push(triggerParam)); } return(ReturnT.Failed(" replace running queue executor error")); }
private async Task PersistWorkflow( Workflow workflow, TriggerParam triggerParam, DateTime?dueDate = null ) { if (workflow == null) { throw new ArgumentNullException(nameof(workflow)); } if (triggerParam.Variables != null && triggerParam.HasVariables) { foreach (var v in triggerParam.Variables) { var variable = workflow.WorkflowVariables .FirstOrDefault(_ => _.Type == v.Key); if (variable != null) { variable.Content = JsonConvert.SerializeObject(v.Value); } else { workflow.AddVariable(v.Value); } } } var entityWorkflow = triggerParam.Instance as IEntityWorkflow; if (entityWorkflow != null) { workflow.Type = entityWorkflow.Type; workflow.State = entityWorkflow.State; workflow.Assignee = entityWorkflow.Assignee; } if (await WorkflowIsCompleted(triggerParam)) { workflow.Completed = SystemTime.Now(); } workflow.DueDate = dueDate; }
public async Task WorkflowEngine_TriggerAsyncWithEntityWorkflowInstance_ReturnsTriggerResult() { // Arrange var instance = new LightSwitcher(); var param = new TriggerParam("SwitchOn", instance); // Act var triggerResult = await this.WorkflowEngine.TriggerAsync(param); // Assert Assert.IsNotNull(triggerResult); Assert.IsFalse(triggerResult.HasErrors); Assert.AreEqual(instance.State, triggerResult.CurrentState); Assert.AreEqual("On", triggerResult.CurrentState); Assert.AreEqual(1, this.Context.Workflows.Count()); Assert.AreEqual(0, this.Context.Workflows.First().WorkflowVariables.Count()); }
public async Task WorkflowEngine_TriggerAsyncWithEntityWorkflowInstanceAndSameWorkflowVariable_ReturnsTriggerResult() { // Arrange var instance = new LightSwitcher(); this.Context.Switchers.Add(instance); var workflow = Workflow.Create(instance.Id, instance.Type, instance.State, "tester"); var variable = new LightSwitcherWorkflowVariable { CanSwitch = true }; workflow.AddVariable(variable); this.Context.Workflows.Add(workflow); await this.Context.SaveChangesAsync(); variable.CanSwitch = false; var param = new TriggerParam("SwitchOn", instance) .AddVariableWithKey <LightSwitcherWorkflowVariable>(variable);; // Act var triggerResult = await this.WorkflowEngine.TriggerAsync(param); // Assert Assert.IsNotNull(triggerResult); Assert.IsFalse(triggerResult.HasErrors); Assert.AreEqual(instance.State, triggerResult.CurrentState); Assert.AreEqual("On", triggerResult.CurrentState); Assert.IsTrue(param.HasVariables); Assert.AreEqual(1, workflow.WorkflowHistories.Count()); var workflowVariable = workflow.WorkflowVariables.First(); var type = KeyBuilder.FromKey(workflowVariable.Type); var myDeserializedVariable = JsonConvert.DeserializeObject(workflowVariable.Content, type); Assert.IsInstanceOfType(myDeserializedVariable, typeof(LightSwitcherWorkflowVariable)); var variableInstance = myDeserializedVariable as LightSwitcherWorkflowVariable; Assert.IsFalse(variableInstance.CanSwitch); }
public void TriggerParam_NewInstance_CreatesANewInstance() { // Arrange var trigger = "SwitchOn"; Switcher switcher = new Switcher { Type = OnOffWorkflow.TYPE }; // Act var triggerParam = new TriggerParam(trigger, switcher); // Assert Assert.NotNull(triggerParam); Assert.Equal(triggerParam.TriggerName, trigger); Assert.Equal(triggerParam.Instance, switcher); Assert.False(triggerParam.HasVariables); Assert.NotNull(triggerParam.Variables); }
public void TriggerParam_NewInstanceWithFluentVariables_CreatesANewInstance() { // Arrange var trigger = "SwitchOn"; Switcher switcher = new Switcher { Type = OnOffWorkflow.TYPE }; // Act var triggerParam = new TriggerParam(trigger, switcher) .AddVariable(SwitcherWorkflowVariable.KEY, new SwitcherWorkflowVariable(true)); // Assert Assert.NotNull(triggerParam); Assert.Equal(triggerParam.TriggerName, trigger); Assert.Equal(triggerParam.Instance, switcher); Assert.True(triggerParam.HasVariables); Assert.NotNull(triggerParam.Variables); }
public async Task <IWorkflowResult <NoWorkflowResult> > ApplyAsync(ApplyHolidayViewModel model) { if (model == null) { throw new ArgumentNullException(nameof(model)); } var holiday = await FindOrCreate(null); holiday.Superior = "alice"; var triggerParam = new TriggerParam(HolidayApprovalWorkflow.APPLY_TRIGGER, holiday) .AddVariable(ApplyHolidayViewModel.KEY, model); var triggerResult = this._workflowEngine.Trigger(triggerParam); var info = this.ToWorkflowTriggerInfo(holiday, triggerResult); var viewModel = new NoWorkflowResult(holiday.Assignee); return(new WorkflowResult <Holiday, NoWorkflowResult>(info, holiday, viewModel)); }
private async Task <TriggerResult> ProcessItemAsync(WorkItem item) { _logger.LogTrace("Processing work item", item); using (var scope = _serviceScopeFactory.CreateScope()) { IServiceProvider serviceProvider = scope.ServiceProvider; var engine = serviceProvider.GetRequiredService <IWorkflowEngine>(); var workflowDefinitionProvider = serviceProvider.GetRequiredService <IWorkflowDefinitionProvider>(); EntityWorkflowDefinitionBase workflowDefinition = (EntityWorkflowDefinitionBase)workflowDefinitionProvider .GetWorkflowDefinition(item.WorkflowType); IWorkflow workflow = engine.Find(item.EntityId, workflowDefinition.EntityType); TriggerParam triggerParam = new TriggerParam(item.TriggerName, workflow); return(await engine.TriggerAsync(triggerParam)); } }
/// <summary> /// 执行队列,并快速返回结果 /// </summary> /// <param name="triggerParam"></param> /// <returns></returns> /// <exception cref="NotImplementedException"></exception> public ReturnT Execute(TriggerParam triggerParam) { var executor = this._executorFactory.GetTaskExecutor(triggerParam.GlueType); if (executor == null) { return(ReturnT.Failed($"glueType[{triggerParam.GlueType}] is not supported ")); } // 1. 根据JobId 获取 TaskQueue; 用于判断是否有正在执行的任务 if (RUNNING_QUEUE.TryGetValue(triggerParam.JobId, out var taskQueue)) { if (taskQueue.Executor != executor) //任务执行器变更 { return(ChangeJobQueue(triggerParam, executor)); } } if (taskQueue != null) //旧任务还在执行,判断执行策略 { //丢弃后续的 if (Constants.ExecutorBlockStrategy.DISCARD_LATER == triggerParam.ExecutorBlockStrategy) { //存在还没执行完成的任务 if (taskQueue.IsRunning()) { return(ReturnT.Failed($"block strategy effect:{triggerParam.ExecutorBlockStrategy}")); } //否则还是继续做 } //覆盖较早的 if (Constants.ExecutorBlockStrategy.COVER_EARLY == triggerParam.ExecutorBlockStrategy) { return(taskQueue.Replace(triggerParam)); } } return(PushJobQueue(triggerParam, executor)); }
public async Task WorkflowEngineService_TriggerAsyncWithEntityWorkflowInstanceAndNewWorkflowVariable_ReturnsTriggerResult() { // Arrange var instance = new LightSwitcher(); var workfowVariable = new LightSwitcherWorkflowVariable { CanSwitch = true }; var param = new TriggerParam("SwitchOn", instance) .AddVariableWithKey <LightSwitcherWorkflowVariable>(workfowVariable); // Act var triggerResult = await this.WorkflowEngineService.TriggerAsync(param); // Assert Assert.NotNull(triggerResult); Assert.False(triggerResult.HasErrors); Assert.Equal(instance.State, triggerResult.CurrentState); Assert.Equal("On", triggerResult.CurrentState); Assert.Equal(1, this.Context.Workflows.Count()); Assert.Single(this.Context.Workflows.First().WorkflowVariables); }
public void TriggerParam_NewInstanceWithVariables_CreatesANewInstance() { // Arrange var trigger = "SwitchOn"; Switcher switcher = new Switcher { Type = OnOffWorkflow.TYPE }; var variables = new Dictionary <string, WorkflowVariableBase>(); var variable = new SwitcherWorkflowVariable(true); variables.Add(SwitcherWorkflowVariable.KEY, variable); // Act var triggerParam = new TriggerParam(trigger, switcher, variables); // Assert Assert.NotNull(triggerParam); Assert.Equal(triggerParam.TriggerName, trigger); Assert.Equal(triggerParam.Instance, switcher); Assert.True(triggerParam.HasVariables); Assert.NotNull(triggerParam.Variables); }
public void CanTrigger_InitialStateIsOff_CanNotTriggerToStateOn() { // Arrange Switcher switcher = new Switcher { Type = OnOffWorkflow.TYPE }; WorkflowExecution execution = new WorkflowExecution(new OnOffWorkflow()); var variables = new Dictionary <string, WorkflowVariableBase>(); var variable = new SwitcherWorkflowVariable(false); variables.Add(SwitcherWorkflowVariable.KEY, variable); var triggerParam = new TriggerParam("SwitchOn", switcher, variables); // Act TriggerResult result = execution.CanTrigger(triggerParam); // Assert Assert.IsNotNull(result); Assert.AreEqual(false, result.CanTrigger); }
private ReturnT Run(TriggerParam triggerParam) { if (Constants.GlueType.BEAN != triggerParam.glueType) { return(ReturnT.CreateFailedResult("glueType[" + triggerParam.glueType + "] is not valid.")); } JobThread jobThread; var isNewThread = _jobThreadFactory.GetJobThread(triggerParam, out jobThread); if (!isNewThread && Constants.ExecutorBlockStrategy.DISCARD_LATER == triggerParam.executorBlockStrategy && jobThread.IsRunningOrHasQueue()) { return(ReturnT.CreateFailedResult("block strategy effect:" + triggerParam.executorBlockStrategy)); } var result = jobThread.PushTriggerQueue(triggerParam); if (isNewThread) { jobThread.Start(); } return(result); }
private void EnsureWorkflowVariables(Workflow workflow, TriggerParam param) { if (workflow.WorkflowVariables.Count == 0) { return; } foreach (var workflowVariable in workflow.WorkflowVariables) { var variable = WorkflowVariable.ConvertContent(workflowVariable); if (variable is WorkflowVariableBase) { var key = workflowVariable.Type; if (param.Variables.ContainsKey(key)) { param.Variables[key] = variable as WorkflowVariableBase; } else { param.Variables.Add(key, variable as WorkflowVariableBase); } } } }
private void EnsureWorkflowVariables(Workflow workflow, TriggerParam param) { if (workflow.WorkflowVariables.Count > 0) { foreach (var workflowVariable in workflow.WorkflowVariables) { var type = KeyBuilder.FromKey(workflowVariable.Type); var variable = JsonConvert.DeserializeObject(workflowVariable.Content, type); var workflowVariableBase = variable as WorkflowVariableBase; if (workflowVariableBase != null) { var key = KeyBuilder.ToKey(type); if (param.Variables.ContainsKey(key)) { param.Variables[key] = variable as WorkflowVariableBase; } else { param.Variables.Add(key, variable as WorkflowVariableBase); } } } } }
public Trigger(TriggerParam triggerParam, string name) { Param = triggerParam; Name = name; }
public Trigger(TriggerParam triggerParam) : this(triggerParam, "") { }
private bool WorkflowIsCompleted(TriggerParam triggerParam) { var triggerResults = this.GetTriggers(triggerParam.Instance, triggerParam.Variables); return(triggerResults.Count() == 0); }
public async Task <TriggerResult> TriggerAsync(TriggerParam param) { if (param == null) { throw new ArgumentNullException(nameof(param)); } _logger.LogTrace("TriggerAsync {Instance}", JsonConvert.SerializeObject( param.Instance, new JsonSerializerSettings { Formatting = Formatting.Indented, ReferenceLoopHandling = ReferenceLoopHandling.Ignore }) ); var entity = param.Instance as IEntityWorkflow; if (entity == null) { // going the non EF way! var execution = GetExecution(param.Instance.Type); return(execution.Trigger(param)); } TriggerResult result = null; using (var transaction = _context.Database.BeginTransaction()) { try { Workflow workflow = null; var execution = GetExecution(param.Instance.Type); await _context.SaveChangesAsync(); // so entity id gets resolved! workflow = FindOrCreate( entity.Id, param.Instance.Type, param.Instance.State, entity.Assignee ); EnsureWorkflowVariables(workflow, param); result = execution.Trigger(param); if (!result.IsAborted) { await PersistWorkflow(workflow, param); await _context.SaveChangesAsync(); transaction.Commit(); } } catch (Exception ex) { transaction.Rollback(); _logger.LogError( "TriggerAsync", ex, "TriggerAsync failed: {Param}", JsonConvert.SerializeObject(param, new JsonSerializerSettings { Formatting = Formatting.Indented, ReferenceLoopHandling = ReferenceLoopHandling.Ignore }) ); var transitionContext = new TransitionContext(param.Instance); transitionContext.AddError(ex.ToString()); result = new TriggerResult( param.TriggerName, transitionContext, false ); } } return(result); }
protected void DefaultPointerDown(BaseEventData eventData, TriggerParam param) { }
private void StartTask() { if (this._cancellationTokenSource != null) { return; //running } this._cancellationTokenSource = new CancellationTokenSource(); var ct = this._cancellationTokenSource.Token; this._runTask = Task.Factory.StartNew(async() => { //ct.ThrowIfCancellationRequested(); while (!ct.IsCancellationRequested) { if (TASK_QUEUE.IsEmpty) { break; } ReturnT result = null; TriggerParam triggerParam = null; try { if (TASK_QUEUE.TryDequeue(out triggerParam)) { if (!ID_IN_QUEUE.TryRemove(triggerParam.LogId, out _)) { this._logger.LogWarning("remove queue failed,logId={logId},jobId={jobId},exists={exists}" , triggerParam.LogId, triggerParam.JobId, ID_IN_QUEUE.ContainsKey(triggerParam.LogId)); } //set log file; this._jobLogger.SetLogFile(triggerParam.LogDateTime, triggerParam.LogId); this._jobLogger.Log("<br>----------- xxl-job job execute start -----------<br>----------- Param:{0}", triggerParam.ExecutorParams); result = await this._executor.Execute(triggerParam); this._jobLogger.Log("<br>----------- xxl-job job execute end(finish) -----------<br>----------- ReturnT:" + result.Code); } else { this._logger.LogWarning("Dequeue Task Failed"); } } catch (Exception ex) { result = ReturnT.Failed("Dequeue Task Failed:" + ex.Message); this._jobLogger.Log("<br>----------- JobThread Exception:" + ex.Message + "<br>----------- xxl-job job execute end(error) -----------"); } if (triggerParam != null) { CallBack?.Invoke(this, new HandleCallbackParam(triggerParam, result ?? ReturnT.FAIL)); } } this._cancellationTokenSource.Dispose(); this._cancellationTokenSource = null; }, this._cancellationTokenSource.Token); }
public void Process(JobKey key, Report report, TriggerParam tparam) { // записали в историю запусков string mailTo = null; if (tparam.MailTo != null && tparam.MailTo.Count > 0) { mailTo = String.Join(",", tparam.MailTo); } var reportRunLog = new ReportRunLog() { JobName = key.Name, RunNow = false, MailTo = mailTo, AccountId = tparam.UserId }; // записали IP только для ручного запуска var ip = "неизвестен (авт. запуск)"; if (tparam is RunNowParam) { ip = ((RunNowParam)tparam).Ip; reportRunLog.Ip = ip; reportRunLog.RunNow = true; } db.ReportRunLog.Add(reportRunLog); db.SaveChanges(); // вытащили расширенные параметры задачи var jext = db.jobextend.Single(x => x.JobName == key.Name && x.JobGroup == key.Group && x.Enable); // добавили сведения о последнем запуске jext.LastRun = DateTime.Now; db.SaveChanges(); var querySort = report.Read <T>(); var user = db.Account.First(x => x.Id == tparam.UserId); user.IP = ip; var mail = new EmailSender(db, new Context(), user); // действия при пустом отчете if (querySort.Count == 0) { jext.DisplayStatusEnum = DisplayStatus.Empty; db.Entry(jext).State = EntityState.Modified; db.SaveChanges(); mail.SendEmptyReportMessage(jext); return; } var reportRow = (ReportRow)Activator.CreateInstance(_type); querySort = reportRow.Treatment(querySort, report); var shredder = new ObjectShredder <T>(); var dataTable = shredder.Shred(querySort); var headers = report.GetHeaders(_helper); var ds = CreateDataSet(report.CastomName, headers, dataTable); // записали XML var sw = new StringWriter(); ds.WriteXml(sw, XmlWriteMode.WriteSchema); // сохранили в базу var jxml = db.reportxml.SingleOrDefault(x => x.JobName == key.Name && x.JobGroup == key.Group); if (jxml == null) { jxml = new reportxml() { JobName = key.Name, JobGroup = key.Group, SchedName = jext.SchedName, Xml = sw.ToString() }; db.reportxml.Add(jxml); } else { jxml.Xml = sw.ToString(); } // отправили статус, что отчет готов jext.DisplayStatusEnum = DisplayStatus.Ready; db.Entry(jext).State = EntityState.Modified; db.SaveChanges(); // если указаны email - отправляем if (tparam.MailTo != null && tparam.MailTo.Count > 0) { // создали excel-файл var file = CreateExcel(key.Group, key.Name, ds, report); // при автоматическом и ручном запуске разное содержимое письма if (tparam is CronParam) { mail.AutoPostReportMessage(jext, file.FullName, tparam.MailTo); } else if (tparam is RunNowParam) { mail.ManualPostReportMessage(jext, file.FullName, tparam.MailTo); } } }