Пример #1
0
        /// <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_000))
                {
                    var ti2 = cache.Get <JobTask>(key);
                    XTrace.WriteLine("[{0}]重复切片:{1}", key, ti2?.ToJson());
                    break;
                }

                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);
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
        /// <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);
                }
            }
        }