I am working on .NET Core 'Worker Service' project to implement service for Windows & Linux OS.
Service reading data from external config.xml file like credentials/urls. I want to add interval time too in config file so that in future if I want change interval time(ex. every hour to every 2 hour), I will just update config file, I not need to modify and recompile the code.
I am using Coraval library for scheduling. Setting interval time in Main method. My doubt is when I will change interval time in config file(being read in Main method), how will it get assigned for further executions? for Windows and Linux.
How often Main method getting called so that it will read new scheduling time from config file?
This is my code
public static void Main(string[] args)
{
var schedulingConfig = GlobalSettings.ReadIntervals(out List<intervalValue> intervalvalues);
string intrvaltype = string.Empty;
foreach (var item in schedulingConfig)
{
if (item.Name == "true")
{
intrvaltype = item.Execution;
break;
}
}
IHost host = CreateHostBuilder(args).Build();
host.Services.UseScheduler(scheduler =>
{
//Remind schedular to repeat the same job
switch (intrvaltype)
{
case "isSignleHourInADay":
scheduler
.Schedule<ReprocessInvocable>()
.Hourly();
break;
case "isMinutes":
scheduler
.Schedule<ReprocessInvocable>()
.EveryFiveMinutes();
break;
case "isOnceInADay":
scheduler
.Schedule<ReprocessInvocable>()
.Daily();
break;
case "isSecond":
scheduler
.Schedule<ReprocessInvocable>()
.EveryThirtySeconds();
break;
}
});
host.Run();
}
Where should I keep my code so that it will do the needful?
Edit1
Program.cs class
public class Program
{
public static void Main(string[] args)
{
IHost host = CreateHostBuilder(args).Build();
host.Services.UseScheduler(scheduler =>
{
scheduler
.Schedule<ReprocessInvocable>()
.Hourly()
.When(() => IsRun("isSignleHourInADay"));
scheduler
.Schedule<ReprocessInvocable>()
.EveryFiveMinutes()
.When(() => IsRun("isMinutes"));
scheduler
.Schedule<ReprocessInvocable>()
.Daily()
.When(() => IsRun("isOnceInADay"));
scheduler
.Schedule<ReprocessInvocable>()
.EveryThirtySeconds()
.When(() => IsRun("isSecond"));
});
host.Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
services.AddScheduler();
}).UseSerilog().UseSystemd();
static Task<bool> IsRun(string intervalType)
{
return Task.Run(() =>
{
var schedulingConfig = ConfigData();
string configIntrvalType = schedulingConfig.FirstOrDefault(i => i.Name == "true")?.Execution;
return intervalType == configIntrvalType;
});
}
public static List<intervalValue> ConfigData()
{
return new List<intervalValue> { new intervalValue { Execution= "isSignleHourInADay", Name="false"},
new intervalValue { Execution= "isMinutes", Name="true"},
new intervalValue { Execution= "isOnceInADay", Name="false"},
new intervalValue { Execution= "isSecond", Name="false"},
new intervalValue { Execution= "isMultipleHoursInADay", Name="false"},
};
}
public class intervalValue
{
public string Execution { get; set; }
public string Name { get; set; }
}
}
ReprocessInvocable.cs class
public class ReprocessInvocable : IInvocable
{
private readonly ILogger<ReprocessInvocable> _logger;
public ReprocessInvocable(ILogger<ReprocessInvocable> logger)
{
_logger = logger;
}
public async Task Invoke()
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
Log.Information("Invoke has called at: {time}", DateTimeOffset.Now);
}
}
Edit2
This is StatusConfigTest2.xml file
<?xml version="1.0" encoding="UTF-8"?>
<parameters>
<intervalValue>
<Definition Execution="isMultipleHoursInADayVal" Name="1AM,4PM,6AM"></Definition>
<Definition Execution="isSignleHourInADayVal" Name="4AM"></Definition>
<Definition Execution="isMinutesVal" Name="5"></Definition>
<Definition Execution="isOnceInADayVal" Name="5PM"></Definition>
<Definition Execution="isSecondVal" Name="20"></Definition>
</intervalValue>
<intervalType>
<Definition Execution="isMultipleHoursInADay" Name="false"></Definition>
<Definition Execution="isSignleHourInADay" Name="false"></Definition>
<Definition Execution="isMinutes" Name="true"></Definition>
<Definition Execution="isOnceInADay" Name="false"></Definition>
<Definition Execution="isSecond" Name="false"></Definition>
</intervalType>
</parameters>
Method to read xml file
public static List<intervalValue> GetFilterProducts1(out List<intervalValue>
intervalValueout)
{
List<intervalValue> IntrvalValueList = new List<intervalValue>();
List<intervalValue> IntervalTypeList = new List<intervalValue>();
try
{
FileStream fs = null;
var files = new List<string>();
files.Add("D:/ProductStatusConfigTest2.xml");
//file2
//file3
foreach (var file in files)
{
try
{
fs = new FileStream(file, FileMode.Open, FileAccess.Read);
break;
}
catch (Exception ex)
{
//throw;
}
}
XmlDocument doc = new XmlDocument();
doc.Load(fs);
XmlNode node = doc.DocumentElement.SelectSingleNode("/parameters/intervalValue");
{
for (int i = 0; i < node.ChildNodes.Count; i++)
{
IntrvalValueList.Add(new intervalValue { Name = node.ChildNodes[i].Attributes["Name"].Value, Execution = node.ChildNodes[i].Attributes["Execution"].Value });
}
}
XmlNode node2 = doc.DocumentElement.SelectSingleNode("/parameters/intervalType");
{
for (int i = 0; i < node.ChildNodes.Count; i++)
{
IntervalTypeList.Add(new intervalValue { Name = node2.ChildNodes[i].Attributes["Name"].Value, Execution = node2.ChildNodes[i].Attributes["Execution"].Value });
}
}
intervalValueout = IntrvalValueList;
return IntervalTypeList;
}
catch (Exception ex)
{
intervalValueout = IntervalTypeList;
return IntervalTypeList;
}
}