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 ;
1112
1213namespace FWO . Middleware . Server
1314{
@@ -16,8 +17,7 @@ namespace FWO.Middleware.Server
1617 /// </summary>
1718 public class ReportScheduler
1819 {
19- private readonly object scheduledReportsLock = new ( ) ;
20- private List < ReportSchedule > scheduledReports = [ ] ;
20+ private ConcurrentBag < ReportSchedule > scheduledReports = [ ] ;
2121 private readonly TimeSpan CheckScheduleInterval = TimeSpan . FromMinutes ( 1 ) ;
2222
2323 private readonly string apiServerUri ;
@@ -27,7 +27,6 @@ public class ReportScheduler
2727 private readonly GraphQlApiSubscription < ReportSchedule [ ] > scheduledReportsSubscription ;
2828 private readonly JwtWriter jwtWriter ;
2929
30- private readonly object ldapLock = new ( ) ;
3130 private List < Ldap > connectedLdaps ;
3231
3332 /// <summary>
@@ -54,18 +53,12 @@ public ReportScheduler(ApiConnection apiConnection, JwtWriter jwtWriter, GraphQl
5453
5554 private void OnLdapUpdate ( List < Ldap > connectedLdaps )
5655 {
57- lock ( ldapLock )
58- {
59- this . connectedLdaps = connectedLdaps ;
60- }
56+ this . connectedLdaps = connectedLdaps ;
6157 }
6258
6359 private void OnScheduleUpdate ( ReportSchedule [ ] scheduledReports )
6460 {
65- lock ( scheduledReportsLock )
66- {
67- this . scheduledReports = [ .. scheduledReports ] ;
68- }
61+ this . scheduledReports = [ .. scheduledReports ] ;
6962 }
7063
7164 private void ApiExceptionHandler ( Exception exception )
@@ -80,16 +73,15 @@ private async void CheckSchedule(object? _, ElapsedEventArgs __)
8073
8174 DateTime dateTimeNowRounded = RoundDown ( DateTime . Now , CheckScheduleInterval ) ;
8275
83- lock ( scheduledReports )
84- {
85- foreach ( ReportSchedule reportSchedule in scheduledReports )
76+ await Parallel . ForEachAsync ( scheduledReports , new ParallelOptions ( ) { MaxDegreeOfParallelism = Environment . ProcessorCount } ,
77+ async ( reportSchedule , ct ) =>
8678 {
8779 try
8880 {
89- if ( reportSchedule . Active )
81+ if ( reportSchedule . Active )
9082 {
9183 // Add schedule interval as long as schedule time is smaller then current time
92- while ( RoundDown ( reportSchedule . StartTime , CheckScheduleInterval ) < dateTimeNowRounded )
84+ while ( RoundDown ( reportSchedule . StartTime , CheckScheduleInterval ) < dateTimeNowRounded )
9385 {
9486 reportSchedule . StartTime = reportSchedule . RepeatInterval switch
9587 {
@@ -102,26 +94,23 @@ private async void CheckSchedule(object? _, ElapsedEventArgs __)
10294 } ;
10395 }
10496
105- if ( RoundDown ( reportSchedule . StartTime , CheckScheduleInterval ) == dateTimeNowRounded )
97+ if ( RoundDown ( reportSchedule . StartTime , CheckScheduleInterval ) == dateTimeNowRounded )
10698 {
107- reportGeneratorTasks . Add ( GenerateReport ( reportSchedule , dateTimeNowRounded ) ) ;
99+ await GenerateReport ( reportSchedule , dateTimeNowRounded , ct ) ;
108100 }
109101 }
110102 }
111- catch ( Exception exception )
103+ catch ( Exception exception )
112104 {
113105 Log . WriteError ( "Report Scheduling" , "Checking scheduled reports lead to exception." , exception ) ;
114106 }
115- }
116- }
107+ } ) ;
117108
118- await Task . WhenAll ( reportGeneratorTasks ) ;
119109 }
120110
121- private Task GenerateReport ( ReportSchedule reportSchedule , DateTime dateTimeNowRounded )
111+ private async Task GenerateReport ( ReportSchedule reportSchedule , DateTime dateTimeNowRounded , CancellationToken token )
122112 {
123- CancellationToken token = new ( ) ;
124- return Task . Run ( async ( ) =>
113+ await Task . Run ( async ( ) =>
125114 {
126115 try
127116 {
@@ -157,6 +146,10 @@ private Task GenerateReport(ReportSchedule reportSchedule, DateTime dateTimeNowR
157146 Log . WriteInfo ( "Report Scheduling" , $ "Scheduled report \" { reportSchedule . Name } \" with id \" { reportSchedule . Id } \" for user \" { reportSchedule . ScheduleOwningUser . Name } \" with id \" { reportSchedule . ScheduleOwningUser . DbId } \" was empty.") ;
158147 }
159148 }
149+ catch ( TaskCanceledException )
150+ {
151+ Log . WriteWarning ( "Report Scheduling" , $ "Generating scheduled report \" { reportSchedule . Name } \" was cancelled") ;
152+ }
160153 catch ( Exception exception )
161154 {
162155 Log . WriteError ( "Report Scheduling" , $ "Generating scheduled report \" { reportSchedule . Name } \" with id \" { reportSchedule . Id } \" lead to exception.", exception ) ;
0 commit comments