Exemple #1
0
        /// <summary>
        /// 执行队列,并快速返回结果
        /// </summary>
        /// <param name="triggerParam"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public ReturnT Execute(TriggerParam triggerParam)
        {
            var executor = this._executorFactory.GetTaskExecutor(triggerParam.GlueType);

            if (executor == null)
            {
                return(ReturnT.Failed($"glueType[{triggerParam.GlueType}] is not supported "));
            }

            // 1. 根据JobId 获取 TaskQueue; 用于判断是否有正在执行的任务
            if (RUNNING_QUEUE.TryGetValue(triggerParam.JobId, out var taskQueue))
            {
                if (taskQueue.Executor != executor) //任务执行器变更
                {
                    return(ChangeJobQueue(triggerParam, executor));
                }
            }

            if (taskQueue != null) //旧任务还在执行,判断执行策略
            {
                //丢弃后续的
                if (Constants.ExecutorBlockStrategy.DISCARD_LATER == triggerParam.ExecutorBlockStrategy)
                {
                    return(ReturnT.Failed($"block strategy effect:{triggerParam.ExecutorBlockStrategy}"));
                }
                //覆盖较早的
                if (Constants.ExecutorBlockStrategy.COVER_EARLY == triggerParam.ExecutorBlockStrategy)
                {
                    return(taskQueue.Replace(triggerParam));
                }
            }

            return(PushJobQueue(triggerParam, executor));
        }
Exemple #2
0
        /// <summary>
        ///  read Log
        /// </summary>
        /// <param name="logDateTime"></param>
        /// <param name="logId"></param>
        /// <param name="fromLineNum"></param>
        /// <returns></returns>
        private ReturnT Log(long logDateTime, long logId, int fromLineNum)
        {
            var ret = ReturnT.Success(null);

            ret.Content = this._jobLogger.ReadLog(logDateTime, logId, fromLineNum);
            return(ret);
        }
Exemple #3
0
 private ReturnT Kill(int jobId)
 {
     return(this._jobDispatcher.TryRemoveJobTask(jobId) ?
            ReturnT.SUCCESS
         :
            ReturnT.Success("job thread already killed."));
 }
 private ReturnT IdleBeat(IdleBeatRequest req)
 {
     if (req == null)
     {
         return(ReturnT.Failed("IdleBeat Error"));
     }
     return(this._jobDispatcher.IdleBeat(req.JobId));
 }
        /// <summary>
        ///  read Log
        /// </summary>
        /// <returns></returns>
        private ReturnT Log(LogRequest req)
        {
            if (req == null)
            {
                return(ReturnT.Failed("Log Error"));
            }
            var ret = ReturnT.Success(null);

            ret.Content = this._jobLogger.ReadLog(req.LogDateTime, req.LogId, req.FromLineNum);
            return(ret);
        }
 private ReturnT Kill(KillRequest req)
 {
     if (req == null)
     {
         return(ReturnT.Failed("Kill Error"));
     }
     return(this._jobDispatcher.TryRemoveJobTask(req.JobId) ?
            ReturnT.SUCCESS
         :
            ReturnT.Success("job thread already killed."));
 }
Exemple #7
0
        public ReturnT Push(TriggerParam triggerParam)
        {
            if (!ID_IN_QUEUE.TryAdd(triggerParam.LogId, 0))
            {
                this._logger.LogWarning("repeat job task,logId={logId},jobId={jobId}", triggerParam.LogId, triggerParam.JobId);
                return(ReturnT.Failed("repeat job task!"));
            }

            //this._logger.LogWarning("add job with logId={logId},jobId={jobId}",triggerParam.LogId,triggerParam.JobId);

            this.TASK_QUEUE.Enqueue(triggerParam);
            StartTask();
            return(ReturnT.SUCCESS);
        }
Exemple #8
0
        private ReturnT PushJobQueue(TriggerParam triggerParam, ITaskExecutor executor)
        {
            if (RUNNING_QUEUE.TryGetValue(triggerParam.JobId, out var jobQueue))
            {
                return(jobQueue.Push(triggerParam));
            }

            //NewJobId
            jobQueue           = new JobTaskQueue(executor, this._jobLogger, this._jobQueueLogger);
            jobQueue.CallBack += TriggerCallback;
            if (RUNNING_QUEUE.TryAdd(triggerParam.JobId, jobQueue))
            {
                return(jobQueue.Push(triggerParam));
            }
            return(ReturnT.Failed("add running queue executor error"));
        }
