This commit is contained in:
@@ -12,7 +12,7 @@ namespace AyaNova.Biz
|
||||
|
||||
/// <summary>
|
||||
/// Notification processor
|
||||
/// turn notifyEvent records into notifications for in app and deliver smtp
|
||||
/// turn notifyEvent records into inappnotification records for in app viewing and / or deliver smtp notifications seperately
|
||||
///
|
||||
/// </summary>
|
||||
internal static class CoreJobNotify
|
||||
@@ -95,6 +95,39 @@ namespace AyaNova.Biz
|
||||
var deliverAfter = notifyevent.EventDate + Subscription.AgeValue - Subscription.AdvanceNotice;
|
||||
if (deliverAfter < DateTime.UtcNow)
|
||||
{
|
||||
//Check "circuit breaker" for notification types that could
|
||||
//repeat rapidly
|
||||
//(e.g. pm notification error for a fucked up PM that is attempted every few minutes or a
|
||||
//system exception for something that pops up every few minutes or a thousand times in a hour etc)
|
||||
//Don't check for ones that are regular object based
|
||||
//which can and will properly send out the same notification regularly
|
||||
//(e.g. workorder status change into out of and back into the same staus)
|
||||
switch (notifyevent.EventType)
|
||||
{
|
||||
case NotifyEventType.BackupStatus:
|
||||
case NotifyEventType.GeneralNotification:
|
||||
case NotifyEventType.ServerOperationsProblem:
|
||||
case NotifyEventType.PMGenerationFailed:
|
||||
{
|
||||
//check if we've just delivered this same thing in the last 12 hours which is the hard limit (case 3917)
|
||||
var twelvehoursago = DateTime.UtcNow - new TimeSpan(12, 0, 0);
|
||||
|
||||
//look for same delivery less than last12hours ago
|
||||
if (await ct.NotifyDeliveryLog.AnyAsync(z => z.Processed > twelvehoursago && z.NotifySubscriptionId == notifyevent.NotifySubscriptionId && z.ObjectId == notifyevent.ObjectId))
|
||||
{
|
||||
log.LogTrace($"Notification event will not be delivered: repetitive (server system event type and delivered at least once in the last 12 hours to this subscriber: {notifyevent})");
|
||||
ct.NotifyEvent.Remove(notifyevent);
|
||||
await ct.SaveChangesAsync();
|
||||
#if (DEBUG)
|
||||
log.LogInformation($"DeliverInApp event will not be delivered: repetitive (server system event type and delivered at least once in the last 12 hours to this subscriber: {notifyevent})");
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//Do the delivery, it's kosher
|
||||
if (Subscription.DeliveryMethod == NotifyDeliveryMethod.App)
|
||||
await DeliverInApp(notifyevent, Subscription.AgeValue, ct);
|
||||
else if (Subscription.DeliveryMethod == NotifyDeliveryMethod.SMTP)
|
||||
@@ -120,8 +153,10 @@ namespace AyaNova.Biz
|
||||
private static async Task DeliverInApp(NotifyEvent ne, TimeSpan ageValue, AyContext ct)
|
||||
{
|
||||
log.LogTrace($"DeliverInApp notify event: {ne}");
|
||||
await ct.Notification.AddAsync(
|
||||
new Notification()
|
||||
|
||||
//Place in the In-app notification table for user to view
|
||||
await ct.InAppNotification.AddAsync(
|
||||
new InAppNotification()
|
||||
{
|
||||
UserId = ne.UserId,
|
||||
AyaType = ne.AyaType,
|
||||
@@ -133,8 +168,16 @@ namespace AyaNova.Biz
|
||||
AgeValue = ageValue,
|
||||
DecValue = ne.DecValue
|
||||
});
|
||||
await ct.SaveChangesAsync();
|
||||
|
||||
ct.NotifyEvent.Remove(ne);
|
||||
//add delivery log item
|
||||
await ct.NotifyDeliveryLog.AddAsync(new NotifyDeliveryLog()
|
||||
{
|
||||
Processed = DateTime.UtcNow,
|
||||
ObjectId = ne.ObjectId,
|
||||
NotifySubscriptionId = ne.NotifySubscriptionId,
|
||||
Fail = false
|
||||
});
|
||||
await ct.SaveChangesAsync();
|
||||
}
|
||||
|
||||
@@ -142,12 +185,22 @@ namespace AyaNova.Biz
|
||||
|
||||
private static async Task DeliverSMTP(NotifyEvent ne, TimeSpan ageValue, TimeSpan advanceNotice, string deliveryAddress, AyContext ct)
|
||||
{
|
||||
var DeliveryLogItem = new NotifyDeliveryLog()
|
||||
{
|
||||
Processed = DateTime.UtcNow,
|
||||
ObjectId = ne.ObjectId,
|
||||
NotifySubscriptionId = ne.NotifySubscriptionId,
|
||||
Fail = false
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
log.LogTrace($"DeliverSMTP delivering notify event: {ne}");
|
||||
if (string.IsNullOrWhiteSpace(deliveryAddress))
|
||||
{
|
||||
await NotifyEventHelper.AddGeneralNotifyEvent(NotifyEventType.GeneralNotification, $"No email address is set in subscription to deliver email notification. This event will be removed from the delivery queue as undeliverable: {ne}", "Error", null, ne.UserId);
|
||||
DeliveryLogItem.Fail = true;
|
||||
DeliveryLogItem.Error = $"No email address provided for smtp delivery; event: {ne}";
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -241,6 +294,8 @@ namespace AyaNova.Biz
|
||||
{
|
||||
await NotifyEventHelper.AddGeneralNotifyEvent(NotifyEventType.GeneralNotification, $"Email notifications are set to OFF at server, unable to send email notification for this event:{ne}", "Error", null, ne.UserId);
|
||||
log.LogInformation($"** WARNING: SMTP notification is currently set to Active=False; unable to deliver email notification, re-routed to in-app notification instead [UserId={ne.UserId}, Notify subscription={ne.NotifySubscriptionId}]. Change this setting or have users remove email delivery notifications if this is permanent **");
|
||||
DeliveryLogItem.Fail = true;
|
||||
DeliveryLogItem.Error = $"Email notifications are set to OFF at server, unable to send email notification for this event: {ne}";
|
||||
}
|
||||
else
|
||||
await m.SendEmailAsync(deliveryAddress, subject, body, ServerGlobalOpsSettingsCache.Notify);
|
||||
@@ -251,11 +306,17 @@ namespace AyaNova.Biz
|
||||
{
|
||||
await NotifyEventHelper.AddOpsProblemEvent("SMTP Notification failed", ex);
|
||||
await NotifyEventHelper.AddGeneralNotifyEvent(NotifyEventType.GeneralNotification, $"An error prevented delivering the following notification via email. System operator users have been notified:{ne}", "Error", null, ne.UserId);
|
||||
DeliveryLogItem.Fail = true;
|
||||
DeliveryLogItem.Error = $"SMTP Notification failed to deliver for this event: {ne}, message: {ex.Message}";
|
||||
log.LogTrace(ex, $"DeliverSMTP Failure delivering notify event: {ne}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
//remove event no matter what
|
||||
ct.NotifyEvent.Remove(ne);
|
||||
|
||||
//add delivery log item
|
||||
await ct.NotifyDeliveryLog.AddAsync(DeliveryLogItem);
|
||||
await ct.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,7 @@ namespace AyaNova.Biz
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Clean up notification system, keep items down to 90 days
|
||||
///
|
||||
/// Clear out old data no longer required for notification system
|
||||
/// </summary>
|
||||
internal static class CoreNotificationSweeper
|
||||
{
|
||||
@@ -32,8 +31,8 @@ namespace AyaNova.Biz
|
||||
log.LogTrace("Sweep starting");
|
||||
using (AyContext ct = AyaNova.Util.ServiceProviderProvider.DBContext)
|
||||
{
|
||||
//Notification (App notifications table) - deletes all APP notifications older than 90 days (if they want to keep it then can turn it into a reminder or SAVE it somehow)
|
||||
await ct.Database.ExecuteSqlInterpolatedAsync($"delete from anotification where created < {dtDeleteCutoff}");
|
||||
//Notification (in-App notifications table) - deletes all APP notifications older than 90 days (if they want to keep it then can turn it into a reminder or SAVE it somehow)
|
||||
await ct.Database.ExecuteSqlInterpolatedAsync($"delete from ainappnotification where created < {dtDeleteCutoff}");
|
||||
|
||||
//NotifyEvent - deletes any notifyevent with no event date created more than 90 days ago
|
||||
await ct.Database.ExecuteSqlInterpolatedAsync($"delete from anotifyevent where eventdate is null and created < {dtDeleteCutoff}");
|
||||
@@ -42,7 +41,7 @@ namespace AyaNova.Biz
|
||||
//then deletes it if created more than 90 days ago (pretty sure there are no back dated events, once it's passed it's past)
|
||||
await ct.Database.ExecuteSqlInterpolatedAsync($"delete from anotifyevent where eventdate < {dtPastEventCutoff} and created < {dtDeleteCutoff}");
|
||||
|
||||
//NotifyDeliveryLog - deletes all log items older than 90 days
|
||||
//NotifyDeliveryLog - deletes all log items older than 90 days (NOTE: this log is also used to identify and prevent high frequency repetitive dupes)
|
||||
await ct.Database.ExecuteSqlInterpolatedAsync($"delete from anotifydeliverylog where processed < {dtDeleteCutoff}");
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user