using Comal.Classes; using InABox.Clients; using InABox.Core; using System; using System.Collections.Generic; using System.Linq; using System.Timers; namespace Comal.TaskScheduler.Shared { public class Scheduler { private Timer timer; public TimeSpan Interval { get; set; } public Scheduler() { CoreUtils.RegisterClasses(); ComalUtils.RegisterClasses(); // Set the Interval to 1 minute Interval = new TimeSpan(0, 1, 0); timer = new System.Timers.Timer(Interval.TotalMilliseconds); timer.Elapsed += new ElapsedEventHandler(CheckSchedules); } public void Start() { DoCheckSchedules(); } public void Stop() { timer.Enabled = false; } private object? GetEntity(Type type, Guid id) { if (type == typeof(Equipment)) return new Client().Load(new Filter(x => x.ID).IsEqualTo(id)).FirstOrDefault(); else if (type == typeof(Customer)) return new Client().Load(new Filter(x => x.ID).IsEqualTo(id)).FirstOrDefault(); else if (type == typeof(Employee)) return new Client().Load(new Filter(x => x.ID).IsEqualTo(id)).FirstOrDefault(); else if (type == typeof(CustomModule)) return new Client().Load(new Filter(x => x.ID).IsEqualTo(id)).FirstOrDefault(); else if (type == typeof(ScheduledScript)) return new Client().Load(new Filter(x => x.ID).IsEqualTo(id)).FirstOrDefault(); return null; //var type = schedule.DocumentType; //IClient client = ClientFactory.CreateClient(type); //var filter = new Filter(x => x.ID).IsEqualTo(schedule.DocumentID); //Entity entity = client.Load(filter).FirstOrDefault(); //var item = entity as ISchedulable; } private void DoCheckSchedules() { timer.Enabled = false; Logger.Send(LogType.Information, ClientFactory.UserID, "Checking Schedules"); var scheduleClient = new Client(); try { Schedule[] schedules = scheduleClient.Load( new Filter(x => x.DocumentClass).IsNotEqualTo("") .And(x => x.DocumentID).IsNotEqualTo(Guid.Empty) .And(x => x.Active).IsEqualTo(true) //.And(x => x.DueDate).IsLessThan(DateTime.Now) ); EmployeeRole[] EmployeeRoles = new Client().Load(); var cache = new Dictionary(); for (int i = 0; i < schedules.Length; i++) { Schedule schedule = schedules[i]; if ((schedule.DocumentClass != "") && (schedule.DocumentID != Guid.Empty)) { ISchedulePlugin? plugin = SchedulePluginFactory.GetPlugin(schedule.DocumentClass); if(plugin == null) { Logger.Send(LogType.Error, ClientFactory.UserID, $"No plugin for {schedule.DocumentClass}"); continue; } //var entity = plugin.LoadEntity(schedule.DocumentID); if (!cache.ContainsKey(schedule.DocumentClass)) { Guid[] ids = schedules.Where(x => x.DocumentClass.Equals(schedule.DocumentClass)).Select(x => x.DocumentID).ToArray(); cache[schedule.DocumentClass] = plugin.LoadEntities(ids); } var entities = cache[schedule.DocumentClass]; var entity = entities.FirstOrDefault(x => x.ID.Equals(schedule.DocumentID)); if (entity != null) { Logger.Send(LogType.Information, ClientFactory.UserID, $"- {entity} - {schedule.Title}"); try { if (!plugin.Execute(schedule, entity)) Logger.Send(LogType.Information, ClientFactory.UserID, " * Schedule not yet due"); } catch (Exception e) { Logger.Send(LogType.Information, ClientFactory.UserID, $" * Exception while processing schedule: {e.Message}\n" + String.Join("\n",e.StackTrace)); } } else Logger.Send(LogType.Information, ClientFactory.UserID, $"- {schedule.Title}: cannot find linked entity({schedule.DocumentClass})"); } } } catch (Exception err) { Logger.Send(LogType.Information, ClientFactory.UserID, err.Message + "\r\n" + err.StackTrace); } GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); timer.Enabled = true; } private void CheckSchedules(object source, ElapsedEventArgs e) { DoCheckSchedules(); } } }