/// <summary> /// 获取Storage 通过这个媒介来处理jobagent的job的统一状态 /// </summary> /// <returns></returns> private IHangfireStorage GetHangfireStorage(HttpContext httpContext, JobItem jobItem) { if (jobItem.Storage == null) { return(httpContext.RequestServices.GetService <IHangfireStorage>()); } var storageFactory = httpContext.RequestServices.GetService <IStorageFactory>(); if (storageFactory == null) { return(null); } return(storageFactory.CreateHangfireStorage(jobItem.Storage)); }
public async Task InvokeAsync(HttpContext httpContext, RequestDelegate next) { httpContext.Response.ContentType = "text/plain"; string message = string.Empty; try { if (!CheckAuth(httpContext, _options)) { message = "err:basic auth invaild!"; _logger.LogError(message); return; } var agentClass = httpContext.Request.Headers["x-job-agent-class"].ToString(); var agentAction = httpContext.Request.Headers["x-job-agent-action"].ToString(); var jobBody = httpContext.Request.Headers["x-job-body"].ToString(); if (string.IsNullOrEmpty(agentClass)) { message = "err:x-job-agent-class in headers can not be empty!"; _logger.LogError(message); return; } if (string.IsNullOrEmpty(agentAction)) { message = $"err:x-job-agent-action in headers can not be empty!"; _logger.LogError(message); return; } JobItem jobItem = null; if (!string.IsNullOrEmpty(jobBody)) { jobItem = Newtonsoft.Json.JsonConvert.DeserializeObject <JobItem>(jobBody); } if (jobItem == null) { jobItem = new JobItem(); } agentAction = agentAction.ToLower(); var requestBody = await GetJobItem(httpContext); var agentClassType = GetAgentType(agentClass); var jobHeaders = GetJobHeaders(httpContext); if (!string.IsNullOrEmpty(agentClassType.Item2)) { message = $"err:JobClass:{agentClass} GetType err:{agentClassType.Item2}"; _logger.LogError(message); return; } if (!JobAgentServiceConfigurer.JobAgentDic.TryGetValue(agentClassType.Item1, out var metaData)) { message = $"err:JobClass:{agentClass} is not registered!"; _logger.LogWarning(message); return; } if (!metaData.Transien) { var job = (JobAgent)httpContext.RequestServices.GetRequiredService(agentClassType.Item1); if (agentAction.Equals("run")) { //单例的 一次只能运行一次 if (job.JobStatus == JobStatus.Running || job.JobStatus == JobStatus.Stopping) { message = $"err:JobClass:{agentClass} can not start, is already Running!"; _logger.LogWarning(message); return; } else if (job.JobStatus == JobStatus.Default) { job.Hang = metaData.Hang; job.AgentClass = agentClass; } var console = GetHangfireConsole(httpContext, agentClassType.Item1); jobItem.JobParam = requestBody; job.Run(jobItem, console, jobHeaders); message = $"JobClass:{agentClass} run success!"; _logger.LogInformation(message); return; } else if (agentAction.Equals("stop")) { if (job.JobStatus == JobStatus.Stopping) { message = $"err:JobClass:{agentClass} is Stopping!"; _logger.LogWarning(message); return; } if (job.JobStatus == JobStatus.Stoped) { message = $"err:JobClass:{agentClass} is already Stoped!"; _logger.LogWarning(message); return; } var console = GetHangfireConsole(httpContext, agentClassType.Item1); job.Stop(jobItem, console, jobHeaders); message = $"JobClass:{agentClass} stop success!"; _logger.LogInformation(message); return; } else if (agentAction.Equals("detail")) { //获取job详情 message = job.GetJobInfo(); _logger.LogInformation(message); return; } message = $"err:agentAction:{agentAction} invaild"; _logger.LogError(message); return; } if (agentAction.Equals("run")) { var job = (JobAgent)httpContext.RequestServices.GetRequiredService(agentClassType.Item1); job.Singleton = false; job.AgentClass = agentClass; job.Hang = metaData.Hang; job.Guid = Guid.NewGuid().ToString("N"); job.TransitentJobDisposeEvent += transitentJob.JobRemove; var jobAgentList = transitentJob.GetOrAdd(agentClass, x => new ConcurrentDictionary <string, JobAgent>()); jobAgentList.TryAdd(job.Guid, job); var console = GetHangfireConsole(httpContext, agentClassType.Item1); jobItem.JobParam = requestBody; job.Run(jobItem, console, jobHeaders); message = $"Transient JobClass:{agentClass} run success!"; _logger.LogInformation(message); return; } else if (agentAction.Equals("stop")) { if (!transitentJob.TryGetValue(agentClass, out var jobAgentList) || jobAgentList.Count < 1) { message = $"err:Transient JobClass:{agentClass} have no running job!"; _logger.LogWarning(message); return; } var instanceCount = 0; var stopedJobList = new List <JobAgent>(); foreach (var runingJob in jobAgentList) { if (runingJob.Value.JobStatus == JobStatus.Stopping) { continue; } if (runingJob.Value.JobStatus == JobStatus.Stoped) { stopedJobList.Add(runingJob.Value); continue; } var console = GetHangfireConsole(httpContext, agentClassType.Item1); runingJob.Value.Stop(jobItem, console, jobHeaders); instanceCount++; } foreach (var stopedJob in stopedJobList) { jobAgentList.TryRemove(stopedJob.Guid, out _); } transitentJob.TryRemove(agentClass, out _); message = $"JobClass:{agentClass},Instance Count:{instanceCount} stop success!"; _logger.LogInformation(message); return; } else if (agentAction.Equals("detail")) { if (!transitentJob.TryGetValue(agentClass, out var jobAgentList) || jobAgentList.Count < 1) { message = $"err:Transient JobClass:{agentClass} have no running job!"; _logger.LogWarning(message); return; } var jobInfo = new List <string>(); var stopedJobList = new List <JobAgent>(); foreach (var jobAgent in jobAgentList) { if (jobAgent.Value.JobStatus == JobStatus.Stoped) { stopedJobList.Add(jobAgent.Value); continue; } jobInfo.Add(jobAgent.Value.GetJobInfo()); } foreach (var stopedJob in stopedJobList) { jobAgentList.TryRemove(stopedJob.Guid, out _); } if (jobInfo.Count < 1) { message = $"err:Transient JobClass:{agentClass} have no running job!"; _logger.LogWarning(message); return; } //获取job详情 message = $"Runing Instance Count:{jobInfo.Count},JobList:{string.Join("\r\n", jobInfo)}"; return; } message = $"err:agentAction:{agentAction} invaild"; _logger.LogError(message); } catch (Exception e) { httpContext.Response.StatusCode = 500; await httpContext.Response.WriteAsync(e.ToString()); } finally { if (!string.IsNullOrEmpty(message)) { if (message.StartsWith("err:")) { httpContext.Response.StatusCode = 500; } await httpContext.Response.WriteAsync(message); } } }