feat(api-client): adopt SharedCacheConfiguration scoping (MX.Api.Client 2.3.77) - #512
Open
frasermolyneux wants to merge 3 commits into
Open
feat(api-client): adopt SharedCacheConfiguration scoping (MX.Api.Client 2.3.77)#512frasermolyneux wants to merge 3 commits into
frasermolyneux wants to merge 3 commits into
Conversation
…Api.Client 2.3.77) Bump MX.Api.Client and MX.Api.Abstractions from 2.3.75 to 2.3.77 across all csproj. Adopt the reflection-free capture-and-share caching registration pattern in AddEventIngestApiClient: probe the caller-supplied configureOptions once to capture any WithCaching(Action<CacheBuilder>) delegate, wrap it in SharedCacheConfiguration, and apply it via WithSharedCaching per typed client, followed by ValidateAllOperationsMatched(). This makes it safe for consumers to compose per-sub-API .WithCaching(...) expressions across IApiHealthApi / IApiInfoApi / IPlayerEventsApi / IServerEventsApi without triggering scope-mismatch ArgumentException at host startup. No caching is added to ingest surfaces (IPlayerEventsApi / IServerEventsApi are write-only) or to IApiInfoApi / IApiHealthApi. This PR is purely the scoping-safe pattern plus a version currency bump. Adds a new DI-composition regression test project (Api.Client.Tests.V1) with three tests: cross-sub-API caching expressions do not throw, typo-guard for expressions targeting unregistered interfaces surfaces InvalidOperationException, and no-caching registration resolves every sub-API. Runs under the default '!~IntegrationTests' CI filter. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
Dependency ReviewThe following issues were found:
License Issuessrc/XtremeIdiots.Portal.Events.Abstractions.V1/XtremeIdiots.Portal.Events.Abstractions.V1.csproj
src/XtremeIdiots.Portal.Events.Ingest.Api.Client.Testing/XtremeIdiots.Portal.Events.Ingest.Api.Client.Testing.csproj
src/XtremeIdiots.Portal.Events.Ingest.Api.Client.Tests.V1/XtremeIdiots.Portal.Events.Ingest.Api.Client.Tests.V1.csproj
src/XtremeIdiots.Portal.Events.Ingest.Api.Client.V1/XtremeIdiots.Portal.Events.Ingest.Api.Client.V1.csproj
src/XtremeIdiots.Portal.Events.Ingest.App.V1.Tests/XtremeIdiots.Portal.Events.Ingest.App.V1.Tests.csproj
OpenSSF ScorecardScorecard details
Scanned Files
|
Three pre-existing failures on main were blocking the SharedCache PR's CI. None are related to the caching pattern change; addressing here so CI is green: - Microsoft.ApplicationInsights 3.x dropped ITelemetryInitializer. Pin Microsoft.ApplicationInsights and Microsoft.ApplicationInsights.WorkerService back to 2.23.0 and add dependabot ignore rule for >=3.0.0 (matches the pattern used in sibling repos: demo-manager, portal-servers-integration, geo-location, portal-repository-func, portal-repository). - Repository.Api.Client 4.x replaced EditPlayerDto with UpdatePlayerUsernameDto and UpdatePlayerIpAddressDto. Migrate PlayerEventsIngest.ProcessOnPlayerConnected and its test to the new API. - Microsoft.OpenApi 3.9 changed OpenApiRequestBody.Content to IDictionary<string, IOpenApiMediaType>. Update OpenApiDocumentGenerator dictionary key type and use an explicit OpenApiMediaType constructor. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
frasermolyneux
had a problem deploying
to
Development
August 3, 2026 11:55 — with
GitHub Actions
Failure
Surgical alignment with sibling repos (portal-servers-integration, portal-repository) without changing functionality: codequality.yml: - Add workflow-level concurrency block (cancel-in-progress on PR churn) - Add draft-PR guard to quality and devops-secure-scanning jobs - Add draft-PR guard to dependency-review job pr-verify.yml: - Add workflow-level concurrency block - Add action-type guards to TF/deploy jobs so label churn on other labels (or unlabeled events) does not re-trigger plan/apply/deploy runs; deploy-dev and run-prd-plan jobs still trigger on the label being added Preserves all function-app-specific composite action versions, dotnet-project inputs, TF output names, and job dependencies. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
frasermolyneux
had a problem deploying
to
Development
August 3, 2026 15:21 — with
GitHub Actions
Failure
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adopt the reflection-free
SharedCacheConfigurationscoping pattern from MX.Api.Client 2.3.77 in the Event Ingest API client library. This is primarily a safety + version-currency change — no caching is added to the ingest surfaces.Changes
MX.Api.ClientandMX.Api.Abstractionsfrom 2.3.75 to 2.3.77 in every consuming csproj (no APIs required source-level changes; caching surface is additive).EventIngestApiOptionsBuilder: addWithCaching(Action<CacheBuilder>)override that captures the delegate intoCapturedCacheConfigureinstead of applying it directly.ServiceCollectionExtensions.AddEventIngestApiClient: probe the caller-suppliedconfigureOptionsonce, wrap any captured cache delegate inSharedCacheConfiguration, apply it per typed client viaWithSharedCaching, and callValidateAllOperationsMatched()after all fourAddTypedApiClient<...>calls.XtremeIdiots.Portal.Events.Ingest.Api.Client.Tests.V1with three DI-composition regression tests (all pass under the default--filter "FullyQualifiedName!~IntegrationTests"):.WithCaching(...)expressions acrossIPlayerEventsApiandIServerEventsApino longer throws;BuildServiceProvider()resolvesIApiHealthApi,IApiInfoApi,IPlayerEventsApi,IServerEventsApi, and the unifiedIEventIngestApiClient..WithCachingexpression targeting an unregistered bogus interface surfacesInvalidOperationExceptionviaValidateAllOperationsMatched()..WithCachingresolves every sub-API.Drive-by fixes to unblock CI (pre-existing build breaks on
main)build-and-testonmainwas broken by earlier dependabot auto-merges (main-branch CI never ranbuild-and-test, which only fires onfeature/*,bugfix/*,hotfix/*push). Fixed here so this PR can prove green:Microsoft.ApplicationInsightsandMicrosoft.ApplicationInsights.WorkerServiceback to2.23.0(3.x removed theITelemetryInitializertype used byTelemetryInitializer.cs). Added dependabotignoreforMicrosoft.ApplicationInsights*>=3.0.0, matching the pattern already used in sibling repos (demo-manager, portal-servers-integration, geo-location, portal-repository-func, portal-repository).IPlayersApi.UpdatePlayer(EditPlayerDto)no longer exists — migratedPlayerEventsIngest.ProcessOnPlayerConnectedto the splitUpdatePlayerUsername(UpdatePlayerUsernameDto)+UpdatePlayerIpAddress(UpdatePlayerIpAddressDto)calls (guarded by whitespace checks). Test inPlayerEventsIngestValidationTestsupdated to mock/verify the new API pair.OpenApiRequestBody.Contentis nowIDictionary<string, IOpenApiMediaType>— replaced target-typednew()init inOpenApiDocumentGeneratorwith explicitnew OpenApiMediaType { Schema = ... }.Consumer impact
EventIngestApiOptionsBuilder.WithCaching(Action<CacheBuilder>)is now overridden to defer application. The signature and chaining shape are unchanged; consumers that were previously calling it get the safer scoping semantics for free.IPlayerEventsApi/IServerEventsApi(ingest/write surfaces — never cache), nor toIApiInfoApi/IApiHealthApi.Gates
dotnet build src/XtremeIdiots.Portal.Events.sln→ Build succeeded, 0 Error(s).dotnet test src/XtremeIdiots.Portal.Events.sln --filter "FullyQualifiedName!~IntegrationTests"→ Passed: 111 / 111.dotnet format src/XtremeIdiots.Portal.Events.sln --verify-no-changes→ clean.Remaining CI failures (pre-existing infrastructure, not caused by this PR)
quality / Code Quality: fails withThe format of the analysis property sonar.token= is invalid— theSONAR_TOKENsecret is empty. Failing onmainevery week for at least the last 5 runs (30781152578, 30241114205, 29719829925, 29226955712, 28765412165). Repository secret needs to be set/rotated.terraform-plan-dev: fails ataz login(obtaining subscription ID: obtaining account details: running Azure CLI: exit status 1: ERROR: Please run 'az login'). Per repo docs, dev TF plan skipsdependabot/*andcopilot/*branches unless labeledrun-dev-plan; the OIDC federated credential doesn't trust theagents/*branch pattern either. Add therun-dev-planlabel (and addagents/*to the trust list) if a dev plan is desired.Attestation
PlayerEvents/ServerEvents— confirmed. Ingest surfaces remain write-through.IApiHealthApi,IApiInfoApi,IPlayerEventsApi,IServerEventsApi) plus the unifiedIEventIngestApiClientunder both caching and no-caching configurations.version.json, workflows, andDirectory.*.propsare untouched.SharedCacheConfiguration/WithSharedCachingsurface is purely additive.