141 lines
5.8 KiB
C#
141 lines
5.8 KiB
C#
using System;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Logging;
|
|
using AyaNova.Models;
|
|
using System;
|
|
using System.Linq;
|
|
using System.Globalization;
|
|
using System.Text;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using AyaNova.Util;
|
|
using AyaNova.Models;
|
|
|
|
namespace AyaNova.Biz
|
|
{
|
|
|
|
/// <summary>
|
|
/// Notification processor
|
|
/// turn notifyEvent records into notifications for in app and deliver smtp
|
|
///
|
|
/// </summary>
|
|
internal static class CoreJobNotify
|
|
{
|
|
private static bool NotifyIsRunning = false;
|
|
private static ILogger log = AyaNova.Util.ApplicationLogging.CreateLogger("CoreJobNotify");
|
|
private static DateTime lastRun = DateTime.MinValue;
|
|
private static TimeSpan DELETE_AFTER_AGE = new TimeSpan(90, 0, 0, 0);
|
|
private static TimeSpan RUN_EVERY_INTERVAL = new TimeSpan(0, 2, 0);//once every 2 minutes minimum
|
|
private static DateTime lastNotifyHealthCheckSentLocal = DateTime.MinValue;
|
|
private static TimeSpan TS_24_HOURS = new TimeSpan(24, 0, 0);//used to ensure daily ops happen no more than that
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// DoSweep
|
|
//
|
|
public static async Task DoWorkAsync()
|
|
{
|
|
log.LogTrace("Checking if Notify should run");
|
|
if (NotifyIsRunning)
|
|
{
|
|
log.LogTrace("Notify is running already exiting this cycle");
|
|
return;
|
|
}
|
|
//This will get triggered roughly every minute, but we don't want to deliver that frequently
|
|
if (DateTime.UtcNow - lastRun < RUN_EVERY_INTERVAL)
|
|
{
|
|
log.LogTrace($"Notify ran less than {RUN_EVERY_INTERVAL}, exiting this cycle");
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
NotifyIsRunning = true;
|
|
log.LogTrace("Notify set to RUNNING state and starting now");
|
|
|
|
//NotifyHealthCheck processing
|
|
//Note this deliberately uses LOCAL time in effort to deliver the health check first thing in the morning for workers
|
|
//However if server is on UTC already then that's what is used, there is no adjustment
|
|
DateTime dtNowLocal = DateTime.Now;
|
|
if (dtNowLocal - lastNotifyHealthCheckSentLocal > TS_24_HOURS)
|
|
{
|
|
//are we in the 7th to 9th hour?
|
|
if (dtNowLocal.Hour > 6 && dtNowLocal.Hour < 10)
|
|
{
|
|
log.LogTrace("Notify health check submitted to subscribers");
|
|
await NotifyEventProcessor.AddGeneralNotifyEvent(NotifyEventType.NotifyHealthCheck, "OK");
|
|
lastNotifyHealthCheckSentLocal = dtNowLocal;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
using (AyContext ct = AyaNova.Util.ServiceProviderProvider.DBContext)
|
|
{
|
|
//select all jobs with no deliver date or deliver date no longer in future
|
|
|
|
//IMPLEMENTATION NOTES: This code
|
|
// finds the events in NotifyEvent
|
|
// check subscription to determine if the age related ones are deliverable now
|
|
// check subscriptions for each delivery type, i.e. there might be both smtp and inapp separately for the same event so it needs to know that and deliver accordingly
|
|
// remove the notify event after it's processed
|
|
|
|
|
|
|
|
//Older notes:
|
|
//### PLAN if it's an smtp delivery that fails and it's to someone who can be delivered in app then it should send an inapp notification of
|
|
//delivery failure and still delete the smtp delivery
|
|
//If it's not possible to notify the person via in app of the failed smtp then perhaps it notifies OPS personnel and biz admin personnel
|
|
//NEW NOTIFICATION SUBSCRIPTION EVENT TYPE:
|
|
//OPERATIONS_PROBLEMS - backup, notifications, out of memory, what have you, anyone can subscribe to it regardless of rights
|
|
//this is just to let people know there is a problem
|
|
//todo: create message here if not already set?
|
|
//todo: generate and attach report here?
|
|
|
|
//All items have an event date, for non time delayed events it's just the moment it was created
|
|
//which will predate this moment now if it's pre-existing
|
|
var items = await ct.NotifyEvent.Include(z => z.NotifySubscription).ToListAsync();
|
|
|
|
//iterate and deliver
|
|
foreach(var item in items){
|
|
//Time delayed ones:
|
|
//when to deliver formula: NotifyEvent "EventDate"+NotifySubscription.AgeValue timespan - NotifySubscription AdvanceNotice timespan > utcNow
|
|
if(item.)
|
|
|
|
//Immediate delivery items
|
|
//
|
|
if(item.EventDate)
|
|
}
|
|
|
|
//turn notifyEvent records into notifications for in app and deliver smtp
|
|
|
|
|
|
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
|
|
}
|
|
finally
|
|
{
|
|
log.LogTrace("Notify is done setting to not running state and tagging lastRun timestamp");
|
|
lastRun = DateTime.UtcNow;
|
|
NotifyIsRunning = false;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
}//eoc
|
|
|
|
|
|
}//eons
|
|
|