Skip to content

Rules-engine worker crash-loops: IStudentResultsClient registered in a bundle without IMemoryCache #326

Description

@dfe-lance

The rules-engine worker crash-loops at startup on current main. Exit 139, restarting continuously, no queue consumer and no retention job running.

Unhandled exception. System.AggregateException: Some services are not able to be constructed
(Error while validating the service descriptor 'ServiceType:
DfE.CheckPerformanceData.Application.ResultsEnquiry.IStudentResultsClient Lifetime: Scoped
ImplementationType: DfE.CheckPerformanceData.Infrastructure.BlobStorage.StudentResultsBlobClient':
Unable to resolve service for type 'Microsoft.Extensions.Caching.Memory.IMemoryCache' while
attempting to activate 'StudentResultsBlobClient'.)

Cause

8f89b358 added to AddInfrastructureDependencies:

// src/DfE.CheckPerformanceData.Infrastructure/DependencyManager.cs:65
services.AddScoped<IStudentResultsClient, StudentResultsBlobClient>();

StudentResultsBlobClient takes IMemoryCache. AddMemoryCache() is registered by AddPersistenceDependencies and by the web host's CoreWebExtensions, and the worker deliberately opts out of the persistence bundle so its manual DbContext registration stays the single source of truth. The worker therefore has no IMemoryCache, and the container is validated on build, so the whole host dies rather than one feature failing.

This is the same shape as #308: a registration added for the web's benefit landing in a bundle the worker also executes.

Why the registration serves nobody

  • AddInfrastructureDependencies has two callers: the worker (RulesEngineWorker/Program.cs:55) and AnalyticsRegistrationTests, which resolves only IAnalyticsService through an unvalidated provider.
  • The worker never resolves IStudentResultsClient — no reference anywhere in that project.
  • Every real consumer (JourneyController, ResultSuggestionsController, DevDataSeedingOrchestrator, SeedStudentResults) is in the web host, which does not call AddInfrastructureDependencies and registers the client itself at Web/Startup/BlobStorageExtensions.cs:54.

BlobStorageExtensionsTests was added under AB#296648 for the mirror image of this failure — the client registered only in Infrastructure, so the web could not boot. The web-side registration was added to fix that; the Infrastructure one was left behind, and it is what now kills the worker.

Impact

Every environment that runs the worker: review, QA, preproduction and production. The queue consumer, the dead-letter retention job, metrics retention, search-analytics retention and content-staging session retention are all in that process and none of them starts.

The Build workflow does not catch it because it compiles and runs tests; it never starts the worker host.

Fix

Remove the registration from AddInfrastructureDependencies. The web keeps its own, so the incorrect-grade enquiry journey is unaffected.

Add a guard so the class of failure — a service registered in a shared bundle whose dependencies only exist in one host — becomes a test failure rather than a crash-loop discovered by running the container.

Remedial work on AB#296648.

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions