/// <summary>申请任务分片</summary> /// <param name="topic">主题</param> /// <param name="server">申请任务的服务端</param> /// <param name="ip">申请任务的IP</param> /// <param name="pid">申请任务的服务端进程ID</param> /// <param name="count">要申请的任务个数</param> /// <param name="cache">用于设置全局锁的缓存对象</param> /// <returns></returns> public IList <JobTask> AcquireMessage(String topic, String server, String ip, Int32 pid, Int32 count, ICache cache) { // 消费消息时,保存主题 if (Topic != topic) { Topic = topic; SaveAsync(); } var list = new List <JobTask>(); if (!Enable) { return(list); } // 验证消息数 var now = DateTime.Now; if (MessageCount == 0 && UpdateTime.AddMinutes(2) > now) { return(list); } //// 全局锁,确保单个作业只有一个线程在分配作业 //using var ck = cache.AcquireLock($"Job:{ID}", 5_000); using var ts = Meta.CreateTrans(); var size = BatchSize; if (size == 0) { size = 1; } // 消费消息。请求任务数量=空闲线程*批大小 var msgs = AppMessage.GetTopic(AppID, topic, now, count * size); if (msgs.Count > 0) { for (var i = 0; i < msgs.Count;) { var msgList = msgs.Skip(i).Take(size).ToList(); if (msgList.Count == 0) { break; } i += msgList.Count; // 创建新的分片 var ti = new JobTask { AppID = AppID, JobID = ID, Data = msgList.Select(e => e.Data).ToJson(), MsgCount = msgList.Count, BatchSize = size, }; ti.Server = server; ti.ProcessID = Interlocked.Increment(ref _idxBatch); ti.Client = $"{ip}@{pid}"; ti.Status = JobStatus.就绪; ti.CreateTime = DateTime.Now; ti.UpdateTime = DateTime.Now; ti.Insert(); // 从去重缓存去掉 cache.Remove(msgList.Select(e => $"{AppID}:{Topic}:{e}").ToArray()); list.Add(ti); } // 批量删除消息 msgs.Delete(); } // 更新作业下的消息数 MessageCount = AppMessage.FindCountByAppIDAndTopic(AppID, topic); UpdateTime = now; Save(); // 消费完成后,更新应用的消息数 if (MessageCount == 0) { var app = App; if (app != null) { app.MessageCount = AppMessage.FindCountByAppID(ID); app.SaveAsync(); } } ts.Commit(); return(list); }
/// <summary>申请任务分片</summary> /// <param name="topic">主题</param> /// <param name="server">申请任务的服务端</param> /// <param name="ip">申请任务的IP</param> /// <param name="pid">申请任务的服务端进程ID</param> /// <param name="count">要申请的任务个数</param> /// <returns></returns> public IList <JobTask> AcquireMessage(String topic, String server, String ip, Int32 pid, Int32 count) { // 消费消息时,保存主题 if (Topic != topic) { Topic = topic; SaveAsync(); } var list = new List <JobTask>(); if (!Enable) { return(list); } // 验证消息数 var now = DateTime.Now; if (MessageCount == 0 && UpdateTime.AddMinutes(2) > now) { return(list); } lock (this) { using (var ts = Meta.CreateTrans()) { var size = BatchSize; if (size == 0) { size = 1; } // 消费消息。请求任务数量=空闲线程*批大小 var msgs = AppMessage.GetTopic(AppID, topic, now, count * size); if (msgs.Count > 0) { for (var i = 0; i < msgs.Count;) { var msgList = msgs.Skip(i).Take(size).ToList(); if (msgList.Count == 0) { break; } i += msgList.Count; // 创建新的分片 var ti = new JobTask { AppID = AppID, JobID = ID, Data = msgList.Select(e => e.Data).ToJson(), MsgCount = msgList.Count, BatchSize = size, }; ti.Server = server; ti.ProcessID = pid; ti.Client = $"{ip}@{pid}"; ti.Status = JobStatus.就绪; ti.CreateTime = DateTime.Now; ti.UpdateTime = DateTime.Now; ti.Insert(); list.Add(ti); } // 批量删除消息 msgs.Delete(); } // 更新作业下的消息数 MessageCount = AppMessage.FindCountByAppIDAndTopic(AppID, topic); UpdateTime = now; Save(); // 消费完成后,更新应用的消息数 if (MessageCount == 0) { var app = App; if (app != null) { app.MessageCount = AppMessage.FindCountByAppID(ID); app.SaveAsync(); } } ts.Commit(); return(list); } } }
/// <summary>申请任务分片</summary> /// <param name="server">申请任务的服务端</param> /// <param name="ip">申请任务的IP</param> /// <param name="pid">申请任务的服务端进程ID</param> /// <param name="count">要申请的任务个数</param> /// <param name="cache">用于设置全局锁的缓存对象</param> /// <returns></returns> public IList <JobTask> Acquire(String server, String ip, Int32 pid, Int32 count, ICache cache) { var list = new List <JobTask>(); if (!Enable) { return(list); } var step = Step; if (step <= 0) { step = 30; } //// 全局锁,确保单个作业只有一个线程在分配作业 //using var ck = cache.AcquireLock($"Job:{ID}", 5_000); using var ts = Meta.CreateTrans(); var start = Start; for (var i = 0; i < count; i++) { if (!TrySplit(start, step, out var end)) { break; } // 创建新的分片 var ti = new JobTask { AppID = AppID, JobID = ID, Start = start, End = end, BatchSize = BatchSize, }; ti.Server = server; ti.ProcessID = Interlocked.Increment(ref _idxBatch); ti.Client = $"{ip}@{pid}"; ti.Status = JobStatus.就绪; ti.CreateTime = DateTime.Now; ti.UpdateTime = DateTime.Now; //// 如果有模板,则进行计算替换 //if (!Data.IsNullOrEmpty()) ti.Data = TemplateHelper.Build(Data, ti.Start, ti.End); // 重复切片判断 var key = $"Job:{ID}:{start:yyyyMMddHHmmss}"; if (!cache.Add(key, ti, 30)) { var ti2 = cache.Get <JobTask>(key); XTrace.WriteLine("[{0}]重复切片:{1}", key, ti2?.ToJson()); using var span = DefaultTracer.Instance?.NewSpan($"antjob:AcquireDuplicate", ti2); } else { ti.Insert(); list.Add(ti); } // 更新任务 Start = end; start = end; } if (list.Count > 0) { // 任务需要ID,不能批量插入优化 //list.Insert(null); UpdateTime = DateTime.Now; Save(); ts.Commit(); } return(list); }
/// <summary>申请任务分片</summary> /// <param name="server">申请任务的服务端</param> /// <param name="ip">申请任务的IP</param> /// <param name="pid">申请任务的服务端进程ID</param> /// <param name="count">要申请的任务个数</param> /// <returns></returns> public IList <JobTask> Acquire(String server, String ip, Int32 pid, Int32 count) { var list = new List <JobTask>(); if (!Enable) { return(list); } var step = Step; if (step <= 0) { step = 30; } lock (this) { using (var ts = Meta.CreateTrans()) { var start = Start; for (var i = 0; i < count; i++) { if (!TrySplit(start, step, out var end)) { break; } // 创建新的分片 var ti = new JobTask { AppID = AppID, JobID = ID, Start = start, End = end, BatchSize = BatchSize, }; ti.Server = server; ti.ProcessID = pid; ti.Client = $"{ip}@{pid}"; ti.Status = JobStatus.就绪; ti.CreateTime = DateTime.Now; ti.UpdateTime = DateTime.Now; //// 如果有模板,则进行计算替换 //if (!Data.IsNullOrEmpty()) ti.Data = TemplateHelper.Build(Data, ti.Start, ti.End); ti.Insert(); // 更新任务 Start = end; start = end; list.Add(ti); } if (list.Count > 0) { // 任务需要ID,不能批量插入优化 //list.Insert(null); UpdateTime = DateTime.Now; Save(); ts.Commit(); } return(list); } } }