@@ -76,8 +76,9 @@ protected override void LoadComplete()
76
76
{
77
77
Logger . Log ( "Beginning background data store processing.." ) ;
78
78
79
- checkForOutdatedStarRatings ( ) ;
80
- processBeatmapSetsWithMissingMetrics ( ) ;
79
+ clearOutdatedStarRatings ( ) ;
80
+ populateMissingStarRatings ( ) ;
81
+ processOnlineBeatmapSetsWithNoUpdate ( ) ;
81
82
// Note that the previous method will also update these on a fresh run.
82
83
processBeatmapsWithMissingObjectCounts ( ) ;
83
84
processScoresWithMissingStatistics ( ) ;
@@ -100,7 +101,7 @@ protected override void LoadComplete()
100
101
/// Check whether the databased difficulty calculation version matches the latest ruleset provided version.
101
102
/// If it doesn't, clear out any existing difficulties so they can be incrementally recalculated.
102
103
/// </summary>
103
- private void checkForOutdatedStarRatings ( )
104
+ private void clearOutdatedStarRatings ( )
104
105
{
105
106
foreach ( var ruleset in rulesetStore . AvailableRulesets )
106
107
{
@@ -132,7 +133,86 @@ private void checkForOutdatedStarRatings()
132
133
}
133
134
}
134
135
135
- private void processBeatmapSetsWithMissingMetrics ( )
136
+ /// <remarks>
137
+ /// This is split out from <see cref="processOnlineBeatmapSetsWithNoUpdate"/> as a separate process to prevent high server-side load
138
+ /// from the <see cref="beatmapUpdater"/> firing online requests as part of the update.
139
+ /// Star rating recalculations can be ran strictly locally.
140
+ /// </remarks>
141
+ private void populateMissingStarRatings ( )
142
+ {
143
+ HashSet < Guid > beatmapIds = new HashSet < Guid > ( ) ;
144
+
145
+ Logger . Log ( "Querying for beatmaps with missing star ratings..." ) ;
146
+
147
+ realmAccess . Run ( r =>
148
+ {
149
+ foreach ( var b in r . All < BeatmapInfo > ( ) . Where ( b => b . StarRating < 0 && b . BeatmapSet != null ) )
150
+ beatmapIds . Add ( b . ID ) ;
151
+ } ) ;
152
+
153
+ if ( beatmapIds . Count == 0 )
154
+ return ;
155
+
156
+ Logger . Log ( $ "Found { beatmapIds . Count } beatmaps which require star rating reprocessing.") ;
157
+
158
+ var notification = showProgressNotification ( beatmapIds . Count , "Reprocessing star rating for beatmaps" , "beatmaps' star ratings have been updated" ) ;
159
+
160
+ int processedCount = 0 ;
161
+ int failedCount = 0 ;
162
+
163
+ Dictionary < string , Ruleset > rulesetCache = new Dictionary < string , Ruleset > ( ) ;
164
+
165
+ Ruleset getRuleset ( RulesetInfo rulesetInfo )
166
+ {
167
+ if ( ! rulesetCache . TryGetValue ( rulesetInfo . ShortName , out var ruleset ) )
168
+ ruleset = rulesetCache [ rulesetInfo . ShortName ] = rulesetInfo . CreateInstance ( ) ;
169
+
170
+ return ruleset ;
171
+ }
172
+
173
+ foreach ( Guid id in beatmapIds )
174
+ {
175
+ if ( notification ? . State == ProgressNotificationState . Cancelled )
176
+ break ;
177
+
178
+ updateNotificationProgress ( notification , processedCount , beatmapIds . Count ) ;
179
+
180
+ sleepIfRequired ( ) ;
181
+
182
+ var beatmap = realmAccess . Run ( r => r . Find < BeatmapInfo > ( id ) ? . Detach ( ) ) ;
183
+
184
+ if ( beatmap == null )
185
+ return ;
186
+
187
+ try
188
+ {
189
+ var working = beatmapManager . GetWorkingBeatmap ( beatmap ) ;
190
+ var ruleset = getRuleset ( working . BeatmapInfo . Ruleset ) ;
191
+
192
+ Debug . Assert ( ruleset != null ) ;
193
+
194
+ var calculator = ruleset . CreateDifficultyCalculator ( working ) ;
195
+
196
+ double starRating = calculator . Calculate ( ) . StarRating ;
197
+ realmAccess . Write ( r =>
198
+ {
199
+ if ( r . Find < BeatmapInfo > ( id ) is BeatmapInfo liveBeatmapInfo )
200
+ liveBeatmapInfo . StarRating = starRating ;
201
+ } ) ;
202
+ ( ( IWorkingBeatmapCache ) beatmapManager ) . Invalidate ( beatmap ) ;
203
+ ++ processedCount ;
204
+ }
205
+ catch ( Exception e )
206
+ {
207
+ Logger . Log ( $ "Background processing failed on { beatmap } : { e } ") ;
208
+ ++ failedCount ;
209
+ }
210
+ }
211
+
212
+ completeNotification ( notification , processedCount , beatmapIds . Count , failedCount ) ;
213
+ }
214
+
215
+ private void processOnlineBeatmapSetsWithNoUpdate ( )
136
216
{
137
217
HashSet < Guid > beatmapSetIds = new HashSet < Guid > ( ) ;
138
218
@@ -148,23 +228,17 @@ private void processBeatmapSetsWithMissingMetrics()
148
228
// of other possible ways), but for now avoid queueing if the user isn't logged in at startup.
149
229
if ( api . IsLoggedIn )
150
230
{
151
- foreach ( var b in r . All < BeatmapInfo > ( ) . Where ( b => ( b . StarRating < 0 || ( b . OnlineID > 0 && b . LastOnlineUpdate == null ) ) && b . BeatmapSet != null ) )
152
- beatmapSetIds . Add ( b . BeatmapSet ! . ID ) ;
153
- }
154
- else
155
- {
156
- foreach ( var b in r . All < BeatmapInfo > ( ) . Where ( b => b . StarRating < 0 && b . BeatmapSet != null ) )
231
+ foreach ( var b in r . All < BeatmapInfo > ( ) . Where ( b => b . OnlineID > 0 && b . LastOnlineUpdate == null && b . BeatmapSet != null ) )
157
232
beatmapSetIds . Add ( b . BeatmapSet ! . ID ) ;
158
233
}
159
234
} ) ;
160
235
161
236
if ( beatmapSetIds . Count == 0 )
162
237
return ;
163
238
164
- Logger . Log ( $ "Found { beatmapSetIds . Count } beatmap sets which require reprocessing .") ;
239
+ Logger . Log ( $ "Found { beatmapSetIds . Count } beatmap sets which require online updates .") ;
165
240
166
- // Technically this is doing more than just star ratings, but easier for the end user to understand.
167
- var notification = showProgressNotification ( beatmapSetIds . Count , "Reprocessing star rating for beatmaps" , "beatmaps' star ratings have been updated" ) ;
241
+ var notification = showProgressNotification ( beatmapSetIds . Count , "Updating online data for beatmaps" , "beatmaps' online data have been updated" ) ;
168
242
169
243
int processedCount = 0 ;
170
244
int failedCount = 0 ;
0 commit comments