55using System . Collections . Generic ;
66using System . Linq ;
77using System . Threading . Tasks ;
8+ using Microsoft . Extensions . DependencyInjection ;
89using Microsoft . Extensions . Logging ;
910using NuGet . Services . Validation ;
1011using NuGet . Versioning ;
@@ -18,19 +19,22 @@ public class InitializationManager
1819 private readonly IRevalidationJobStateService _jobState ;
1920 private readonly IPackageRevalidationStateService _packageState ;
2021 private readonly IPackageFinder _packageFinder ;
22+ private readonly IServiceScopeFactory _scopeFactory ;
2123 private readonly InitializationConfiguration _config ;
2224 private readonly ILogger < InitializationManager > _logger ;
2325
2426 public InitializationManager (
2527 IRevalidationJobStateService jobState ,
2628 IPackageRevalidationStateService packageState ,
2729 IPackageFinder packageFinder ,
30+ IServiceScopeFactory scopeFactory ,
2831 InitializationConfiguration config ,
2932 ILogger < InitializationManager > logger )
3033 {
3134 _jobState = jobState ?? throw new ArgumentNullException ( nameof ( jobState ) ) ;
3235 _packageState = packageState ?? throw new ArgumentNullException ( nameof ( packageState ) ) ;
3336 _packageFinder = packageFinder ?? throw new ArgumentNullException ( nameof ( packageFinder ) ) ;
37+ _scopeFactory = scopeFactory ?? throw new ArgumentNullException ( nameof ( scopeFactory ) ) ;
3438 _config = config ?? throw new ArgumentNullException ( nameof ( config ) ) ;
3539 _logger = logger ?? throw new ArgumentNullException ( nameof ( logger ) ) ;
3640 }
@@ -122,59 +126,83 @@ private async Task ClearPackageRevalidationStateAsync()
122126
123127 private async Task InitializePackageSetAsync ( string setName , HashSet < int > packageRegistrationKeys )
124128 {
125- var packageInformations = await _packageFinder . FindPackageRegistrationInformationAsync ( setName , packageRegistrationKeys ) ;
129+ using ( var scope = _scopeFactory . CreateScope ( ) )
130+ {
131+ var scopedPackageFinder = scope . ServiceProvider . GetRequiredService < IPackageFinder > ( ) ;
132+ var scopedJobState = scope . ServiceProvider . GetRequiredService < IRevalidationJobStateService > ( ) ;
133+ var scopedScopeFactory = scope . ServiceProvider . GetRequiredService < IServiceScopeFactory > ( ) ;
126134
127- var chunks = packageInformations
128- . OrderByDescending ( p => p . Downloads )
129- . WeightedBatch ( BatchSize , p => p . Versions ) ;
135+ var packageInformations = await scopedPackageFinder . FindPackageRegistrationInformationAsync ( setName , packageRegistrationKeys ) ;
136+ var chunks = packageInformations
137+ . OrderByDescending ( p => p . Downloads )
138+ . WeightedBatch ( BatchSize , p => p . Versions ) ;
130139
131- for ( var chunkIndex = 0 ; chunkIndex < chunks . Count ; chunkIndex ++ )
132- {
133- while ( await _jobState . IsKillswitchActiveAsync ( ) )
140+ for ( var chunkIndex = 0 ; chunkIndex < chunks . Count ; chunkIndex ++ )
134141 {
135- _logger . LogInformation (
136- "Delaying initialization of chunk {Chunk} of {Chunks} for package set {SetName} due to active killswitch" ,
137- chunkIndex + 1 ,
138- chunks . Count ,
139- setName ) ;
142+ while ( await scopedJobState . IsKillswitchActiveAsync ( ) )
143+ {
144+ _logger . LogInformation (
145+ "Delaying initialization of chunk {Chunk} of {Chunks} for package set {SetName} due to active killswitch" ,
146+ chunkIndex + 1 ,
147+ chunks . Count ,
148+ setName ) ;
140149
141- await Task . Delay ( _config . SleepDurationBetweenBatches ) ;
150+ await Task . Delay ( _config . SleepDurationBetweenBatches ) ;
151+ }
152+
153+ await InitializePackageSetChunkAsync ( setName , chunks , chunkIndex , scopedScopeFactory , _logger ) ;
154+
155+ // Sleep if this is not the last chunk to prevent overloading the database.
156+ if ( chunkIndex < chunks . Count - 1 )
157+ {
158+ _logger . LogInformation (
159+ "Sleeping for {SleepDuration} before initializing the next chunk..." ,
160+ _config . SleepDurationBetweenBatches ) ;
161+
162+ await Task . Delay ( _config . SleepDurationBetweenBatches ) ;
163+ }
142164 }
143165
144- _logger . LogInformation (
145- "Initializing chunk {Chunk} of {Chunks} for package set {SetName}..." ,
146- chunkIndex + 1 ,
147- chunks . Count ,
148- setName ) ;
166+ _logger . LogInformation ( "Finished initializing package set {SetName}" , setName ) ;
167+ }
168+ }
169+
170+ private static async Task InitializePackageSetChunkAsync (
171+ string setName ,
172+ List < List < PackageRegistrationInformation > > chunks ,
173+ int chunkIndex ,
174+ IServiceScopeFactory scopeFactory ,
175+ ILogger < InitializationManager > logger )
176+ {
177+ logger . LogInformation (
178+ "Initializing chunk {Chunk} of {Chunks} for package set {SetName}..." ,
179+ chunkIndex + 1 ,
180+ chunks . Count ,
181+ setName ) ;
182+
183+ using ( var scope = scopeFactory . CreateScope ( ) )
184+ {
185+ var scopedPackageState = scope . ServiceProvider . GetRequiredService < IPackageRevalidationStateService > ( ) ;
186+ var scopedPackageFinder = scope . ServiceProvider . GetRequiredService < IPackageFinder > ( ) ;
149187
150188 var chunk = chunks [ chunkIndex ] ;
151- var versions = _packageFinder . FindAppropriateVersions ( chunk ) ;
189+ var versions = scopedPackageFinder . FindAppropriateVersions ( chunk ) ;
152190
153- await InitializeRevalidationsAsync ( chunk , versions ) ;
191+ await InitializeRevalidationsAsync ( chunk , versions , scopedPackageState , logger ) ;
154192
155- _logger . LogInformation (
193+ logger . LogInformation (
156194 "Initialized chunk {Chunk} of {Chunks} for package set {SetName}" ,
157195 chunkIndex + 1 ,
158196 chunks . Count ,
159197 setName ) ;
160-
161- // Sleep if this is not the last chunk to prevent overloading the database.
162- if ( chunkIndex < chunks . Count - 1 )
163- {
164- _logger . LogInformation (
165- "Sleeping for {SleepDuration} before initializing the next chunk..." ,
166- _config . SleepDurationBetweenBatches ) ;
167-
168- await Task . Delay ( _config . SleepDurationBetweenBatches ) ;
169- }
170198 }
171-
172- _logger . LogInformation ( "Finished initializing package set {SetName}" , setName ) ;
173199 }
174200
175- private async Task InitializeRevalidationsAsync (
201+ private static async Task InitializeRevalidationsAsync (
176202 List < PackageRegistrationInformation > packageRegistrations ,
177- Dictionary < int , List < NuGetVersion > > versions )
203+ Dictionary < int , List < NuGetVersion > > versions ,
204+ IPackageRevalidationStateService packageState ,
205+ ILogger < InitializationManager > logger )
178206 {
179207 var revalidations = new List < PackageRevalidation > ( ) ;
180208
@@ -184,7 +212,7 @@ private async Task InitializeRevalidationsAsync(
184212
185213 if ( ! versions . ContainsKey ( packageRegistration . Key ) || versions [ packageRegistration . Key ] . Count == 0 )
186214 {
187- _logger . LogWarning ( "Could not find any versions of package {PackageId} to revalidate" , packageId ) ;
215+ logger . LogWarning ( "Could not find any versions of package {PackageId} to revalidate" , packageId ) ;
188216
189217 continue ;
190218 }
@@ -205,7 +233,7 @@ private async Task InitializeRevalidationsAsync(
205233 }
206234 }
207235
208- await _packageState . AddPackageRevalidationsAsync ( revalidations ) ;
236+ await packageState . AddPackageRevalidationsAsync ( revalidations ) ;
209237 }
210238 }
211239}
0 commit comments