DbJobPersistence.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. using Microsoft.Extensions.DependencyInjection;
  2. namespace Admin.NET.Core.Service;
  3. /// <summary>
  4. /// 作业持久化(数据库)
  5. /// </summary>
  6. public class DbJobPersistence : IJobPersistence
  7. {
  8. private readonly IServiceProvider _serviceProvider;
  9. public DbJobPersistence(IServiceProvider serviceProvider)
  10. {
  11. _serviceProvider = serviceProvider;
  12. }
  13. /// <summary>
  14. /// 作业调度服务启动时
  15. /// </summary>
  16. /// <returns></returns>
  17. public IEnumerable<SchedulerBuilder> Preload()
  18. {
  19. using var serviceScope = _serviceProvider.CreateScope();
  20. var jobDetailRep = serviceScope.ServiceProvider.GetService<SqlSugarRepository<SysJobDetail>>();
  21. var jobTriggerRep = serviceScope.ServiceProvider.GetService<SqlSugarRepository<SysJobTrigger>>();
  22. // 获取内存的作业
  23. IEnumerable<SchedulerBuilder> memoryJobs = App.EffectiveTypes.ScanToBuilders();
  24. // 若数据库不存在任何作业,则返回内存作业
  25. if (!jobDetailRep.IsAny(u => true)) return memoryJobs;
  26. var schedulerBuilders = new List<SchedulerBuilder>();
  27. // 获取数据库所有作业
  28. var dbJobs = jobDetailRep.GetList();
  29. foreach (var dbJob in dbJobs)
  30. {
  31. var jobDetail = JobBuilder.Create(dbJob.AssemblyName, dbJob.JobType).LoadFrom(dbJob);
  32. // 加载数据库的触发器
  33. var triggerBuilders = new List<TriggerBuilder>();
  34. var dbTriggers = jobTriggerRep.GetList(u => u.JobId == dbJob.JobId)
  35. .Select(u => Triggers.Create(u.AssemblyName, u.TriggerType).LoadFrom(u)).ToArray();
  36. triggerBuilders.AddRange(dbTriggers);
  37. var memoryTriggers = memoryJobs.Where(u => u.GetJobBuilder().JobId == dbJob.JobId).SelectMany(u => u.GetTriggerBuilders());
  38. foreach (var memTrigger in memoryTriggers)
  39. {
  40. var triggerId = memTrigger.TriggerId;
  41. // 若数据库中已包含这个触发器
  42. if (!string.IsNullOrWhiteSpace(triggerId) && dbTriggers.Any(u => u.TriggerId == triggerId))
  43. continue;
  44. triggerBuilders.Add(memTrigger);
  45. }
  46. schedulerBuilders.Add(SchedulerBuilder.Create(jobDetail, triggerBuilders.ToArray()).Updated());
  47. }
  48. // 合并作业
  49. foreach (var job in memoryJobs)
  50. {
  51. var jobId = job.GetJobBuilder().JobId;
  52. // 若数据库中已包含这个作业
  53. if (!string.IsNullOrWhiteSpace(jobId) && dbJobs.Any(u => u.JobId == jobId))
  54. continue;
  55. schedulerBuilders.Add(job);
  56. }
  57. return schedulerBuilders;
  58. }
  59. /// <summary>
  60. /// 作业计划初始化通知
  61. /// </summary>
  62. /// <param name="builder"></param>
  63. /// <returns></returns>
  64. public SchedulerBuilder OnLoading(SchedulerBuilder builder)
  65. {
  66. using var serviceScope = _serviceProvider.CreateScope();
  67. var jobDetailRep = serviceScope.ServiceProvider.GetService<SqlSugarRepository<SysJobDetail>>();
  68. var jobTriggerRep = serviceScope.ServiceProvider.GetService<SqlSugarRepository<SysJobTrigger>>();
  69. //return rep.IsAny(u => u.JobId != builder.GetJobBuilder().JobId) ? builder.Appended() : builder.Updated();
  70. foreach (var (jobBuilder, triggerBuilder) in builder.GetEnumerable())
  71. {
  72. if (jobTriggerRep.IsAny(u => u.JobId == jobBuilder.JobId && u.TriggerId == triggerBuilder.TriggerId))
  73. triggerBuilder.Updated();
  74. else
  75. triggerBuilder.Appended();
  76. }
  77. return builder;
  78. }
  79. /// <summary>
  80. /// 作业计划Scheduler的JobDetail变化时
  81. /// </summary>
  82. /// <param name="context"></param>
  83. public void OnChanged(PersistenceContext context)
  84. {
  85. using var serviceScope = _serviceProvider.CreateScope();
  86. var db = serviceScope.ServiceProvider.GetService<ISqlSugarClient>();
  87. var jobDetail = context.JobDetail.Adapt<SysJobDetail>();
  88. if (context.Behavior == PersistenceBehavior.Appended)
  89. {
  90. db.Insertable(jobDetail).ExecuteCommand();
  91. }
  92. else if (context.Behavior == PersistenceBehavior.Updated)
  93. {
  94. db.Updateable(jobDetail).WhereColumns(u => new { u.JobId }).IgnoreColumns(u => new { u.Id }).ExecuteCommand();
  95. }
  96. else if (context.Behavior == PersistenceBehavior.Removed)
  97. {
  98. db.Deleteable<SysJobDetail>().Where(u => u.JobId == jobDetail.JobId).ExecuteCommand();
  99. }
  100. }
  101. /// <summary>
  102. /// 作业计划Scheduler的触发器Trigger变化时
  103. /// </summary>
  104. /// <param name="context"></param>
  105. public void OnTriggerChanged(PersistenceTriggerContext context)
  106. {
  107. using var serviceScope = _serviceProvider.CreateScope();
  108. var db = serviceScope.ServiceProvider.GetService<ISqlSugarClient>();
  109. var jobTrigger = context.Trigger.Adapt<SysJobTrigger>();
  110. if (context.Behavior == PersistenceBehavior.Appended)
  111. {
  112. db.Insertable(jobTrigger).ExecuteCommand();
  113. }
  114. else if (context.Behavior == PersistenceBehavior.Updated)
  115. {
  116. db.Updateable(jobTrigger).WhereColumns(u => new { u.TriggerId, u.JobId }).IgnoreColumns(u => new { u.Id }).ExecuteCommand();
  117. }
  118. else if (context.Behavior == PersistenceBehavior.Removed)
  119. {
  120. db.Deleteable<SysJobTrigger>().Where(u => u.TriggerId == jobTrigger.TriggerId && u.JobId == jobTrigger.JobId).ExecuteCommand();
  121. }
  122. }
  123. }