From e71936063d76678f6748689aa6166a895c7072c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=B7=B3?= <454313500@qq.com> Date: Fri, 12 Jan 2024 17:18:39 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=88=9D=E6=AD=A5=E6=90=AD=E5=BB=BA?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E8=B0=83=E5=BA=A6=E7=AE=A1=E7=90=86=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Dtos/Task/TaskGetOutput.cs | 35 +- .../Services/TaskService.cs | 333 ++++++++++-------- 2 files changed, 192 insertions(+), 176 deletions(-) diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application.Contracts/Dtos/Task/TaskGetOutput.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application.Contracts/Dtos/Task/TaskGetOutput.cs index 824e3e7b..1a00c57f 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application.Contracts/Dtos/Task/TaskGetOutput.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application.Contracts/Dtos/Task/TaskGetOutput.cs @@ -7,74 +7,59 @@ /// 作业 Id /// - public string JobId { get; internal set; } + public string JobId { get; set; } /// /// 作业组名称 /// - public string GroupName { get; internal set; } + public string GroupName { get; set; } /// /// 作业处理程序类型 /// /// 存储的是类型的 FullName - public string JobType { get; internal set; } + public string JobType { get; set; } /// /// 作业处理程序类型所在程序集 /// /// 存储的是程序集 Name - public string AssemblyName { get; internal set; } + public string AssemblyName { get; set; } /// /// 描述信息 /// - public string Description { get; internal set; } + public string Description { get; set; } /// /// 是否采用并行执行 /// /// 如果设置为 false,那么使用串行执行 - public bool Concurrent { get; internal set; } = true; + public bool Concurrent { get; set; } = true; /// /// 是否扫描 IJob 实现类 [Trigger] 特性触发器 /// - public bool IncludeAnnotations { get; internal set; } = false; + public bool IncludeAnnotations { get; set; } = false; /// /// 作业信息额外数据 /// - public string Properties { get; internal set; } = "{}"; + public string Properties { get; set; } = "{}"; /// /// 作业更新时间 /// - public DateTime? UpdatedTime { get; internal set; } - - /// - /// 标记其他作业正在执行 - /// - /// 为 false 时有效,也就是串行执行 - internal bool Blocked { get; set; } = false; - - /// - /// 作业处理程序运行时类型 - /// - internal string RuntimeJobType { get; set; } - - /// - /// 作业信息额外数据运行时实例 - /// - internal string RuntimeProperties { get; set; } + public DateTime? UpdatedTime { get; set; } + public string TriggerArgs { get; set; } diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/TaskService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/TaskService.cs index fd74c322..d299ec88 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/TaskService.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/TaskService.cs @@ -1,171 +1,202 @@ -using Volo.Abp.Application.Services; +using System.Reflection; +using Mapster; +using Microsoft.AspNetCore.Mvc; +using Quartz; +using Quartz.Impl.Matchers; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; +using Yi.Framework.Rbac.Application.Contracts.Dtos.Task; using Yi.Framework.Rbac.Application.Contracts.IServices; +using Yi.Framework.Rbac.Domain.Shared.Enums; namespace Yi.Framework.Rbac.Application.Services { public class TaskService : ApplicationService, ITaskService { - //private readonly ISchedulerFactory _schedulerFactory; - //public TaskService(ISchedulerFactory schedulerFactory) - //{ - // _schedulerFactory = schedulerFactory; - //} - ///// - ///// 单查job - ///// - ///// - ///// - //[HttpGet("{jobId}")] - //public TaskGetOutput GetById([FromRoute] string jobId) - //{ - // var result = _schedulerFactory.TryGetJob(jobId, out var scheduler); - // var data = scheduler.GetModel(); - // var output = data.JobDetail.Adapt(); - // output.TriggerArgs = data.Triggers[0].Args; - // output.NextRunTime = data.Triggers[0].NextRunTime; - // output.LastRunTime = data.Triggers[0].LastRunTime; - // output.NumberOfRuns = data.Triggers[0].NumberOfRuns; - // return output; - //} - - ///// - ///// 多查job - ///// - ///// - //[HttpGet("")] - //public PagedResultDto GetList([FromQuery] TaskGetListInput input) - //{ - // var data = _schedulerFactory.GetJobsOfModels().Skip((input.PageNum - 1) * input.PageSize).Take(input.PageSize).OrderByDescending(x => x.JobDetail.UpdatedTime) - - // .ToList(); - // var output = data.Select(x => - // { - - // var res = new TaskGetListOutput(); - // res = x.JobDetail.Adapt(); - // res.TriggerArgs = x.Triggers[0].Args; - // res.Status = x.Triggers[0].Status.ToString(); - // return res; - // }).ToList(); - // return new PagedResultDto(data.Count(), output); - //} - - ///// - ///// 创建job - ///// - ///// - ///// - //public ScheduleResult Create(TaskCreateInput input) - //{ + private readonly ISchedulerFactory _schedulerFactory; + public TaskService(ISchedulerFactory schedulerFactory) + { + _schedulerFactory = schedulerFactory; + } - // //jobBuilder - // var jobBuilder = JobBuilder.Create(input.AssemblyName, input.JobType).SetJobId(input.JobId).SetGroupName(input.GroupName) - // .SetConcurrent(input.Concurrent).SetDescription(input.Description); + /// + /// 单查job + /// + /// + /// + [HttpGet("{jobId}")] + public async Task GetByIdAsync([FromRoute] string jobId) + { + var scheduler = await _schedulerFactory.GetScheduler(); - // //triggerBuilder - // //毫秒 - // TriggerBuilder triggerBuilder = null; - // switch (input.Type) - // { - // case Core.Rbac.Enums.JobTypeEnum.Cron: - // triggerBuilder = Triggers.Cron(input.Cron, CronStringFormat.WithSeconds); - // break; - // case Core.Rbac.Enums.JobTypeEnum.Millisecond: - // triggerBuilder = Triggers.Period(input.Millisecond); - // break; - // } + var jobDetail = await scheduler.GetJobDetail(new JobKey(jobId)); + var trigger = (await scheduler.GetTriggersOfJob(new JobKey(jobId))).First(); + //状态 + var state = await scheduler.GetTriggerState(trigger.Key); + var output = new TaskGetOutput + { + JobId = jobDetail.Key.Name, + GroupName = jobDetail.Key.Group, + JobType = jobDetail.JobType.Name, + Properties = Newtonsoft.Json.JsonConvert.SerializeObject(jobDetail.JobDataMap), + Concurrent = !jobDetail.ConcurrentExecutionDisallowed, + Description = jobDetail.Description, + LastRunTime = trigger.GetPreviousFireTimeUtc()?.DateTime, + }; - // //作业计划,单个jobBuilder与多个triggerBuilder组合 - // var schedulerBuilder = SchedulerBuilder.Create(jobBuilder, triggerBuilder); + if (trigger is ISimpleTrigger simple) + { + output.TriggerArgs = simple.RepeatInterval.TotalMilliseconds.ToString() + "毫秒"; + + } + else if (trigger is ICronTrigger cron) + { + output.TriggerArgs = cron.CronExpressionString!; + } + return output; + } + + /// + /// 多查job + /// + /// + [HttpGet("")] + public async Task> GetList([FromQuery] TaskGetListInput input) + { + var items = new List(); + + var scheduler = await _schedulerFactory.GetScheduler(); + + var groups = await scheduler.GetJobGroupNames(); + + foreach (var groupName in groups) + { + foreach (var jobKey in await scheduler.GetJobKeys(GroupMatcher.GroupEquals(groupName))) + { + string jobName = jobKey.Name; + string jobGroup = jobKey.Group; + var triggers = (await scheduler.GetTriggersOfJob(jobKey)).First(); + items.Add(await GetByIdAsync(jobName)); + } + } - // //调度中心工厂,使用作业计划管理job,返回调度中心单个 - // var result = _schedulerFactory.TryAddJob(schedulerBuilder, out var scheduler); + var output = items.Skip((input.SkipCount - 1) * input.MaxResultCount).Take(input.MaxResultCount) + .OrderByDescending(x => x.LastRunTime) + .ToList(); + return new PagedResultDto(items.Count(), output.Adapt>()); + } - // return result; - //} + /// + /// 创建job + /// + /// + /// + public async Task Create(TaskCreateInput input) + { + var scheduler = await _schedulerFactory.GetScheduler(); - ///// - ///// 移除job - ///// - ///// - ///// - //public ScheduleResult Remove(string jobId) - //{ - // var res = _schedulerFactory.TryRemoveJob(jobId, out var scheduler); - // return res; - //} - - ///// - ///// 暂停job - ///// - ///// - ///// - //[HttpPut] - //public ScheduleResult Pause(string jobId) - //{ - // var res = _schedulerFactory.TryGetJob(jobId, out var scheduler); - - // scheduler.Pause(); - // return res; - //} - - ///// - ///// 开始job - ///// - ///// - ///// - //[HttpPut] - //public ScheduleResult Start(string jobId) - //{ - // var res = _schedulerFactory.TryGetJob(jobId, out var scheduler); - // scheduler.Start(); - // return res; - //} - - ///// - ///// 更新job - ///// - ///// - ///// - ///// - //public ScheduleResult Update(string jobId, TaskUpdateInput input) - //{ - // //jobBuilder - // var jobBuilder = JobBuilder.Create(input.AssemblyName, input.JobType).SetJobId(jobId).SetGroupName(input.GroupName) - // .SetConcurrent(input.Concurrent).SetDescription(input.Description); - - // //triggerBuilder - // //毫秒 - // TriggerBuilder triggerBuilder = null; - // switch (input.Type) - // { - // case Core.Rbac.Enums.JobTypeEnum.Cron: - // triggerBuilder = Triggers.Cron(input.Cron, CronStringFormat.WithSeconds); - // break; - // case Core.Rbac.Enums.JobTypeEnum.Millisecond: - // triggerBuilder = Triggers.Period(input.Millisecond); - // break; - // } - - // //作业计划,单个jobBuilder与多个triggerBuilder组合 - // var schedulerBuilder = SchedulerBuilder.Create(jobBuilder, triggerBuilder); + //设置启动时执行一次,然后最大只执行一次 - // var result = _schedulerFactory.TryUpdateJob(schedulerBuilder, out var scheduler); - // return result; - //} + //jobBuilder + var jobClassType = Assembly.LoadFrom(input.AssemblyName).GetType(input.JobType); - //[HttpPost] - //public bool RunOnce(string jobId) - //{ - // var result = _schedulerFactory.TryGetJob(jobId, out var scheduler); + var jobBuilder = JobBuilder.Create(jobClassType).WithIdentity(new JobKey(input.JobId, input.GroupName)) + .WithDescription(input.Description); + if (!input.Concurrent) + { + jobBuilder.DisallowConcurrentExecution(); + } - // var triggerBuilder = Triggers.Period(100).SetRunOnStart(true).SetMaxNumberOfRuns(1); - // scheduler.AddTrigger(triggerBuilder); - // //设置启动时执行一次,然后最大只执行一次 - // return true; - //} + //triggerBuilder + TriggerBuilder triggerBuilder = null; + switch (input.Type) + { + case JobTypeEnum.Cron: + triggerBuilder = + TriggerBuilder.Create().StartNow() + .WithCronSchedule(input.Cron); + + + + + break; + case JobTypeEnum.Millisecond: + triggerBuilder = + TriggerBuilder.Create().StartNow() + .WithSimpleSchedule(x => x + .WithInterval(TimeSpan.FromMilliseconds(input.Millisecond)) + .RepeatForever() + ); + break; + } + + //作业计划,单个jobBuilder与多个triggerBuilder组合 + await scheduler.ScheduleJob(jobBuilder.Build(), triggerBuilder.Build()); + } + + /// + /// 移除job + /// + /// + /// + public async Task Remove(string jobId) + { + var scheduler = await _schedulerFactory.GetScheduler(); + await scheduler.ResumeJob(new JobKey(jobId)); + } + + /// + /// 暂停job + /// + /// + /// + [HttpPut] + public async Task Pause(string jobId) + { + var scheduler = await _schedulerFactory.GetScheduler(); + await scheduler.PauseJob(new JobKey(jobId)); + } + + /// + /// 开始job + /// + /// + /// + [HttpPut] + public async Task Start(string jobId) + { + var scheduler = await _schedulerFactory.GetScheduler(); + await scheduler.ResumeJob(new JobKey(jobId)); + } + + /// + /// 更新job + /// + /// + /// + /// + public async Task Update(string jobId, TaskUpdateInput input) + { + await Remove(jobId); + await Create(input.Adapt()); + } + + [HttpPost] + public async Task RunOnce(string jobId) + { + var scheduler = await _schedulerFactory.GetScheduler(); + var jobDetail = await scheduler.GetJobDetail(new JobKey(jobId)); + + //设置启动时执行一次,然后最大只执行一次 + var trigger = TriggerBuilder.Create().WithIdentity(Guid.NewGuid().ToString()).StartNow() + .WithSimpleSchedule(x => x + .WithRepeatCount(1)) + .Build(); + + await scheduler.ScheduleJob(jobDetail, trigger); + } } }