Exemple #9
0
        private ReturnT ChangeJobQueue(TriggerParam triggerParam, ITaskExecutor executor)
        {
            if (RUNNING_QUEUE.TryRemove(triggerParam.JobId, out var oldJobTask))
            {
                oldJobTask.CallBack -= TriggerCallback;
                oldJobTask.Dispose(); //释放原来的资源
            }

            JobTaskQueue jobQueue = new JobTaskQueue(executor, this._jobLogger, this._jobQueueLogger);

            jobQueue.CallBack += TriggerCallback;
            if (RUNNING_QUEUE.TryAdd(triggerParam.JobId, jobQueue))
            {
                return(jobQueue.Push(triggerParam));
            }
            return(ReturnT.Failed(" replace running queue executor error"));
        }
Exemple #10
0
        private async Task <ReturnT> InvokeRpcService(string methodName, object jsonObject)
        {
            var     triedTimes = 0;
            ReturnT ret        = null;

            while (triedTimes++ < this._addresses.Count)
            {
                var address = this._addresses[this._currentIndex];
                this._currentIndex = (this._currentIndex + 1) % this._addresses.Count;
                if (!address.CheckAccessible())
                {
                    continue;
                }
                try
                {
                    var json = await address.RequestUri.AppendPathSegment(methodName)
                               .WithHeader("XXL-JOB-ACCESS-TOKEN", this._options.AccessToken)
                               .PostJsonAsync(jsonObject)
                               .ReceiveString();

                    //.ReceiveJson<ReturnT>();
                    ret = JsonConvert.DeserializeObject <ReturnT>(json);
                    address.Reset();
                }
                catch (Exception ex)
                {
                    this._logger.LogError(ex, "request admin error.{0}", ex.Message);
                    address.SetFail();
                    continue;
                }
            }
            if (ret == null)
            {
                ret = ReturnT.Failed("call admin fail");
            }
            return(ret);
        }
Exemple #11
0
        private void StartTask()
        {
            if (this._cancellationTokenSource != null)
            {
                return; //running
            }
            this._cancellationTokenSource = new CancellationTokenSource();
            var ct = this._cancellationTokenSource.Token;

            this._runTask = Task.Factory.StartNew(async() =>
            {
                //ct.ThrowIfCancellationRequested();

                while (!ct.IsCancellationRequested)
                {
                    if (TASK_QUEUE.IsEmpty)
                    {
                        break;
                    }

                    ReturnT result            = null;
                    TriggerParam triggerParam = null;
                    try
                    {
                        if (TASK_QUEUE.TryDequeue(out triggerParam))
                        {
                            if (!ID_IN_QUEUE.TryRemove(triggerParam.LogId, out _))
                            {
                                this._logger.LogWarning("remove queue failed,logId={logId},jobId={jobId},exists={exists}"
                                                        , triggerParam.LogId, triggerParam.JobId, ID_IN_QUEUE.ContainsKey(triggerParam.LogId));
                            }
                            //set log file;
                            this._jobLogger.SetLogFile(triggerParam.LogDateTime, triggerParam.LogId);

                            this._jobLogger.Log("<br>----------- xxl-job job execute start -----------<br>----------- Param:{0}", triggerParam.ExecutorParams);

                            result = await this._executor.Execute(triggerParam);

                            this._jobLogger.Log("<br>----------- xxl-job job execute end(finish) -----------<br>----------- ReturnT:" + result.Code);
                        }
                        else
                        {
                            this._logger.LogWarning("Dequeue Task Failed");
                        }
                    }
                    catch (Exception ex)
                    {
                        result = ReturnT.Failed("Dequeue Task Failed:" + ex.Message);
                        this._jobLogger.Log("<br>----------- JobThread Exception:" + ex.Message + "<br>----------- xxl-job job execute end(error) -----------");
                    }

                    if (triggerParam != null)
                    {
                        CallBack?.Invoke(this, new HandleCallbackParam(triggerParam, result ?? ReturnT.FAIL));
                    }
                }


                this._cancellationTokenSource.Dispose();
                this._cancellationTokenSource = null;
            }, this._cancellationTokenSource.Token);
        }
