DbJobPersistence.cs 5.6 KB

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