Update x gestione schedulazione riavvio notturno + test vari

This commit is contained in:
Samuele Locatelli
2025-06-11 20:53:42 +02:00
parent c8bfe67b85
commit 911026d6df
15 changed files with 345 additions and 267 deletions
+3 -10
View File
@@ -33,7 +33,6 @@
blazorWebView1 = new Microsoft.AspNetCore.Components.WebView.WindowsForms.BlazorWebView();
timerCheck = new System.Windows.Forms.Timer(components);
timerTask = new System.Windows.Forms.Timer(components);
timerStats = new System.Windows.Forms.Timer(components);
SuspendLayout();
//
// blazorWebView1
@@ -41,7 +40,7 @@
blazorWebView1.Dock = DockStyle.Fill;
blazorWebView1.Location = new Point(0, 0);
blazorWebView1.Name = "blazorWebView1";
blazorWebView1.Size = new Size(1184, 561);
blazorWebView1.Size = new Size(1184, 661);
blazorWebView1.StartPath = "/";
blazorWebView1.TabIndex = 0;
blazorWebView1.Text = "blazorWebView1";
@@ -53,19 +52,14 @@
//
// timerTask
//
timerTask.Interval = 1000;
timerTask.Interval = 30000;
timerTask.Tick += timerTask_Tick;
//
// timerStats
//
timerStats.Interval = 600000;
timerStats.Tick += timerStats_Tick;
//
// BlazorForm
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(1184, 561);
ClientSize = new Size(1184, 661);
Controls.Add(blazorWebView1);
Icon = (Icon)resources.GetObject("$this.Icon");
Name = "BlazorForm";
@@ -80,6 +74,5 @@
private Microsoft.AspNetCore.Components.WebView.WindowsForms.BlazorWebView blazorWebView1;
private System.Windows.Forms.Timer timerCheck;
private System.Windows.Forms.Timer timerTask;
private System.Windows.Forms.Timer timerStats;
}
}
+16 -62
View File
@@ -31,13 +31,20 @@ namespace IOB_MAN8.App
ServiceInit();
InitBlazorView();
StartTimer();
StartLastAsync();
}
#endregion Public Constructors
#region Private Fields
#region Protected Fields
/// <summary>
/// Dataora prossima scadenza riavvio automatico
/// </summary>
protected DateTime tOutAutocheck = DateTime.Now;
#endregion Protected Fields
#region Private Fields
/// <summary>
/// Classe logger
@@ -61,17 +68,12 @@ namespace IOB_MAN8.App
private System.Reflection.AssemblyName CurrAssembly { get; set; } = new System.Reflection.AssemblyName();
/// <summary>
/// Dataora prossima scadenza riavvio automatico
/// </summary>
protected DateTime tOutAutocheck = DateTime.Now;
/// <summary>
/// Ultima visualizzazione messaggio...
/// </summary>
private DateTime lastMsqShown { get; set; } = DateTime.MinValue;
private Size lastSize { get; set; } = new Size(1200, 600);
private Size lastSize { get; set; } = new Size(1200, 700);
#endregion Private Properties
@@ -130,7 +132,6 @@ namespace IOB_MAN8.App
DoRestart(true);
}
private void BlazorForm_FormClosing(object sender, FormClosingEventArgs e)
{
ACService.EA_ConfigUpdated -= ACService_EA_ConfigUpdated;
@@ -140,12 +141,9 @@ namespace IOB_MAN8.App
timerCheck.Dispose();
timerTask.Stop();
timerTask.Dispose();
timerStats.Stop();
timerStats.Dispose();
ACService.DoCloseAll(false);
}
/// <summary>
/// Evento completamento caricamento app
/// </summary>
@@ -154,11 +152,8 @@ namespace IOB_MAN8.App
private void BlazorForm_Load(object sender, EventArgs e)
{
SetPosition();
// apro i child...
ACService.DoOpenAllChild();
}
/// <summary>
/// Esegue eventuale unzip file risorse www
/// </summary>
@@ -189,11 +184,8 @@ namespace IOB_MAN8.App
/// </summary>
private async Task ForceReload()
{
#if false
await ACService.DoFullCheckAsync(true);
#endif
ACService.DoAutoRestart(true);
await ACService.DoScan();
await ACService.DoTaskCheckAsync(true);
}
private void InitBlazorView()
@@ -236,32 +228,14 @@ namespace IOB_MAN8.App
this.Location = new Point((workArea.Right - lastSize.Width) / 2, (workArea.Bottom - lastSize.Height) / 2);
}
/// <summary>
/// init ultime attività async
/// </summary>
private void StartLastAsync()
{
var pUpd = Task.Run(async () =>
{
await ForceReload();
});
pUpd.Wait();
}
private void StartTimer()
{
// timer controlli da conf
timerCheck.Interval = (ACService.RefreshPeriod);
// timer statistiche a 30 min fisso x ora
#if DEBUG
timerStats.Interval = 1000 * 60 * 5;
#else
timerStats.Interval = 1000 * 60 * 30;
#endif
timerTask.Interval = (ACService.CheckRestartPeriod);
// avvio timer
timerCheck.Start();
timerTask.Start();
timerStats.Start();
}
/// <summary>
@@ -279,36 +253,16 @@ namespace IOB_MAN8.App
}
/// <summary>
/// Gestione timer statistiche
/// Timer task x eventuale riavvio processi fermi SE abilitato...
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void timerStats_Tick(object sender, EventArgs e)
{
// fermo task...
timerStats.Stop();
// esegue controllo task
#if false
await ACService.SendStats();
await ACService.SendLicInfo();
await ACService.SendConfTarget();
#endif
await Task.Delay(250);
// riavvio task x evitare sovrapposizioni in debug
timerStats.Start();
}
/// <summary>
/// Timer task (1 sec base)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void timerTask_Tick(object sender, EventArgs e)
private void timerTask_Tick(object sender, EventArgs e)
{
// fermo task...
timerTask.Stop();
// esegue controllo task
await ACService.DoTaskCheckAsync(false);
// esegue controllo task x eventuale autorestart
ACService.DoAutoRestart(false);
// riavvio task x evitare sovrapposizioni in debug
timerTask.Start();
}
-3
View File
@@ -123,9 +123,6 @@
<metadata name="timerTask.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>351, 17</value>
</metadata>
<metadata name="timerStats.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>456, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
@@ -15,16 +15,17 @@
}
<ProgressDisplay RefreshInterval="100" Title="@UpdateMsg" MaxVal="@maxVal" CurrVal="@currVal" NextVal="@nextVal" ExpTimeMSec="@expTimeMSec" DisplaySize="ProgressDisplay.ModalSize.Medium" ModalCss="card alert-primary" SlowLimit="0.4"></ProgressDisplay>
</div>
<div class="p-0 d-flex small text-nowrap">
<div class="px-0 input-group input-group-sm">
<button class="btn btn-sm btn-outline-primary" @onclick="DoShowAll" title="Mostra Tutti">Show All</button>
<button class="btn btn-sm btn-outline-primary" @onclick="DoHideAll" title="Mostra Tutti">Hide All</button>
<div class="p-0 d-flex small">
@* <div class="p-0 d-flex small col-9 col-md-8 col-lg-7 col-xl-5"> *@
<div class="px-0 input-group input-group-sm flex-lg-nowrap me-2">
<button class="btn btn-sm btn-outline-primary text-nowrap" @onclick="DoShowAll" title="Mostra Tutti">Show All</button>
<button class="btn btn-sm btn-outline-primary text-nowrap" @onclick="DoHideAll" title="Mostra Tutti">Hide All</button>
</div>
<div class="px-0 input-group input-group-sm">
<div class="px-0 input-group input-group-sm flex-lg-nowrap me-2">
@if (enableKillTask)
{
<button class="btn btn-sm btn-outline-dark" @onclick="DoCloseAll" title="Mostra Tutti">Close All</button>
<button class="btn btn-sm btn-outline-dark" @onclick="DoRestartAll" title="Mostra Tutti">Restart All</button>
<button class="btn btn-sm btn-outline-dark text-nowrap" @onclick="DoCloseAll" title="Mostra Tutti">Close All</button>
<button class="btn btn-sm btn-outline-dark text-nowrap" @onclick="DoRestartAll" title="Mostra Tutti">Restart All</button>
}
else
{
@@ -32,24 +33,24 @@
<button class="btn btn-sm btn-outline-dark disabled opacity-75" title="Mostra Tutti">Restart All</button>
}
</div>
<div class="px-0 input-group input-group-sm">
<div class="px-0 input-group input-group-sm flex-lg-nowrap me-2">
<span class="input-group-text py-0 align-content-center">
<span class="form-check form-switch pe-2 align-content-center">
<label class="form-check-label">Auto Restart</label>
<input class="form-check-input" type="checkbox" @bind="@AutoRestart">
<input class="form-check-input" type="checkbox" @bind="@AutoRestart" title="Auto Restart">
</span>
</span>
@if (!autoRestart)
@if (!AutoRestart)
{
<input class="form-input text-center" @bind="countAutoRestart" style="width: 4rem;" />
<input class="form-control text-center" @bind="countAutoRestart" style="width: 4rem;" />
<button class="btn btn-sm btn-outline-primary" @onclick="DelayRestart" title="Ritarda abilitazione automatica al restart processo"><i class="fa-solid fa-plus"></i></button>
}
</div>
<div class="px-0 input-group input-group-sm">
<div class="px-0 input-group input-group-sm flex-lg-nowrap">
<span class="input-group-text py-0">
<span class="form-text">Log Level</span>
</span>
<select @bind="@LogLevel" class="form-select bg-light text-dark text-start" title="Livello log">
<select @bind="@LogLevel" class="form-select bg-light text-dark text-start" title="Livello log" style="width: 6rem;">
@foreach (var item in Enum.GetValues(typeof(CoreEnum.LogLevelIob)))
{
<option value="@item">@item</option>
@@ -89,7 +90,7 @@
<th>Prog</th>
<th>Tipo</th>
<th>pID</th>
<th>Started</th>
@* <th>Started</th> *@
<th>Uptime</th>
<th class="">Run | PLC | Online</th>
<th class="text-end">Pz.IOB</th>
@@ -138,8 +139,8 @@
<td class="@CssClassIob(item)">@item.TgtName</td>
<td class="@CssClassIob(item)">@item.IobType</td>
<td class="@CssClassIob(item)">@item.pID</td>
<td>@item.startTime</td>
<td>@item.uptime</td>
@* <td title="@item.startTime">@item.startTime.ToString("HH:mm:ss")</td> *@
<td title="Started at @item.startTime">@item.uptime</td>
<td>
@if (item.isRunning)
{
@@ -172,7 +173,7 @@
<td class="text-end">@item.queueFlLen</td>
<td class="text-end">@item.sentFlHour</td>
<td class="text-end">@item.readBandwith</td>
<td class="text-end">@item.lastPlcRead</td>
<td class="text-end" title="@item.lastPlcRead">@item.lastPlcRead.ToString("HH:mm:ss")</td>
<td class="text-end">@item.ExeName</td>
<td>
@if (item.isRunning)
@@ -36,21 +36,24 @@ namespace IOB_MAN8.App.Components.Compo
protected bool AutoRestart
{
get => autoRestart;
get => ACService.AutoRestartEnabled;
set
{
autoRestart = value;
ACService.DelayRestart(!value);
currPage = 1;
ForceReload();
if (ACService.AutoRestartEnabled != value)
{
ACService.AutoRestartEnabled = value;
// eseguo check/riavvio...
if (value)
{
DoRestartClosed();
ACService.DoReopenClosed();
}
else
{
countAutoRestart = "0000";
ACService.DelayRestart(!value);
}
currPage = 1;
ForceReload();
}
}
}
@@ -183,11 +186,6 @@ namespace IOB_MAN8.App.Components.Compo
//ForceReload();
}
protected void DoRestartClosed()
{
// chiude tutto
ACService.DoReopenClosed();
}
/// <summary>
/// Mostra in primo piano tutte le finestre IOB
@@ -306,8 +304,6 @@ namespace IOB_MAN8.App.Components.Compo
#region Private Properties
private bool autoRestart { get; set; } = true;
private string ComputerName
{
get => Environment.MachineName;
@@ -378,7 +374,7 @@ namespace IOB_MAN8.App.Components.Compo
private void ACService_EA_StatusUpdated()
{
// verifico gestione atuorestart...
if (!autoRestart)
if (!AutoRestart)
{
var remSec = (int)ACService.VetoAutoCheck.Subtract(DateTime.Now).TotalSeconds;
countAutoRestart = remSec > 0 ? $"{remSec:N0}" : "!!!";
+1 -4
View File
@@ -42,11 +42,8 @@ namespace IOB_MAN8.App.Components.Pages
protected async Task ForceCheck()
{
#if false
await ACService.DoFullCheckAsync(true);
#endif
ACService.DoAutoRestart(true);
await ACService.DoScan();
await ACService.DoTaskCheckAsync(true);
}
protected override async Task OnInitializedAsync()
+1 -1
View File
@@ -7,7 +7,7 @@
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
<Version>1.02506.1116</Version>
<Version>4.0.2506.1120</Version>
<Configurations>Debug;Release;Remote_DEBUG</Configurations>
</PropertyGroup>
<ItemGroup>
+21
View File
@@ -0,0 +1,21 @@
@ECHO OFF
SET EXEName=IOB-MAN.exe
SET EXEFullPath=C:\Steamware\IOB-MAN8\IOB-MAN8.App.exe
REM Controllo se ci sia upgrade in corso x NON riavviare...
IF EXIST "C:\Steamware\IOB-MAN\update.run" (
REM Update in corso: NON faccio nulla
) ELSE (
REM Do another thing
TASKLIST | FINDSTR /I "%EXEName%"
IF ERRORLEVEL 1 GOTO :StartIobMan
)
REM "Programma ancora in run, nessuna azione necessaria"
timeout /T 1
GOTO :EOF
:StartIobMan
START "" "%EXEFullPath%"
GOTO :EOF
+6 -1
View File
@@ -1,10 +1,15 @@
{
"RefreshIntMSec": 1000,
"Redis": "localhost, DefaultDatabase=10, connectTimeout=5000, syncTimeout=5000, asyncTimeout=5000, abortConnect=false, ssl=false, allowAdmin=true",
"IobAdapt": {
"ConfDir": "CONF",
"ConfFile": "IOB-MAN-CONFIG.json"
},
"TaskData": {
"TimerFastMSec": 1000,
"TimerCheckMSec": 30000,
"AutoRebootMinutes": 1440,
"AutoRebootSched": "00:30:00"
},
"OptKVP": {
"BaseArgs": "MODE=MAN IOB=",
"DelayTimerRestart": 15
+81 -57
View File
@@ -13,57 +13,6 @@ namespace IOB_MAN8.Core.Config
{
#region Public Properties
#if false
/// <summary>
/// Chiave specifica autorizzazione applicativo
/// </summary>
public string AppKey { get; set; } = "";
/// <summary>
/// Nome applicativo
/// default: UpdateManager
/// </summary>
public string CodApp { get; set; } = "UpdateManager";
/// <summary>
/// Verifica ci siano tutte le info di comunicazione
/// </summary>
public bool HasCommData
{
get => !string.IsNullOrEmpty(MainKey) && !string.IsNullOrEmpty(AppKey);
}
/// <summary>
/// Chiave principale di autorizzazione
/// </summary>
public string MainKey { get; set; } = "";
/// <summary>
/// Elenco degli oggetti da monitorare per update
/// </summary>
public List<ControlTarget> TargetList { get; set; } = new List<ControlTarget>();
/// <summary>
/// Veto prima di effettuare un nuovo controllo automatico COMPLETO
/// </summary>
public int VetoCheckMinutes { get; set; } = 120;
/// <summary>
/// Veto prima di effettuare un refresh di base
/// </summary>
public int VetoRefreshMinutes { get; set; } = 60;
#endif
/// <summary>
/// Tempo del tick-timer per verifica scadenza task di controllo stato
/// </summary>
public int RefreshIntMSec { get; set; } = 2000;
/// <summary>
/// Stringa connessione REDIS
/// </summary>
public string Redis { get; set; } = "localhost, DefaultDatabase=10, connectTimeout=5000, syncTimeout=5000, asyncTimeout=5000, abortConnect=false, ssl=false";
/// <summary>
/// Abilitazione notifiche in tray
/// </summary>
@@ -79,11 +28,19 @@ namespace IOB_MAN8.Core.Config
/// </summary>
public Dictionary<string, string> OptKVP { get; set; } = new Dictionary<string, string>();
public class IobAdaptConf
{
public string ConfDir { get; set; } = "CONF";
public string ConfFile { get; set; } = "IOB-MAN-CONFIG.json";
}
/// <summary>
/// Stringa connessione REDIS
/// </summary>
public string Redis { get; set; } = "localhost, DefaultDatabase=10, connectTimeout=5000, syncTimeout=5000, asyncTimeout=5000, abortConnect=false, ssl=false";
/// <summary>
/// Configurazione timers e schedularzione x reboot
/// </summary>
public TaskConf TaskData { get; set; } = new TaskConf();
#endregion Public Properties
#region Public Methods
/// <summary>
/// Restituisce chiave se presente nel dizionario OptKVP
@@ -111,7 +68,7 @@ namespace IOB_MAN8.Core.Config
if (OptKVP.ContainsKey(chiave))
{
var rawVal = OptKVP[chiave];
if(!string.IsNullOrEmpty(rawVal))
if (!string.IsNullOrEmpty(rawVal))
{
int.TryParse(rawVal, out answ);
}
@@ -119,6 +76,73 @@ namespace IOB_MAN8.Core.Config
return answ;
}
#endregion Public Methods
#region Public Classes
public class IobAdaptConf
{
#region Public Properties
public string ConfDir { get; set; } = "CONF";
public string ConfFile { get; set; } = "IOB-MAN-CONFIG.json";
#endregion Public Properties
}
public class TaskConf
{
#region Public Properties
/// <summary>
/// Abilitazione autoreboot (da verifica conf)
/// </summary>
[NotMapped]
public bool AutoRebootEnabled
{
get => !string.IsNullOrEmpty(AutoRebootSched) && AutoRebootSched.Contains(":");
}
/// <summary>
/// Intervallo in minuti esecuzione task, default 1440 = 1 day
/// </summary>
public int AutoRebootMinutes { get; set; } = 1440;
/// <summary>
/// DataOra autoreboot, se != null è abilitato
/// </summary>
public string AutoRebootSched { get; set; } = "";
/// <summary>
/// Data ora autoriavvio come timespan sul giorno, default zero = midnight
/// </summary>
[NotMapped]
public TimeSpan AutoRebootTSpan
{
get
{
TimeSpan answ = new TimeSpan(0);
if (AutoRebootSched.Contains(":"))
{
TimeSpan.TryParse(AutoRebootSched, out answ);
}
return answ;
}
}
/// <summary>
/// Tempo del timer per verifica riavvio processi fermati in caso d autorestart abilitato
/// </summary>
public int TimerCheckMSec { get; set; } = 40000;
/// <summary>
/// Tempo del tick-timer per verifica scadenza task di controllo stato
/// </summary>
public int TimerFastMSec { get; set; } = 2000;
#endregion Public Properties
}
#endregion Public Classes
}
}
+97 -87
View File
@@ -5,6 +5,7 @@ using IOB_MAN8.Core.Config;
using IOB_MAN8.Core.Data;
using IOB_MAN8.Core.Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;
using StackExchange.Redis;
using System.Collections.Concurrent;
@@ -18,7 +19,7 @@ using static System.Net.Mime.MediaTypeNames;
namespace IOB_MAN8.Core.Services
{
public class AppControlService : IAppControlService
public class AppControlService : IAppControlService, IDisposable
{
#region Public Fields
@@ -42,25 +43,14 @@ namespace IOB_MAN8.Core.Services
#region Public Constructors
/// <summary>
/// Init classe
/// </summary>
public AppControlService()
{
try
{
mainAssembly = Assembly.GetCallingAssembly();
string startDir = Path.GetDirectoryName(mainAssembly.Location)!;
ConfDirBase = startDir;
// init configurazioni
DoReloadConfig();
LoadConfAndStart();
}
// init servizio Redis monitoring
DoSetupRedis();
Log.Trace($"Config setup done | ConfPathApp: {ConfPathApp} | ConfPathIob: {ConfPathIob}");
}
catch (Exception exc)
{
Log.Error($"Error in AppControlService.init:{Environment.NewLine}{exc}");
}
}
#endregion Public Constructors
@@ -95,6 +85,17 @@ namespace IOB_MAN8.Core.Services
#region Public Properties
/// <summary>
/// Abilitazione autorestart
/// </summary>
public bool AutoRestartEnabled { get; set; } = true;
public int CheckRestartPeriod
{
get => CurrAppConf.TaskData.TimerCheckMSec;
set => CurrAppConf.TaskData.TimerCheckMSec = value;
}
/// <summary>
/// ABilitazione glocale notifiche da conf
/// </summary>
@@ -152,13 +153,13 @@ namespace IOB_MAN8.Core.Services
public int RefreshPeriod
{
get => CurrAppConf.RefreshIntMSec;
get => CurrAppConf.TaskData.TimerFastMSec;
set
{
if (CurrAppConf.RefreshIntMSec != value)
if (CurrAppConf.TaskData.TimerFastMSec != value)
{
// verifico ammissibilità
CurrAppConf.RefreshIntMSec = value < refPMin ? refPMin : value > refPMax ? refPMax : value;
CurrAppConf.TaskData.TimerFastMSec = value < refPMin ? refPMin : value > refPMax ? refPMax : value;
ReportConfigUpd();
}
}
@@ -183,6 +184,23 @@ namespace IOB_MAN8.Core.Services
ReportConfigUpd();
}
public void Dispose()
{
DoCloseAll(true);
}
/// <summary>
/// Se abilitato esegue riavvio e report processi variati
/// </summary>
/// <param name="doForce">se true esegue anche prima della scadenza veto</param>
public void DoAutoRestart(bool doForce)
{
if (AutoRestartEnabled || doForce)
{
DoReopenClosed();
}
}
/// <summary>
/// Chiude tutti i child
/// </summary>
@@ -401,73 +419,6 @@ namespace IOB_MAN8.Core.Services
ReportStatusUpd();
}
/// <summary>
/// Effettua un controllo dei task da eseguire
/// </summary>
/// <param name="doForce">se true esegue anche prima della scadenza veto</param>
public async Task DoTaskCheckAsync(bool doForce)
{
DateTime adesso = DateTime.Now;
await Task.Delay(1);
bool sendStats = false;
#if false
if (vetoTaskCheck < adesso || doForce || numFastCheck > 0)
{
Stopwatch sw = new Stopwatch();
sw.Start();
// veto random prossimo controllo default 2 min (media)...
double vetoSec = (double)rnd.Next(10000, 14000) / 100;
if (numFastCheck > 0)
{
numFastCheck--;
}
// verifica se ci siano task da eseguire...
var task2exe = await CurrCheck.TaskGetReq(DeviceName);
if (task2exe != null && task2exe.Count > 0)
{
CloudCallActive = true;
// in primis li segnala in running...
await CurrCheck.TaskSetRunningAsync(DeviceName, task2exe);
// imposto limite a scalare x i prox fast check avendo trovato task da eseguire...
numFastCheck = RuntimeConfInt("CountNumFastCheck");
Dictionary<string, string> taskResults = new Dictionary<string, string>();
// eseguo 1:1 ...
foreach (var currTask in task2exe)
{
var cResp = await ExecuteTask(currTask);
// provo ad accodare risposte...
foreach (var resp in cResp)
{
if (taskResults.ContainsKey(resp.Key))
{
taskResults[resp.Key] = resp.Value;
}
else
{
taskResults.Add(resp.Key, resp.Value);
}
}
}
// invio risposta esito esecuzione finale
await CurrCheck.TaskSetDoneAsync(DeviceName, taskResults);
sendStats = true;
CloudCallActive = false;
}
// imposto veto controlli task
vetoTaskCheck = adesso.AddSeconds(vetoSec);
// Collezione statistiche esecuzione
sw.Stop();
StatsCollector.UpdateStat($"TaskCheck", sw.Elapsed);
if (sendStats)
{
// invio statistiche esecuzione...
await DoSendRunStats();
}
}
#endif
}
public string IobTgtPath(string codIOB)
{
string answ = "";
@@ -629,10 +580,15 @@ namespace IOB_MAN8.Core.Services
protected DateTime _VetoAutoCheck = DateTime.Now;
protected string ConfDirBase = "";
protected string DeviceName = "";
protected int numProcConfig;
protected int numProcRunning;
protected int numProcStarted;
protected int numTypeConfig;
#endregion Protected Fields
@@ -640,7 +596,9 @@ namespace IOB_MAN8.Core.Services
#region Protected Properties
protected AppSettings CurrAppConf { get; set; } = new AppSettings();
protected IobManConfig CurrIobConf { get; set; } = new IobManConfig();
protected SubLicManager SubLicManager { get; set; } = new SubLicManager();
#endregion Protected Properties
@@ -706,7 +664,9 @@ namespace IOB_MAN8.Core.Services
private DateTime lastCheckDone = DateTime.Today.AddMonths(-1);
private LogLevelIob logLevel = LogLevelIob.Info;
private Assembly mainAssembly = Assembly.GetExecutingAssembly();
private int minDelayrestart = 30;
/// <summary>
@@ -1033,6 +993,40 @@ namespace IOB_MAN8.Core.Services
}
}
/// <summary>
/// Esecuzione init configurazione + restart globale
/// </summary>
private void LoadConfAndStart()
{
try
{
mainAssembly = Assembly.GetCallingAssembly();
string startDir = Path.GetDirectoryName(mainAssembly.Location)!;
ConfDirBase = startDir;
// init configurazioni
DoReloadConfig();
// init servizio Redis monitoring
DoSetupRedis();
Log.Trace($"Config setup done | ConfPathApp: {ConfPathApp} | ConfPathIob: {ConfPathIob}");
// sistemo log a INFO
SetIobLogLevel("INFO");
Log.Trace($"Log set to INFO");
// avvio i processi...
DoOpenAllChild();
Log.Trace($"Child Opened");
// avvio timers e schedulazioni varie
StartScheduler();
}
catch (Exception exc)
{
Log.Error($"Error in AppControlService.init:{Environment.NewLine}{exc}");
}
}
private void ReportConfigUpd()
{
if (EA_ConfigUpdated != null)
@@ -1097,6 +1091,22 @@ namespace IOB_MAN8.Core.Services
}
}
/// <summary>
/// Avvia schedulatore reboot
/// </summary>
private void StartScheduler()
{
// avvio lo schedulatore, se abilitato...
if (CurrAppConf.TaskData.AutoRebootEnabled)
{
var dtReq = CurrAppConf.TaskData.AutoRebootTSpan;
TaskSchedulerService.IntervalInMinutes(dtReq.Hours, dtReq.Minutes, CurrAppConf.TaskData.AutoRebootMinutes, () =>
{
LoadConfAndStart();
});
}
}
private void UpdateCounters()
{
numProcStarted = ListIobAdapters.Where(x => x.isRunning).Count();
@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IOB_MAN8.Core.Services
{
/// <summary>
/// Classe di gestione Scheduler scadenziabili
///
/// rif https://codinginfinite.com/creating-scheduler-task-seconds-minutes-hours-days/
/// </summary>
public class SchedulerService
{
private static SchedulerService _instance;
private List<Timer> timers = new List<Timer>();
private SchedulerService() { }
public static SchedulerService Instance => _instance ?? (_instance = new SchedulerService());
public void ScheduleTask(int hour, int min, double intervalInHour, Action task)
{
DateTime now = DateTime.Now;
DateTime firstRun = new DateTime(now.Year, now.Month, now.Day, hour, min, 0, 0);
if (now > firstRun)
{
firstRun = firstRun.AddDays(1);
}
TimeSpan timeToGo = firstRun - now;
if (timeToGo <= TimeSpan.Zero)
{
timeToGo = TimeSpan.Zero;
}
var timer = new Timer(x =>
{
task.Invoke();
}, null, timeToGo, TimeSpan.FromHours(intervalInHour));
timers.Add(timer);
}
}
}
@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IOB_MAN8.Core.Services
{
public static class TaskSchedulerService
{
public static void IntervalInSeconds(int hour, int sec, double interval, Action task)
{
interval = interval / 3600;
SchedulerService.Instance.ScheduleTask(hour, sec, interval, task);
}
public static void IntervalInMinutes(int hour, int min, double interval, Action task)
{
interval = interval / 60;
SchedulerService.Instance.ScheduleTask(hour, min, interval, task);
}
public static void IntervalInHours(int hour, int min, double interval, Action task)
{
SchedulerService.Instance.ScheduleTask(hour, min, interval, task);
}
public static void IntervalInDays(int hour, int min, double interval, Action task)
{
interval = interval * 24;
SchedulerService.Instance.ScheduleTask(hour, min, interval, task);
}
}
}
+1 -1
View File
@@ -1 +1 @@
1.0
4.0.