Exemple #12
0
        private async Task <ReturnT> InvokeRpcService(string methodName, List <object> parameterTypes,
                                                      object parameters, bool polling = false)
        {
            var request = new RpcRequest {
                RequestId        = Guid.NewGuid().ToString("N"),
                CreateMillisTime = DateTime.Now.GetTotalMilliseconds(),
                AccessToken      = _options.AccessToken,
                ClassName        = "com.xxl.job.core.biz.AdminBiz",
                MethodName       = methodName,
                ParameterTypes   = parameterTypes,
                Parameters       = new List <object> {
                    parameters
                }
            };

            byte[] postBuf;
            using (var stream = new MemoryStream())
            {
                HessianSerializer.SerializeRequest(stream, request);

                postBuf = stream.ToArray();
            }

            var triedTimes = 0;
            var retList    = new List <ReturnT>();

            using (var client = this._clientFactory.CreateClient(Constants.DefaultHttpClientName))
            {
                while (triedTimes++ < this._addresses.Count)
                {
                    var address = this._addresses[this._currentIndex];
                    this._currentIndex = (this._currentIndex + 1) % this._addresses.Count;
                    if (!address.CheckAccessible())
                    {
                        continue;
                    }

                    Stream resStream;
                    try
                    {
                        resStream = await DoPost(client, address, postBuf);

                        address.Reset();
                    }
                    catch (Exception ex)
                    {
                        this._logger.LogError(ex, "request admin error.{0}", ex.Message);
                        address.SetFail();
                        continue;
                    }

                    RpcResponse res = null;
                    try
                    {
                        /*
                         * using (StreamReader reader = new StreamReader(resStream))
                         * {
                         * string content  = await reader.ReadToEndAsync();
                         *
                         * this._logger.LogWarning(content);
                         * }
                         */
                        res = HessianSerializer.DeserializeResponse(resStream);
                    }
                    catch (Exception ex)
                    {
                        this._logger.LogError(ex, "DeserializeResponse error:{errorMessage}", ex.Message);
                    }

                    if (res == null)
                    {
                        retList.Add(ReturnT.Failed("response is null"));
                    }
                    else if (res.IsError)
                    {
                        retList.Add(ReturnT.Failed(res.ErrorMsg));
                    }
                    else if (res.Result is ReturnT ret)
                    {
                        retList.Add(ret);
                    }
                    else
                    {
                        retList.Add(ReturnT.Failed("response is null"));
                    }

                    if (!polling)
                    {
                        return(retList[0]);
                    }
                }

                if (retList.Count > 0)
                {
                    return(retList.Last());
                }
            }
            throw new Exception("xxl-rpc server address not accessible.");
        }
        public async Task HandlerAsync(HttpRequest request, HttpResponse response)
        {
            var path = request.Path.Value;

            ReturnT ret      = null;
            var     arrParts = path.Split('/');
            var     method   = arrParts[arrParts.Length - 1].ToLower();

            if (!string.IsNullOrEmpty(this._options.AccessToken))
            {
                var reqToken = "";
                if (request.Headers.TryGetValue("XXL-JOB-ACCESS-TOKEN", out var tokenValues))
                {
                    reqToken = tokenValues[0].ToString();
                }
                if (this._options.AccessToken != reqToken)
                {
                    ret = ReturnT.Failed("ACCESS-TOKEN Auth Fail");
                    response.ContentType = "application/json;charset=utf-8";
                    await response.WriteAsync(JsonConvert.SerializeObject(ret));

                    return;
                }
            }
            try
            {
                string json = await CollectBody(request.Body);

                switch (method)
                {
                case "beat":
                    ret = Beat();
                    break;

                case "idleBeat":
                    ret = IdleBeat(JsonConvert.DeserializeObject <IdleBeatRequest>(json));
                    break;

                case "run":
                    ret = Run(JsonConvert.DeserializeObject <TriggerParam>(json));
                    break;

                case "kill":
                    ret = Kill(JsonConvert.DeserializeObject <KillRequest>(json));
                    break;

                case "log":
                    ret = Log(JsonConvert.DeserializeObject <LogRequest>(json));
                    break;
                }
            }
            catch (Exception ex)
            {
                this._logger.LogError(ex, "响应出错" + ex.Message);
                ret = ReturnT.Failed("执行器内部错误");
            }


            if (ret == null)
            {
                ret = ReturnT.Failed($"method {method}  is not impl");
            }
            response.ContentType = "application/json;charset=utf-8";
            await response.WriteAsync(JsonConvert.SerializeObject(ret, new JsonSerializerSettings()
            {
                StringEscapeHandling = StringEscapeHandling.EscapeNonAscii
            }));
        }