Преглед изворни кода

修复任务调度持久化时重复问题

zuohuaijun пре 3 година
родитељ
комит
08f80cef5c

+ 62 - 2
Admin.NET/Admin.NET.Core/Service/Job/DbJobPersistence.cs

@@ -1,4 +1,6 @@
-namespace Admin.NET.Core.Service;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Admin.NET.Core.Service;
 
 /// <summary>
 /// 作业持久化(数据库)
@@ -18,7 +20,53 @@ public class DbJobPersistence : IJobPersistence
     /// <returns></returns>
     public IEnumerable<SchedulerBuilder> Preload()
     {
-        return App.EffectiveTypes.ScanToBuilders();
+        using var serviceScope = _serviceProvider.CreateScope();
+        var jobDetailRep = serviceScope.ServiceProvider.GetService<SqlSugarRepository<SysJobDetail>>();
+        var jobTriggerRep = serviceScope.ServiceProvider.GetService<SqlSugarRepository<SysJobTrigger>>();
+
+        // 获取内存的作业
+        IEnumerable<SchedulerBuilder> memoryJobs = App.EffectiveTypes.ScanToBuilders();
+
+        // 若数据库不存在任何作业,则返回内存作业
+        if (!jobDetailRep.IsAny(u => true)) return memoryJobs;
+
+        var schedulerBuilders = new List<SchedulerBuilder>();
+
+        // 获取数据库所有作业
+        var dbJobs = jobDetailRep.GetList();
+        foreach (var dbJob in dbJobs)
+        {
+            var jobDetail = JobBuilder.Create(dbJob.AssemblyName, dbJob.JobType).LoadFrom(dbJob);
+
+            // 加载数据库的触发器
+            var triggerBuilders = new List<TriggerBuilder>();
+            var dbTriggers = jobTriggerRep.GetList(u => u.JobId == dbJob.JobId)
+                .Select(u => Triggers.Create(u.AssemblyName, u.TriggerType).LoadFrom(u)).ToArray();
+            triggerBuilders.AddRange(dbTriggers);
+
+            var memoryTriggers = memoryJobs.Where(u => u.GetJobBuilder().JobId == dbJob.JobId).SelectMany(u => u.GetTriggerBuilders());
+            foreach (var memTrigger in memoryTriggers)
+            {
+                var triggerId = memTrigger.TriggerId;
+                // 若数据库中已包含这个触发器
+                if (!string.IsNullOrWhiteSpace(triggerId) && dbTriggers.Any(u => u.TriggerId == triggerId))
+                    continue;
+                triggerBuilders.Add(memTrigger);
+            }
+            schedulerBuilders.Add(SchedulerBuilder.Create(jobDetail, triggerBuilders.ToArray()).Updated());
+        }
+
+        // 合并作业
+        foreach (var job in memoryJobs)
+        {
+            var jobId = job.GetJobBuilder().JobId;
+            // 若数据库中已包含这个作业
+            if (!string.IsNullOrWhiteSpace(jobId) && dbJobs.Any(u => u.JobId == jobId))
+                continue;
+            schedulerBuilders.Add(job);
+        }
+
+        return schedulerBuilders;
     }
 
     /// <summary>
@@ -28,6 +76,18 @@ public class DbJobPersistence : IJobPersistence
     /// <returns></returns>
     public SchedulerBuilder OnLoading(SchedulerBuilder builder)
     {
+        using var serviceScope = _serviceProvider.CreateScope();
+        var jobDetailRep = serviceScope.ServiceProvider.GetService<SqlSugarRepository<SysJobDetail>>();
+        var jobTriggerRep = serviceScope.ServiceProvider.GetService<SqlSugarRepository<SysJobTrigger>>();
+        //return rep.IsAny(u => u.JobId != builder.GetJobBuilder().JobId) ? builder.Appended() : builder.Updated();
+
+        foreach (var (jobBuilder, triggerBuilder) in builder.GetEnumerable())
+        {
+            if (jobTriggerRep.IsAny(u => u.JobId == jobBuilder.JobId && u.TriggerId == triggerBuilder.TriggerId))
+                triggerBuilder.Updated();
+            else
+                triggerBuilder.Appended();
+        }
         return builder;
     }
 

+ 1 - 1
Admin.NET/Admin.NET.Core/Service/Job/SysJobService.cs

@@ -113,7 +113,7 @@ public class SysJobService : IDynamicApiController, ITransient
         if (isExist)
             throw Oops.Oh(ErrorCodeEnum.D1006);
 
-        await _sysJobTriggerRep.UpdateAsync(input.Adapt<SysJobTrigger>());
+        await _sysJobTriggerRep.InsertAsync(input.Adapt<SysJobTrigger>());
     }
 
     /// <summary>

+ 3 - 3
Web/src/views/system/job/index.vue

@@ -141,7 +141,7 @@
 				<el-table-column label="操作" width="170" fixed="right" align="center" show-overflow-tooltip>
 					<template #default="scope">
 						<el-tooltip content="增加触发器">
-							<el-button size="small" type="primary" icon="ele-CirclePlus" text @click="openAddJobTrigger"> </el-button>
+							<el-button size="small" type="primary" icon="ele-CirclePlus" text @click="openAddJobTrigger(scope.row)"> </el-button>
 						</el-tooltip>
 						<el-tooltip content="启动作业">
 							<el-button size="small" type="primary" icon="ele-VideoPlay" text @click="startJob(scope.row)" />
@@ -260,9 +260,9 @@ export default defineComponent({
 				.catch(() => {});
 		};
 		// 打开新增触发器页面
-		const openAddJobTrigger = () => {
+		const openAddJobTrigger = (row: any) => {
 			state.editJobTriggerTitle = '添加触发器';
-			editJobTriggerRef.value.openDialog({ retryTimeout: 1000, startNow: true, runOnStart: true, resetOnlyOnce: true });
+			editJobTriggerRef.value.openDialog({ jobId: row.jobDetail.jobId, retryTimeout: 1000, startNow: true, runOnStart: true, resetOnlyOnce: true });
 		};
 		// 打开编辑触发器页面
 		const openEditJobTrigger = (row: any) => {