/// <summary>验证数据,通过抛出异常的方式提示验证失败。</summary> /// <param name="isNew">是否插入</param> public override void Valid(Boolean isNew) { // 如果没有脏数据,则不需要进行任何处理 if (!HasDirty) { return; } // 这里验证参数范围,建议抛出参数异常,指定参数名,前端用户界面可以捕获参数异常并聚焦到对应的参数输入框 if (Name.IsNullOrEmpty()) { throw new ArgumentNullException(nameof(Name), "名称不能为空!"); } if (!isNew && JobCount == 0 && !Dirtys[nameof(JobCount)]) { JobCount = Job.FindCountByAppID(ID); } if (!isNew && MessageCount == 0 && !Dirtys[nameof(MessageCount)]) { MessageCount = AppMessage.FindCountByAppID(ID); } }
/// <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); } } }