0cbffd8613
- solo task attivi - esce da gruppo se fallisce uno step
265 lines
10 KiB
C#
265 lines
10 KiB
C#
using Maat.Data.DbModels;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Configuration;
|
|
using NLog;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using static Maat.Core.Enums;
|
|
|
|
namespace Maat.Data.Controllers
|
|
{
|
|
public class MsSqlController : IDisposable
|
|
{
|
|
#region Public Constructors
|
|
|
|
/// <summary>
|
|
/// Avvio Controller ThreadRun x DB
|
|
/// </summary>
|
|
/// <param name="threadName">nome del thread di esecuzione</param>
|
|
/// <param name="cString">stringa di connessione da impiegare</param>
|
|
/// <param name="cmdExecTOut">timeout esecuzione comandi (minuti)</param>
|
|
public MsSqlController(string threadName, string cString, int cmdExecTOut)
|
|
{
|
|
tName = threadName;
|
|
connString = cString;
|
|
cmdTimeout = cmdExecTOut;
|
|
Log.Info($"{tName} | Avviata classe MsSqlController");
|
|
}
|
|
|
|
#endregion Public Constructors
|
|
|
|
#region Public Methods
|
|
|
|
public DateTime CalcNextExe(TaskListModel taskRec)
|
|
{
|
|
DateTime dtNext = DateTime.Today;
|
|
DateTime adesso = DateTime.Now;
|
|
int maxIter = 1000;
|
|
try
|
|
{
|
|
// prendo come partenza la DATA di fine a cui aggiungo l'ora/minuti schedulata precedentemente
|
|
TimeSpan oraSched = taskRec.DtNextExec.Subtract(taskRec.DtNextExec.Date);
|
|
DateTime baseDT = taskRec.DtLastExec.Date.Add(oraSched);
|
|
// calcolo next exec da tipo... con ciclo fino a quando supero dataora attuale...
|
|
while (dtNext < adesso && maxIter > 0)
|
|
{
|
|
switch (taskRec.Freq)
|
|
{
|
|
case TaskFreqType.ND:
|
|
dtNext = baseDT.AddDays(taskRec.Cad);
|
|
break;
|
|
|
|
case TaskFreqType.Sec:
|
|
dtNext = baseDT.AddSeconds(taskRec.Cad);
|
|
break;
|
|
|
|
case TaskFreqType.Min:
|
|
dtNext = baseDT.AddMinutes(taskRec.Cad);
|
|
break;
|
|
|
|
case TaskFreqType.Hour:
|
|
dtNext = baseDT.AddHours(taskRec.Cad);
|
|
break;
|
|
|
|
case TaskFreqType.Day:
|
|
dtNext = baseDT.AddDays(taskRec.Cad);
|
|
break;
|
|
|
|
case TaskFreqType.Week:
|
|
dtNext = baseDT.AddDays(7 * taskRec.Cad);
|
|
break;
|
|
|
|
case TaskFreqType.Month:
|
|
dtNext = baseDT.AddMonths(taskRec.Cad);
|
|
break;
|
|
|
|
case TaskFreqType.Year:
|
|
dtNext = baseDT.AddYears(taskRec.Cad);
|
|
break;
|
|
|
|
default:
|
|
dtNext = baseDT.AddDays(taskRec.Cad);
|
|
break;
|
|
}
|
|
baseDT = dtNext;
|
|
maxIter--;
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
Log.Error($"Eccezione in CalcNextExe{Environment.NewLine}{exc}");
|
|
}
|
|
return dtNext;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Chiamata esecuzione di un singolo task programmato
|
|
/// </summary>
|
|
/// <param name="TaskId"></param>
|
|
/// <param name="SchedNext">Se true rischedula successiva chiamata</param>
|
|
/// <returns></returns>
|
|
public TaskResultModel ExecuteSqlTask(int TaskId, bool SchedNext)
|
|
{
|
|
TaskResultModel callRes = new TaskResultModel();
|
|
using (var dbCtx = new TaskRunContext(connString))
|
|
{
|
|
// imposto timeout a 5 min
|
|
dbCtx.Database.SetCommandTimeout(TimeSpan.FromMinutes(cmdTimeout));
|
|
string sqlCall = "";
|
|
try
|
|
{
|
|
DateTime dtStart = DateTime.Now;
|
|
// recupero i dati da richiamare...
|
|
var currRec = dbCtx
|
|
.DbSetTaskList
|
|
.Where(x => x.TaskId == TaskId)
|
|
.FirstOrDefault();
|
|
if (currRec != null)
|
|
{
|
|
// recupero comando
|
|
string sqlCommand = currRec.Command;
|
|
string rawParams = currRec.Args;
|
|
// salvo la call x eventuale log errore
|
|
sqlCall = $"EXEC {sqlCommand} {rawParams}";
|
|
|
|
var rawData = dbCtx
|
|
.DbSetTaskResult
|
|
.FromSqlRaw($"EXEC {sqlCommand} {rawParams}")
|
|
.ToList();
|
|
|
|
callRes = rawData.FirstOrDefault() ?? new TaskResultModel();
|
|
|
|
DateTime dtEnd = DateTime.Now;
|
|
|
|
// preparo record esecuzione...
|
|
TaskExecModel resRec = new TaskExecModel()
|
|
{
|
|
TaskId = TaskId,
|
|
DtStart = dtStart,
|
|
DtEnd = dtEnd,
|
|
IsError = callRes.ExecResult < 0,
|
|
Result = callRes.TextResult
|
|
};
|
|
dbCtx
|
|
.DbSetTaskExe
|
|
.Add(resRec);
|
|
|
|
// aggiorno record chiamata...
|
|
currRec.DtLastExec = dtStart;
|
|
currRec.LastResult = resRec.Result;
|
|
currRec.LastIsError = resRec.IsError;
|
|
currRec.LastDuration = dtEnd.Subtract(dtStart).TotalSeconds;
|
|
// solo se richiesto rischedulazione ricalcola chiamata
|
|
if (SchedNext)
|
|
{
|
|
// calcolo prossima esecuzione...
|
|
currRec.DtNextExec = CalcNextExe(currRec);
|
|
}
|
|
// segno modificato
|
|
dbCtx.Entry(currRec).State = EntityState.Modified;
|
|
|
|
// salvo modifiche!
|
|
dbCtx.SaveChanges();
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
string excMsg = $"{tName} | Eccezione in ExecuteSqlTask{Environment.NewLine}Call eseguita:{Environment.NewLine}{sqlCall}{Environment.NewLine}------- Stack Eccezione -------{Environment.NewLine}{exc}";
|
|
callRes.ExecResult = -1;
|
|
callRes.TextResult = excMsg;
|
|
Log.Error(excMsg);
|
|
}
|
|
}
|
|
return callRes;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue registrazione di un Task generico (NON SQL)
|
|
/// </summary>
|
|
/// <param name="TaskId"></param>
|
|
/// <param name="SchedNext">Se true rischedula successiva chiamata</param>
|
|
/// <param name="ResRec">Record esecuzione task esterno</param>
|
|
/// <returns></returns>
|
|
public TaskResultModel TaskExecSaveExecuted(int TaskId, bool SchedNext, TaskExecModel ResRec)
|
|
{
|
|
TaskResultModel callRes = new TaskResultModel();
|
|
using (var dbCtx = new TaskRunContext(connString))
|
|
{
|
|
try
|
|
{
|
|
// recupero i dati da richiamare...
|
|
var currRec = dbCtx
|
|
.DbSetTaskList
|
|
.Where(x => x.TaskId == TaskId)
|
|
.FirstOrDefault();
|
|
if (currRec != null)
|
|
{
|
|
// registro task ricevuto
|
|
dbCtx
|
|
.DbSetTaskExe
|
|
.Add(ResRec);
|
|
|
|
// aggiorno record chiamata...
|
|
currRec.DtLastExec = ResRec.DtStart;
|
|
currRec.LastResult = ResRec.Result;
|
|
currRec.LastIsError = ResRec.IsError;
|
|
currRec.LastDuration = ResRec.DtEnd.Subtract(ResRec.DtStart).TotalSeconds;
|
|
// solo se richiesto rischedulazione ricalcola chiamata
|
|
if (SchedNext)
|
|
{
|
|
// calcolo prossima esecuzione...
|
|
currRec.DtNextExec = CalcNextExe(currRec);
|
|
}
|
|
// segno modificato
|
|
dbCtx.Entry(currRec).State = EntityState.Modified;
|
|
|
|
// salvo modifiche!
|
|
dbCtx.SaveChanges();
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
Log.Error($"Eccezione in TaskExecSaveExecuted{Environment.NewLine}{exc}");
|
|
}
|
|
}
|
|
return callRes;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ricerca task dato tipo e
|
|
/// </summary>
|
|
/// <param name="TType"></param>
|
|
/// <returns></returns>
|
|
public List<TaskListModel> TaskListGetAll(Task2ExeType TType)
|
|
{
|
|
List<TaskListModel> dbResult = new List<TaskListModel>();
|
|
using (var dbCtx = new TaskRunContext(connString))
|
|
{
|
|
dbResult = dbCtx
|
|
.DbSetTaskList
|
|
.Where(x => (TType == Task2ExeType.ND || x.TType == TType))
|
|
.OrderBy(x => x.Ordinal)
|
|
.ToList();
|
|
}
|
|
return dbResult;
|
|
}
|
|
|
|
#endregion Public Methods
|
|
|
|
#region Private Fields
|
|
|
|
private static Logger Log = LogManager.GetCurrentClassLogger();
|
|
private string connString = "";
|
|
private string tName = "";
|
|
private int cmdTimeout = 0;
|
|
|
|
#endregion Private Fields
|
|
}
|
|
} |