2022-03-15 18:00:53 +00:00
// (c) Copyright Ascensio System SIA 2010-2022
//
// This program is a free software product.
// You can redistribute it and/or modify it under the terms
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
// any third-party rights.
//
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
//
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// The interactive user interfaces in modified source and object code versions of the Program must
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
//
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
// trademark law for use of our trademarks.
//
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
2022-02-15 11:52:43 +00:00
namespace ASC.Notify.Engine ;
2022-03-31 17:32:46 +00:00
public interface INotifyEngineAction
{
void BeforeTransferRequest ( NotifyRequest request ) ;
void AfterTransferRequest ( NotifyRequest request ) ;
}
2022-03-25 14:51:03 +00:00
[Singletone]
2022-04-14 13:52:51 +00:00
public class NotifyEngine : INotifyEngine , IDisposable
2022-02-15 11:52:43 +00:00
{
2022-04-26 17:53:48 +00:00
private readonly ILogger _logger ;
2022-02-15 11:52:43 +00:00
private readonly Context _context ;
private readonly List < SendMethodWrapper > _sendMethods = new List < SendMethodWrapper > ( ) ;
private readonly Queue < NotifyRequest > _requests = new Queue < NotifyRequest > ( 1000 ) ;
private readonly Thread _notifyScheduler ;
private readonly Thread _notifySender ;
private readonly AutoResetEvent _requestsEvent = new AutoResetEvent ( false ) ;
private readonly AutoResetEvent _methodsEvent = new AutoResetEvent ( false ) ;
private readonly Dictionary < string , IPatternStyler > _stylers = new Dictionary < string , IPatternStyler > ( ) ;
private readonly IPatternFormatter _sysTagFormatter = new ReplacePatternFormatter ( @"_#(?<tagName>[A-Z0-9_\-.]+)#_" , true ) ;
private readonly TimeSpan _defaultSleep = TimeSpan . FromSeconds ( 10 ) ;
2022-03-31 17:32:46 +00:00
private readonly IServiceScopeFactory _serviceScopeFactory ;
internal readonly ICollection < Type > Actions ;
2022-02-15 11:52:43 +00:00
2022-04-26 17:53:48 +00:00
public NotifyEngine ( Context context , ILoggerProvider options , IServiceScopeFactory serviceScopeFactory )
2022-02-15 11:52:43 +00:00
{
2022-03-31 17:32:46 +00:00
Actions = new List < Type > ( ) ;
2022-02-15 11:52:43 +00:00
_context = context ? ? throw new ArgumentNullException ( nameof ( context ) ) ;
2022-04-26 17:53:48 +00:00
_logger = options . CreateLogger ( "ASC.Notify" ) ;
2022-03-31 17:32:46 +00:00
_serviceScopeFactory = serviceScopeFactory ;
2022-02-15 11:52:43 +00:00
_notifyScheduler = new Thread ( NotifyScheduler ) { IsBackground = true , Name = "NotifyScheduler" } ;
_notifySender = new Thread ( NotifySender ) { IsBackground = true , Name = "NotifySender" } ;
}
2022-03-31 17:32:46 +00:00
public void AddAction < T > ( ) where T : INotifyEngineAction
{
Actions . Add ( typeof ( T ) ) ;
}
2022-02-15 11:52:43 +00:00
2022-03-31 17:32:46 +00:00
public void QueueRequest ( NotifyRequest request )
2022-02-15 11:52:43 +00:00
{
lock ( _requests )
{
if ( ! _notifySender . IsAlive )
{
_notifySender . Start ( ) ;
2022-02-14 21:02:57 +00:00
}
2022-02-15 11:52:43 +00:00
_requests . Enqueue ( request ) ;
}
_requestsEvent . Set ( ) ;
}
internal void RegisterSendMethod ( Action < DateTime > method , string cron )
{
2022-03-09 17:15:51 +00:00
ArgumentNullException . ThrowIfNull ( method ) ;
ArgumentNullOrEmptyException . ThrowIfNullOrEmpty ( cron ) ;
2022-02-15 11:52:43 +00:00
var w = new SendMethodWrapper ( method , cron , _logger ) ;
lock ( _sendMethods )
{
if ( ! _notifyScheduler . IsAlive )
2022-02-14 21:02:57 +00:00
{
2022-02-15 11:52:43 +00:00
_notifyScheduler . Start ( ) ;
2022-02-14 21:02:57 +00:00
}
2022-02-15 11:52:43 +00:00
_sendMethods . Remove ( w ) ;
_sendMethods . Add ( w ) ;
}
_methodsEvent . Set ( ) ;
}
internal void UnregisterSendMethod ( Action < DateTime > method )
{
2022-03-09 17:15:51 +00:00
ArgumentNullException . ThrowIfNull ( method ) ;
2022-02-15 11:52:43 +00:00
lock ( _sendMethods )
{
_sendMethods . Remove ( new SendMethodWrapper ( method , null , _logger ) ) ;
}
}
private void NotifyScheduler ( object state )
{
try
{
while ( true )
2022-02-14 21:02:57 +00:00
{
2022-02-15 11:52:43 +00:00
var min = DateTime . MaxValue ;
var now = DateTime . UtcNow ;
List < SendMethodWrapper > copy ;
lock ( _sendMethods )
{
copy = _sendMethods . ToList ( ) ;
}
foreach ( var w in copy )
{
if ( ! w . ScheduleDate . HasValue )
{
lock ( _sendMethods )
{
_sendMethods . Remove ( w ) ;
}
}
if ( w . ScheduleDate . Value < = now )
{
try
{
w . InvokeSendMethod ( now ) ;
}
catch ( Exception error )
{
2022-05-05 14:13:47 +00:00
_logger . ErrorInvokeSendMethod ( error ) ;
2022-02-15 11:52:43 +00:00
}
w . UpdateScheduleDate ( now ) ;
}
if ( w . ScheduleDate . Value > now & & w . ScheduleDate . Value < min )
{
min = w . ScheduleDate . Value ;
}
}
var wait = min ! = DateTime . MaxValue ? min - DateTime . UtcNow : _defaultSleep ;
if ( wait < _defaultSleep )
{
wait = _defaultSleep ;
}
else if ( wait . Ticks > int . MaxValue )
{
wait = TimeSpan . FromTicks ( int . MaxValue ) ;
}
_methodsEvent . WaitOne ( wait , false ) ;
2022-02-14 21:02:57 +00:00
}
2022-02-15 11:52:43 +00:00
}
catch ( ThreadAbortException )
{
return ;
}
catch ( Exception e )
{
2022-05-05 14:13:47 +00:00
_logger . ErrorNotifyScheduler ( e ) ;
2022-02-15 11:52:43 +00:00
}
}
2022-02-14 21:02:57 +00:00
2022-02-15 11:52:43 +00:00
private void NotifySender ( object state )
{
try
{
while ( true )
2022-02-14 21:02:57 +00:00
{
2022-02-15 11:52:43 +00:00
NotifyRequest request = null ;
lock ( _requests )
{
if ( _requests . Count > 0 )
{
request = _requests . Dequeue ( ) ;
}
}
if ( request ! = null )
{
2022-03-31 17:32:46 +00:00
using var scope = _serviceScopeFactory . CreateScope ( ) ;
foreach ( var action in Actions )
{
( ( INotifyEngineAction ) scope . ServiceProvider . GetRequiredService ( action ) ) . AfterTransferRequest ( request ) ;
}
2022-02-15 11:52:43 +00:00
try
{
SendNotify ( request , scope ) ;
}
catch ( Exception e )
{
2022-05-05 14:13:47 +00:00
_logger . ErrorSendNotify ( e ) ;
2022-02-15 11:52:43 +00:00
}
}
else
{
_requestsEvent . WaitOne ( ) ;
}
2022-02-14 21:02:57 +00:00
}
2022-02-15 11:52:43 +00:00
}
catch ( ThreadAbortException )
{
return ;
}
catch ( Exception e )
{
2022-05-05 14:13:47 +00:00
_logger . ErrorNotifySender ( e ) ;
2022-02-15 11:52:43 +00:00
}
}
2022-02-14 21:02:57 +00:00
2022-02-15 11:52:43 +00:00
private NotifyResult SendNotify ( NotifyRequest request , IServiceScope serviceScope )
{
var sendResponces = new List < SendResponse > ( ) ;
var response = CheckPreventInterceptors ( request , InterceptorPlace . Prepare , serviceScope , null ) ;
if ( response ! = null )
{
sendResponces . Add ( response ) ;
}
else
{
sendResponces . AddRange ( SendGroupNotify ( request , serviceScope ) ) ;
}
NotifyResult result ;
if ( sendResponces . Count = = 0 )
{
result = new NotifyResult ( SendResult . OK , sendResponces ) ;
}
else
{
result = new NotifyResult ( sendResponces . Aggregate ( ( SendResult ) 0 , ( s , r ) = > r . Result ) , sendResponces ) ;
}
2022-05-05 14:13:47 +00:00
_logger . Debug ( result . ToString ( ) ) ;
2022-02-15 11:52:43 +00:00
return result ;
}
private SendResponse CheckPreventInterceptors ( NotifyRequest request , InterceptorPlace place , IServiceScope serviceScope , string sender )
{
return request . Intercept ( place , serviceScope ) ? new SendResponse ( request . NotifyAction , sender , request . Recipient , SendResult . Prevented ) : null ;
}
private List < SendResponse > SendGroupNotify ( NotifyRequest request , IServiceScope serviceScope )
{
var responces = new List < SendResponse > ( ) ;
SendGroupNotify ( request , responces , serviceScope ) ;
return responces ;
}
private void SendGroupNotify ( NotifyRequest request , List < SendResponse > responces , IServiceScope serviceScope )
{
if ( request . Recipient is IDirectRecipient )
{
var subscriptionSource = request . GetSubscriptionProvider ( serviceScope ) ;
2022-03-17 16:57:02 +00:00
if ( ! request . _isNeedCheckSubscriptions | | ! subscriptionSource . IsUnsubscribe ( request . Recipient as IDirectRecipient , request . NotifyAction , request . ObjectID ) )
2022-02-15 11:52:43 +00:00
{
var directresponses = new List < SendResponse > ( 1 ) ;
try
{
directresponses = SendDirectNotify ( request , serviceScope ) ;
}
catch ( Exception exc )
{
directresponses . Add ( new SendResponse ( request . NotifyAction , request . Recipient , exc ) ) ;
}
responces . AddRange ( directresponses ) ;
}
}
else
{
if ( request . Recipient is IRecipientsGroup )
{
var checkresp = CheckPreventInterceptors ( request , InterceptorPlace . GroupSend , serviceScope , null ) ;
if ( checkresp ! = null )
{
responces . Add ( checkresp ) ;
}
else
{
var recipientProvider = request . GetRecipientsProvider ( serviceScope ) ;
try
{
var recipients = recipientProvider . GetGroupEntries ( request . Recipient as IRecipientsGroup ) ? ? new IRecipient [ 0 ] ;
foreach ( var recipient in recipients )
{
try
{
var newRequest = request . Split ( recipient ) ;
SendGroupNotify ( newRequest , responces , serviceScope ) ;
}
catch ( Exception exc )
{
responces . Add ( new SendResponse ( request . NotifyAction , request . Recipient , exc ) ) ;
}
}
2022-02-14 21:02:57 +00:00
}
2022-02-15 11:52:43 +00:00
catch ( Exception exc )
{
responces . Add ( new SendResponse ( request . NotifyAction , request . Recipient , exc ) { Result = SendResult . IncorrectRecipient } ) ;
}
}
}
else
2022-02-14 21:02:57 +00:00
{
2022-02-15 11:52:43 +00:00
responces . Add ( new SendResponse ( request . NotifyAction , request . Recipient , null )
{
Result = SendResult . IncorrectRecipient ,
Exception = new NotifyException ( "recipient may be IRecipientsGroup or IDirectRecipient" )
} ) ;
2022-02-14 21:02:57 +00:00
}
2022-02-15 11:52:43 +00:00
}
}
2022-02-14 21:02:57 +00:00
2022-02-15 11:52:43 +00:00
private List < SendResponse > SendDirectNotify ( NotifyRequest request , IServiceScope serviceScope )
{
2022-04-14 19:23:57 +00:00
if ( request . Recipient is not IDirectRecipient )
2022-02-15 11:52:43 +00:00
{
throw new ArgumentException ( "request.Recipient not IDirectRecipient" , nameof ( request ) ) ;
}
var responses = new List < SendResponse > ( ) ;
var response = CheckPreventInterceptors ( request , InterceptorPlace . DirectSend , serviceScope , null ) ;
if ( response ! = null )
{
responses . Add ( response ) ;
return responses ;
}
try
{
PrepareRequestFillSenders ( request , serviceScope ) ;
PrepareRequestFillPatterns ( request , serviceScope ) ;
PrepareRequestFillTags ( request , serviceScope ) ;
}
catch ( Exception ex )
{
responses . Add ( new SendResponse ( request . NotifyAction , null , request . Recipient , SendResult . Impossible ) ) ;
2022-05-05 14:13:47 +00:00
_logger . ErrorPrepare ( ex ) ;
2022-02-15 11:52:43 +00:00
}
2022-03-17 16:57:02 +00:00
if ( request . _senderNames ! = null & & request . _senderNames . Length > 0 )
2022-02-15 11:52:43 +00:00
{
2022-03-17 16:57:02 +00:00
foreach ( var sendertag in request . _senderNames )
2022-02-15 11:52:43 +00:00
{
2022-03-25 14:51:03 +00:00
var channel = _context . GetSender ( sendertag ) ;
2022-02-15 11:52:43 +00:00
if ( channel ! = null )
{
try
{
response = SendDirectNotify ( request , channel , serviceScope ) ;
2022-02-14 21:02:57 +00:00
}
2022-02-15 11:52:43 +00:00
catch ( Exception exc )
{
response = new SendResponse ( request . NotifyAction , channel . SenderName , request . Recipient , exc ) ;
}
}
else
{
response = new SendResponse ( request . NotifyAction , sendertag , request . Recipient , new NotifyException ( $"Not registered sender \" { sendertag } \ "." ) ) ;
}
responses . Add ( response ) ;
2022-02-14 21:02:57 +00:00
}
2022-02-15 11:52:43 +00:00
}
else
{
response = new SendResponse ( request . NotifyAction , request . Recipient , new NotifyException ( "Notice hasn't any senders." ) ) ;
responses . Add ( response ) ;
}
return responses ;
}
private SendResponse SendDirectNotify ( NotifyRequest request , ISenderChannel channel , IServiceScope serviceScope )
{
2022-04-14 19:23:57 +00:00
if ( request . Recipient is not IDirectRecipient )
2022-02-15 11:52:43 +00:00
{
throw new ArgumentException ( "request.Recipient not IDirectRecipient" , nameof ( request ) ) ;
}
request . CurrentSender = channel . SenderName ;
var oops = CreateNoticeMessageFromNotifyRequest ( request , channel . SenderName , serviceScope , out var noticeMessage ) ;
if ( oops ! = null )
{
return oops ;
}
request . CurrentMessage = noticeMessage ;
var preventresponse = CheckPreventInterceptors ( request , InterceptorPlace . MessageSend , serviceScope , channel . SenderName ) ;
if ( preventresponse ! = null )
{
return preventresponse ;
}
channel . SendAsync ( noticeMessage ) ;
return new SendResponse ( noticeMessage , channel . SenderName , SendResult . Inprogress ) ;
}
private SendResponse CreateNoticeMessageFromNotifyRequest ( NotifyRequest request , string sender , IServiceScope serviceScope , out NoticeMessage noticeMessage )
{
2022-03-09 17:15:51 +00:00
ArgumentNullException . ThrowIfNull ( request ) ;
2022-02-15 11:52:43 +00:00
var recipientProvider = request . GetRecipientsProvider ( serviceScope ) ;
var recipient = request . Recipient as IDirectRecipient ;
var addresses = recipient . Addresses ;
if ( addresses = = null | | addresses . Length = = 0 )
{
addresses = recipientProvider . GetRecipientAddresses ( request . Recipient as IDirectRecipient , sender ) ;
recipient = new DirectRecipient ( request . Recipient . ID , request . Recipient . Name , addresses ) ;
}
recipient = recipientProvider . FilterRecipientAddresses ( recipient ) ;
noticeMessage = request . CreateMessage ( recipient ) ;
addresses = recipient . Addresses ;
if ( addresses = = null | | ! addresses . Any ( a = > ! string . IsNullOrEmpty ( a ) ) )
{
//checking addresses
return new SendResponse ( request . NotifyAction , sender , recipient , new NotifyException ( string . Format ( "For recipient {0} by sender {1} no one addresses getted." , recipient , sender ) ) ) ;
}
var pattern = request . GetSenderPattern ( sender ) ;
if ( pattern = = null )
{
return new SendResponse ( request . NotifyAction , sender , recipient , new NotifyException ( string . Format ( "For action \"{0}\" by sender \"{1}\" no one patterns getted." , request . NotifyAction , sender ) ) ) ;
}
noticeMessage . Pattern = pattern ;
noticeMessage . ContentType = pattern . ContentType ;
noticeMessage . AddArgument ( request . Arguments . ToArray ( ) ) ;
var patternProvider = request . GetPatternProvider ( serviceScope ) ;
var formatter = patternProvider . GetFormatter ( pattern ) ;
try
{
if ( formatter ! = null )
2022-02-14 21:02:57 +00:00
{
2022-02-15 11:52:43 +00:00
formatter . FormatMessage ( noticeMessage , noticeMessage . Arguments ) ;
2022-02-14 21:02:57 +00:00
}
2022-02-15 11:52:43 +00:00
_sysTagFormatter . FormatMessage (
noticeMessage , new [ ]
{
2022-03-25 14:54:34 +00:00
new TagValue ( Context . SysRecipientId , request . Recipient . ID ) ,
new TagValue ( Context . SysRecipientName , request . Recipient . Name ) ,
new TagValue ( Context . SysRecipientAddress , addresses ! = null & & addresses . Length > 0 ? addresses [ 0 ] : null )
2022-02-15 11:52:43 +00:00
}
) ;
//Do styling here
if ( ! string . IsNullOrEmpty ( pattern . Styler ) )
{
//We need to run through styler before templating
StyleMessage ( serviceScope , noticeMessage ) ;
}
}
catch ( Exception exc )
{
return new SendResponse ( request . NotifyAction , sender , recipient , exc ) ;
}
2022-02-14 21:02:57 +00:00
2022-02-15 11:52:43 +00:00
return null ;
}
private void StyleMessage ( IServiceScope scope , NoticeMessage message )
{
try
{
if ( ! _stylers . ContainsKey ( message . Pattern . Styler ) )
2022-02-14 21:02:57 +00:00
{
2022-02-15 11:52:43 +00:00
if ( scope . ServiceProvider . GetService ( Type . GetType ( message . Pattern . Styler , true ) ) is IPatternStyler styler )
{
_stylers . Add ( message . Pattern . Styler , styler ) ;
}
2022-02-14 21:02:57 +00:00
}
2022-02-15 11:52:43 +00:00
_stylers [ message . Pattern . Styler ] . ApplyFormating ( message ) ;
}
catch ( Exception exc )
{
2022-05-05 14:13:47 +00:00
_logger . WarningErrorStyling ( exc ) ;
2022-02-15 11:52:43 +00:00
}
}
private void PrepareRequestFillSenders ( NotifyRequest request , IServiceScope serviceScope )
{
2022-03-17 16:57:02 +00:00
if ( request . _senderNames = = null )
2022-02-15 11:52:43 +00:00
{
var subscriptionProvider = request . GetSubscriptionProvider ( serviceScope ) ;
var senderNames = new List < string > ( ) ;
senderNames . AddRange ( subscriptionProvider . GetSubscriptionMethod ( request . NotifyAction , request . Recipient ) ? ? Array . Empty < string > ( ) ) ;
senderNames . AddRange ( request . Arguments . OfType < AdditionalSenderTag > ( ) . Select ( tag = > ( string ) tag . Value ) ) ;
2022-03-17 16:57:02 +00:00
request . _senderNames = senderNames . ToArray ( ) ;
2022-02-15 11:52:43 +00:00
}
}
2022-02-14 21:02:57 +00:00
2022-02-15 11:52:43 +00:00
private void PrepareRequestFillPatterns ( NotifyRequest request , IServiceScope serviceScope )
{
2022-03-17 16:57:02 +00:00
if ( request . _patterns = = null )
2022-02-15 11:52:43 +00:00
{
2022-03-17 16:57:02 +00:00
request . _patterns = new IPattern [ request . _senderNames . Length ] ;
if ( request . _patterns . Length = = 0 )
2022-02-14 21:02:57 +00:00
{
2022-02-15 11:52:43 +00:00
return ;
2022-02-14 21:02:57 +00:00
}
2022-02-15 11:52:43 +00:00
var apProvider = request . GetPatternProvider ( serviceScope ) ;
2022-03-17 16:57:02 +00:00
for ( var i = 0 ; i < request . _senderNames . Length ; i + + )
2022-02-14 21:02:57 +00:00
{
2022-03-17 16:57:02 +00:00
var senderName = request . _senderNames [ i ] ;
2022-02-15 11:52:43 +00:00
IPattern pattern = null ;
if ( apProvider . GetPatternMethod ! = null )
{
pattern = apProvider . GetPatternMethod ( request . NotifyAction , senderName , request ) ;
}
if ( pattern = = null )
{
pattern = apProvider . GetPattern ( request . NotifyAction , senderName ) ;
}
2022-03-17 16:57:02 +00:00
request . _patterns [ i ] = pattern ? ? throw new NotifyException ( $"For action \" { request . NotifyAction . ID } \ " by sender \"{senderName}\" no one patterns getted." ) ;
2022-02-14 21:02:57 +00:00
}
2022-02-15 11:52:43 +00:00
}
}
2022-02-14 21:02:57 +00:00
2022-02-15 11:52:43 +00:00
private void PrepareRequestFillTags ( NotifyRequest request , IServiceScope serviceScope )
{
var patternProvider = request . GetPatternProvider ( serviceScope ) ;
2022-03-17 16:57:02 +00:00
foreach ( var pattern in request . _patterns )
2022-02-15 11:52:43 +00:00
{
IPatternFormatter formatter ;
try
{
formatter = patternProvider . GetFormatter ( pattern ) ;
2022-02-14 21:02:57 +00:00
}
2022-02-15 11:52:43 +00:00
catch ( Exception exc )
{
throw new NotifyException ( string . Format ( "For pattern \"{0}\" formatter not instanced." , pattern ) , exc ) ;
}
var tags = Array . Empty < string > ( ) ;
try
{
if ( formatter ! = null )
2022-02-14 21:02:57 +00:00
{
2022-02-15 11:52:43 +00:00
tags = formatter . GetTags ( pattern ) ? ? Array . Empty < string > ( ) ;
2022-02-14 21:02:57 +00:00
}
2022-02-15 11:52:43 +00:00
}
catch ( Exception exc )
{
throw new NotifyException ( string . Format ( "Get tags from formatter of pattern \"{0}\" failed." , pattern ) , exc ) ;
}
2022-02-14 21:02:57 +00:00
2022-03-17 16:57:02 +00:00
foreach ( var tag in tags . Where ( tag = > ! request . Arguments . Exists ( tagValue = > Equals ( tagValue . Tag , tag ) ) & & ! request . _requaredTags . Exists ( rtag = > Equals ( rtag , tag ) ) ) )
2022-02-15 11:52:43 +00:00
{
2022-03-17 16:57:02 +00:00
request . _requaredTags . Add ( tag ) ;
2022-02-15 11:52:43 +00:00
}
}
}
private sealed class SendMethodWrapper
{
private readonly object _locker = new object ( ) ;
private readonly CronExpression _cronExpression ;
private readonly Action < DateTime > _method ;
public DateTime ? ScheduleDate { get ; private set ; }
2022-04-26 17:53:48 +00:00
public ILogger Logger { get ; }
2022-02-15 11:52:43 +00:00
2022-04-26 17:53:48 +00:00
public SendMethodWrapper ( Action < DateTime > method , string cron , ILogger log )
2022-02-15 11:52:43 +00:00
{
_method = method ;
Logger = log ;
if ( ! string . IsNullOrEmpty ( cron ) )
{
_cronExpression = new CronExpression ( cron ) ;
}
UpdateScheduleDate ( DateTime . UtcNow ) ;
}
public void UpdateScheduleDate ( DateTime d )
{
try
{
if ( _cronExpression ! = null )
{
ScheduleDate = _cronExpression . GetTimeAfter ( d ) ;
2022-02-14 21:02:57 +00:00
}
2022-02-15 11:52:43 +00:00
}
catch ( Exception e )
{
2022-05-05 14:13:47 +00:00
Logger . ErrorUpdateScheduleDate ( e ) ;
2022-02-15 11:52:43 +00:00
}
}
public void InvokeSendMethod ( DateTime d )
{
lock ( _locker )
{
Task . Run ( ( ) = >
{
try
{
_method ( d ) ;
}
catch ( Exception e )
{
2022-05-05 14:13:47 +00:00
Logger . ErrorInvokeSendMethod ( e ) ;
2022-02-15 11:52:43 +00:00
}
} ) . Wait ( ) ;
}
}
public override bool Equals ( object obj )
{
return obj is SendMethodWrapper w & & _method . Equals ( w . _method ) ;
}
public override int GetHashCode ( )
{
return _method . GetHashCode ( ) ;
}
}
2022-04-14 13:52:51 +00:00
public void Dispose ( )
{
if ( _methodsEvent ! = null )
{
_methodsEvent . Dispose ( ) ;
}
if ( _requestsEvent ! = null )
{
_requestsEvent . Dispose ( ) ;
}
}
2022-03-31 17:32:46 +00:00
}
[Scope]
public class NotifyEngineQueue
{
private readonly NotifyEngine _notifyEngine ;
private readonly IServiceProvider _serviceProvider ;
public NotifyEngineQueue ( NotifyEngine notifyEngine , IServiceProvider serviceProvider )
{
_notifyEngine = notifyEngine ;
_serviceProvider = serviceProvider ;
}
public void QueueRequest ( NotifyRequest request )
{
foreach ( var action in _notifyEngine . Actions )
{
( ( INotifyEngineAction ) _serviceProvider . GetRequiredService ( action ) ) . BeforeTransferRequest ( request ) ;
}
_notifyEngine . QueueRequest ( request ) ;
}
2019-05-15 14:56:09 +00:00
}