ibms-dome/Backend/Quartz/JobSchedule.cs

199 lines
7.5 KiB
C#
Raw Normal View History

using Microsoft.Extensions.Logging;
using Repository.BackendRepository.Implement;
using Repository.BackendRepository.Interface;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Threading.Tasks;
using NCrontab;
using static NCrontab.CrontabSchedule;
namespace Backend.Quartz
{
/// <summary>
/// Job調度中間對象
/// </summary>
public class JobSchedule
{
public JobSchedule(Type jobType, string cronExpression)
{
this.JobType = jobType ?? throw new ArgumentNullException(nameof(jobType));
CronExpression = cronExpression ?? throw new ArgumentNullException(nameof(cronExpression));
}
/// <summary>
/// Job類型
/// </summary>
public Type JobType { get; private set; }
/// <summary>
/// Cron表達式
/// </summary>
public string CronExpression { get; private set; }
/// <summary>
/// Job狀態
/// </summary>
public JobStatus JobStatu { get; set; } = JobStatus.Init;
}
/// <summary>
/// Job運行狀態
/// </summary>
public enum JobStatus : byte
{
[Description("初始化")]
Init = 0,
[Description("運行中")]
Running = 1,
[Description("調度中")]
Scheduling = 2,
[Description("已停止")]
Stopped = 3,
}
public class Task_Detail
{
private readonly IBackendRepository backendRepository;
private readonly ILogger<Task_Detail> logger;
public Task_Detail(ILogger<Task_Detail> logger, IBackendRepository backendRepository)
{
this.logger = logger;
this.backendRepository = backendRepository;
}
/// <summary>
/// 取得時間規則
/// </summary>
/// <param name="task"></param>
/// <param name="task_item"></param>
/// <returns></returns>
private async Task<string> GetWorkRule(string task,string task_item)
{
string Times = null;
try
{
var sql = $@"select b.system_value from task_detail a
join variable b on a.variable_id = b.id
where a.task = '{task}' and a.task_item = '{task_item}'";
Times = await backendRepository.GetOneAsync<string>(sql);
}
catch(Exception exception)
{
logger.LogError("【Task_Detail】【任務時間獲取失敗】");
logger.LogError("【Task_Detail】【任務時間獲取失敗】[Exception]{0},Task:{1},task_item:{2}", exception.ToString(),task,task_item);
}
return Times;
}
/// <summary>
/// 是否執行任務
/// </summary>
/// <param name="task"></param>
/// <param name="task_item"></param>
/// <returns></returns>
public async Task<bool> GetNeedWorkTask(string task, string task_item)
{
try
{
var sql = $@"select a.lastwork_time from task_detail a
where a.task = '{task}' and a.task_item = '{task_item}'";
var lastworkTime = await backendRepository.GetOneAsync<string>(sql);
DateTime dateTime = lastworkTime != null ? Convert.ToDateTime(lastworkTime) : Convert.ToDateTime("1970-01-01 00:00:01");
var nextTime = CrontabSchedule.Parse(await GetWorkRule(task, task_item), new ParseOptions { IncludingSeconds = true } ).GetNextOccurrence(dateTime);
if (DateTime.Now >= nextTime)
{
return true;
}
}
catch(Exception exception)
{
logger.LogError("【Task_Detail】【時間解析失敗】[Exception]{0},Task:{1},task_item:{2}", exception.ToString(), task, task_item);
}
return false;
}
/// <summary>
/// 紀錄任務開始執行時間
/// </summary>
/// <param name="task"></param>
/// <param name="task_item"></param>
/// <returns></returns>
public async Task InsertWorkTime(string task, string task_item ,string LoggerWord = null)
{
try
{
Dictionary<string, object> worktime = new Dictionary<string, object>()
{
{ "@lastwork_time", DateTime.Now},
{ "@success", 2},
{ "@updated_at", DateTime.Now},
};
await backendRepository.UpdateOneByCustomTable(worktime, "task_detail", $" task = '{task}' and task_item = '{task_item}'");
if(LoggerWord == null)
{
logger.LogInformation($"【Task_Detail】【開始{task},{task_item}任務】");
}
logger.LogInformation($"【Task_Detail】【{LoggerWord}】");
}
catch (Exception exception)
{
logger.LogError("【Task_Detail】【任務輸入開始時間】[Exception]{0},Task:{1},task_item:{2}", exception.ToString(), task, task_item);
}
}
/// <summary>
/// 紀錄任務結束時間
/// </summary>
/// <param name="task"></param>
/// <param name="task_item"></param>
/// <returns></returns>
public async Task InsertWorkTime_End(string task, string task_item,string LoggerWord = null)
{
try
{
Dictionary<string, object> worktime = new Dictionary<string, object>()
{
{ "@success", 0},
{ "@lastwork_end_time", DateTime.Now},
{ "@updated_at", DateTime.Now},
};
await backendRepository.UpdateOneByCustomTable(worktime, "task_detail", $" task = '{task}' and task_item = '{task_item}'");
if (LoggerWord == null)
{
logger.LogInformation($"【Task_Detail】【結束{task},{task_item}任務】");
}
logger.LogInformation($"【Task_Detail】【{LoggerWord}】");
}
catch (Exception exception)
{
logger.LogError("【Task_Detail】【任務輸入結束時間】[Exception]{0},Task:{1},task_item:{2}", exception.ToString(), task, task_item);
}
}
/// <summary>
/// 執行失敗紀錄
/// </summary>
/// <param name="task"></param>
/// <param name="task_item"></param>
/// <returns></returns>
public async Task WorkFail(string task, string task_item,string reason = "")
{
try
{
Dictionary<string, object> worktime = new Dictionary<string, object>()
{
{ "@success", 1},
{ "@updated_at", DateTime.Now},
};
await backendRepository.UpdateOneByCustomTable(worktime, "task_detail", $" task = '{task}' and task_item = '{task_item}'");
logger.LogError("【Task_Detail】【任務執行失敗】[Exception]{0},Task:{1},task_item:{2}", reason, task, task_item);
}
catch (Exception exception)
{
logger.LogError("【Task_Detail】【任務執行失敗】[Exception]{0},Task:{1},task_item:{2}", exception.ToString(), task, task_item);
}
}
}
}