Overview
Gallery.Maintenance is a console executable background job that performs periodic housekeeping operations directly against the NuGet Gallery SQL database. It follows the standard NuGet Jobs pattern, extending JsonConfigurationJob from NuGet.Jobs.Common and driven by JobRunner, which handles the run loop, Application Insights telemetry, sleep intervals, and optional continuous-run vs. run-once behavior.
The job’s architecture is built around an extensible MaintenanceTask abstract base class. On each run, Job uses reflection to discover every concrete, non-abstract subclass of MaintenanceTask in its own assembly, instantiates each one with a typed ILogger<T>, and executes them sequentially. If any task throws, its failure is recorded and the job continues running the remaining tasks, then throws a summary exception at the end to signal an unhealthy exit to the job runner. This means a single broken task does not prevent other maintenance work from completing.
Currently the only implemented task is DeleteExpiredApiKeysTask, which queries the Credentials and Scopes tables for apikey.verify.* and apikey.v5 credential types whose Expires timestamp is in the past, logs each found record, then deletes the matching rows from both tables within a SQL transaction.
Role in System
Task Discovery via Reflection
Job.GetMaintenanceTasks() scans its own assembly at runtime for all concrete MaintenanceTask subclasses. Adding a new maintenance operation only requires creating a new class — no registration step needed.Fault-Tolerant Orchestration
Individual task failures are caught, logged, and deferred. All tasks run on every iteration; a summary exception is raised afterwards only if at least one task failed.
Transactional Credential Cleanup
DeleteExpiredApiKeysTask deletes expired credentials and their associated scopes atomically within a SQL transaction, with up to 3 retries on the SELECT and a 5-minute command timeout.Windows Service Deployment
Packaged as a NuGet package with PowerShell pre/post deploy scripts that use NSSM to register, configure automatic restart, and start/stop the job as a Windows service.
Key Files and Classes
Dependencies
NuGet Package References
Internal Project References
Notable Patterns and Implementation Details
New maintenance tasks are added by creating a new
MaintenanceTask subclass with a constructor that accepts ILogger<TTask>. No manual registration is required — Job.GetMaintenanceTasks() discovers subclasses automatically using Assembly.GetTypes(). The constructor signature requirement is enforced at runtime via reflection; a missing or mismatched constructor will throw a NullReferenceException when the task is being instantiated.