1- using FWO . Basics ;
1+ using FWO . Basics ;
22using FWO . Data . Report ;
33using FWO . Api . Client ;
44using FWO . Api . Client . Queries ;
88using FWO . Report ;
99using System . Timers ;
1010using FWO . Config . File ;
11+ using System . Collections . Concurrent ;
12+ using System ;
13+ using MethodTimer ;
14+ using System . Reflection ;
1115
1216namespace FWO . Middleware . Server
1317{
@@ -16,8 +20,7 @@ namespace FWO.Middleware.Server
1620 /// </summary>
1721 public class ReportScheduler
1822 {
19- private readonly object scheduledReportsLock = new ( ) ;
20- private List < ReportSchedule > scheduledReports = [ ] ;
23+ private ConcurrentBag < ReportSchedule > scheduledReports = [ ] ;
2124 private readonly TimeSpan CheckScheduleInterval = TimeSpan . FromMinutes ( 1 ) ;
2225
2326 private readonly string apiServerUri ;
@@ -27,7 +30,6 @@ public class ReportScheduler
2730 private readonly GraphQlApiSubscription < ReportSchedule [ ] > scheduledReportsSubscription ;
2831 private readonly JwtWriter jwtWriter ;
2932
30- private readonly object ldapLock = new ( ) ;
3133 private List < Ldap > connectedLdaps ;
3234
3335 /// <summary>
@@ -54,18 +56,12 @@ public ReportScheduler(ApiConnection apiConnection, JwtWriter jwtWriter, GraphQl
5456
5557 private void OnLdapUpdate ( List < Ldap > connectedLdaps )
5658 {
57- lock ( ldapLock )
58- {
59- this . connectedLdaps = connectedLdaps ;
60- }
59+ this . connectedLdaps = connectedLdaps ;
6160 }
6261
6362 private void OnScheduleUpdate ( ReportSchedule [ ] scheduledReports )
6463 {
65- lock ( scheduledReportsLock )
66- {
67- this . scheduledReports = [ .. scheduledReports ] ;
68- }
64+ this . scheduledReports = [ .. scheduledReports ] ;
6965 }
7066
7167 private void ApiExceptionHandler ( Exception exception )
@@ -74,22 +70,22 @@ private void ApiExceptionHandler(Exception exception)
7470 // Subscription will be restored if no exception is thrown here
7571 }
7672
73+ [ Time ]
7774 private async void CheckSchedule ( object ? _ , ElapsedEventArgs __ )
7875 {
7976 List < Task > reportGeneratorTasks = [ ] ;
8077
8178 DateTime dateTimeNowRounded = RoundDown ( DateTime . Now , CheckScheduleInterval ) ;
8279
83- lock ( scheduledReports )
84- {
85- foreach ( ReportSchedule reportSchedule in scheduledReports )
80+ await Parallel . ForEachAsync ( scheduledReports , new ParallelOptions ( ) { MaxDegreeOfParallelism = Environment . ProcessorCount } ,
81+ async ( reportSchedule , ct ) =>
8682 {
8783 try
8884 {
89- if ( reportSchedule . Active )
85+ if ( reportSchedule . Active )
9086 {
9187 // Add schedule interval as long as schedule time is smaller then current time
92- while ( RoundDown ( reportSchedule . StartTime , CheckScheduleInterval ) < dateTimeNowRounded )
88+ while ( RoundDown ( reportSchedule . StartTime , CheckScheduleInterval ) < dateTimeNowRounded )
9389 {
9490 reportSchedule . StartTime = reportSchedule . RepeatInterval switch
9591 {
@@ -102,26 +98,24 @@ private async void CheckSchedule(object? _, ElapsedEventArgs __)
10298 } ;
10399 }
104100
105- if ( RoundDown ( reportSchedule . StartTime , CheckScheduleInterval ) == dateTimeNowRounded )
101+ if ( RoundDown ( reportSchedule . StartTime , CheckScheduleInterval ) == dateTimeNowRounded )
106102 {
107- reportGeneratorTasks . Add ( GenerateReport ( reportSchedule , dateTimeNowRounded ) ) ;
103+ await GenerateReport ( reportSchedule , dateTimeNowRounded , ct ) ;
108104 }
109105 }
110106 }
111- catch ( Exception exception )
107+ catch ( Exception exception )
112108 {
113109 Log . WriteError ( "Report Scheduling" , "Checking scheduled reports lead to exception." , exception ) ;
114110 }
115- }
116- }
111+ } ) ;
117112
118- await Task . WhenAll ( reportGeneratorTasks ) ;
119113 }
120114
121- private Task GenerateReport ( ReportSchedule reportSchedule , DateTime dateTimeNowRounded )
115+ [ Time ]
116+ private async Task GenerateReport ( ReportSchedule reportSchedule , DateTime dateTimeNowRounded , CancellationToken token )
122117 {
123- CancellationToken token = new ( ) ;
124- return Task . Run ( async ( ) =>
118+ await Task . Run ( async ( ) =>
125119 {
126120 try
127121 {
@@ -157,6 +151,10 @@ private Task GenerateReport(ReportSchedule reportSchedule, DateTime dateTimeNowR
157151 Log . WriteInfo ( "Report Scheduling" , $ "Scheduled report \" { reportSchedule . Name } \" with id \" { reportSchedule . Id } \" for user \" { reportSchedule . ScheduleOwningUser . Name } \" with id \" { reportSchedule . ScheduleOwningUser . DbId } \" was empty.") ;
158152 }
159153 }
154+ catch ( TaskCanceledException )
155+ {
156+ Log . WriteWarning ( "Report Scheduling" , $ "Generating scheduled report was cancelled") ;
157+ }
160158 catch ( Exception exception )
161159 {
162160 Log . WriteError ( "Report Scheduling" , $ "Generating scheduled report \" { reportSchedule . Name } \" with id \" { reportSchedule . Id } \" lead to exception.", exception ) ;
0 commit comments