Refine dynamic endpoint allocation#17879
Conversation
Make proxyless container endpoint allocation dependency-aware so safe references can remain lazy while circular or unknown references still allocate early. Preserve explicit proxy settings when randomizing ports and publish connection string availability for dynamic allocation paths. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 17879Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 17879" |
Clear the connection-string availability de-dupe state when a resource is recreated for restart so the event can publish again after callbacks are re-evaluated. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
PR Testing ReportPR Information
CLI Version Verification
Changes AnalyzedFiles Changed
Change Categories
Test Scenarios ExecutedScenario 1: Independent proxyless container endpoint stays lazyObjective: Verify a caller-aware reference from an independent executable to a proxyless container endpoint waits for DCP allocation instead of falling back to the endpoint target port. Steps:
Evidence:
Observations:
Scenario 2: Circular/dependent proxyless container endpoint resolves earlyObjective: Verify a circular endpoint reference still resolves early to target-port fallback and does not block startup. Steps:
Evidence:
Observations:
Scenario 3: Randomized ports preserve explicit proxy settingsObjective: Verify isolated/randomized-port runs proxy implicit persistent endpoints by default while preserving explicit proxyless configuration. Steps:
Evidence:
Observations:
Scenario 4: Resource restart after connection-string event reset pathObjective: Verify restart/recreate still succeeds and re-evaluates endpoint values after the new connection-string availability de-dupe reset is wired into the restart path. Steps:
Evidence:
Observations:
Summary
Overall ResultPR VERIFIED Artifacts
Recommendations
|
There was a problem hiding this comment.
Pull request overview
Refines Aspire hosting’s dynamic endpoint allocation for proxyless container endpoints, aiming to avoid early fallback allocation unless endpoint resolution cannot safely wait (e.g., circular/unknown/self references), and ensuring endpoint/connection-string availability events are published consistently (including across restarts).
Changes:
- Updates endpoint reference resolution to decide when to allocate an endpoint on-demand based on the resolving caller and discovered resource dependencies.
- Adjusts DCP execution flow to pre-allocate certain dynamic proxyless container endpoints earlier and to dedupe/publish
OnConnectionStringAvailableevents (resetting dedupe on restart). - Changes default proxying behavior for persistent endpoints when
RandomizePorts=true, while preserving explicit proxy settings; adds/extends tests for these scenarios.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/Aspire.Hosting.Tests/EndpointReferenceTests.cs | Adds unit tests covering on-demand allocation vs waiting behavior based on caller/dependency context. |
| tests/Aspire.Hosting.Tests/Dcp/DcpExecutorTests.cs | Adds coverage for randomized-port proxy defaults and connection-string-available event publication (including restart scenarios). |
| src/Aspire.Hosting/Dcp/DcpModelUtilities.cs | Adds helper to pre-allocate dependent dynamic proxyless container endpoints prior to container submission. |
| src/Aspire.Hosting/Dcp/DcpExecutor.cs | Wires new endpoint allocation publication path, adds connection-string event dedupe/reset logic, and adjusts proxy defaulting under randomized ports. |
| src/Aspire.Hosting/ApplicationModel/EndpointReference.cs | Adds caller/dependency-aware gating for on-demand endpoint allocation before falling back to waiting for allocation. |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Default persistent container reuse tests to normal port behavior while allowing individual tests to opt into randomized ports. Add Redis and RabbitMQ coverage for reuse with randomized ports. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
/backport to release/13.4 |
|
Started backporting to |
|
@danegsta backporting to git am output$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patch
Applying: Refine dynamic endpoint allocation
Applying: Reset connection string events on restart
Applying: Use direct dependency scan for DCP preallocation
Applying: Document endpoint allocation wait
Applying: Update persistent container port randomization tests
Using index info to reconstruct a base tree...
M tests/Aspire.Hosting.RabbitMQ.Tests/RabbitMQFunctionalTests.cs
M tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs
A tests/Aspire.Hosting.Tests/Utils/PersistentContainerTestHelpers.cs
Falling back to patching base and 3-way merge...
Auto-merging tests/Aspire.Hosting.RabbitMQ.Tests/RabbitMQFunctionalTests.cs
CONFLICT (content): Merge conflict in tests/Aspire.Hosting.RabbitMQ.Tests/RabbitMQFunctionalTests.cs
Auto-merging tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs
CONFLICT (content): Merge conflict in tests/Aspire.Hosting.Redis.Tests/RedisFunctionalTests.cs
CONFLICT (modify/delete): tests/Aspire.Hosting.Tests/Utils/PersistentContainerTestHelpers.cs deleted in HEAD and modified in Update persistent container port randomization tests. Version Update persistent container port randomization tests of tests/Aspire.Hosting.Tests/Utils/PersistentContainerTestHelpers.cs left in tree.
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Patch failed at 0005 Update persistent container port randomization tests
Error: The process '/usr/bin/git' failed with exit code 128 |
|
❌ CLI E2E Tests failed — 111 passed, 2 failed, 2 unknown (commit ❌ Failed Tests
View all recordings
📹 Recordings uploaded automatically from CI run #26914128242 |
|
/backport to release/13.4 |
|
Started backporting to |
…ilename globs match nested paths Three automated PRs in the last 14d fired more tests than they needed to: #17672, #17263 [Automated] Update ATS API Surface Area #17534 Move repository skills to .agents They each touched only api/*.txt or only README/skill markdown, but were firing trigger_all or selective:integrations — burning the full ~25min CI critical path. Audit-replay over 161 merged PRs found them, plus a latent C# glob bug where bare-filename patterns silently ignored nested matches. Root causes — two independent bugs: 1. The category-trigger rescue logic in RescueCategoryTriggerFiles built a synthetic union of all category triggerPaths without consulting per-category excludePaths. An ignored file that textually matched some category's glob but was excluded from that category got rescued back to active and then hit fallback_unmatched (worse than staying ignored). For src/Aspire.Hosting.Foundry/api/*.txt this meant ATS-only PRs fired integrations even after `**/api/*.txt` was added to ignorePaths. 2. The four glob analyzers (CriticalFileDetector, IgnorePathFilter, CategoryMapper.CompiledCategory, ProjectMappingResolver.CompiledMapping) handed user-facing patterns directly to FileSystemGlobbing.Matcher. The Matcher anchors bare-filename patterns at the repo root, so `Directory.Build.props` matched only the root file, not `src/Directory.Build.props` or `tests/Directory.Build.props`. The Python audit-replay evaluator (eval_rules.py) already documented and applied a "prepend **/ to bare-filename patterns" rule; the C# analyzers did not, so the two evaluators silently disagreed on ~5 patterns across ignorePaths, triggerAllPaths, and sourceToTestMappings. The fix: - Rescue now passes config.Categories directly to CategoryMapper so CompiledCategory.Matches honors per-category excludes. A file is rescued only when at least one category would actually fire on it. - New PatternNormalization.NormalizeGlob prepends `**/` to any pattern without a path separator. Every glob entry point applies it: the four analyzers above plus ProjectMappingResolver's regex compiler. - Rules: integrations.excludePaths gains `tests/Aspire.Acquisition.Tests/**`, `tests/Infrastructure.Tests/**`, `**/*.md`, `**/api/*.txt`. The same `**/api/*.txt` exclude is added to every category so an ignored ATS file can't be rescued back by any category. ignorePaths gains `**/api/*.txt`. Acquisition mapping's source list gains the missing self-mapping `tests/Aspire.Acquisition.Tests/**` (Templates and Infrastructure mappings already had this; Acquisition was an oversight exposed only after the new exclude was added). Verification: - Audit replay over 161 merged PRs: 4 outcomes change (#17263, #17534, #17549, #17672 all move to `skip`); zero regressions; zero fallback_unmatched. - New AuditFixtureTests xUnit [Theory] replays 28 hand-validated PRs against the live audit rules. Each row is a separate test, so any future rule edit that changes a row's outcome shows up as a visible CI failure. Coverage includes templates (#16447), CLI native build (#17567), extension multi-category (#17881/17698/17772), Hosting-core trigger_all (#17879), polyglot (#17948), and the regression canaries for previous fallback_unmatched cases. - Per-component regression tests pin both bugs: two new tests in EndToEndEvaluationTests for rescue+excludes; two more for bare-filename matching at nested paths. - Three pre-existing analyzer tests had asserted the buggy bare-filename behavior as expected (e.g. `*.md` not matching `docs/guide.md`). Updated with comments explaining the user-intent rule. - Full TestSelector namespace: 290 tests, all pass. No collateral damage on the wider Infrastructure.Tests suite (5 pre-existing baseline failures unchanged). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Refine dynamic endpoint allocation Make proxyless container endpoint allocation dependency-aware so safe references can remain lazy while circular or unknown references still allocate early. Preserve explicit proxy settings when randomizing ports and publish connection string availability for dynamic allocation paths. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Reset connection string events on restart Clear the connection-string availability de-dupe state when a resource is recreated for restart so the event can publish again after callbacks are re-evaluated. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Use direct dependency scan for DCP preallocation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Document endpoint allocation wait Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update persistent container port randomization tests Default persistent container reuse tests to normal port behavior while allowing individual tests to opt into randomized ports. Add Redis and RabbitMQ coverage for reuse with randomized ports. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Description
This PR refines dynamic endpoint allocation for proxyless container endpoints so Aspire only falls back to early allocation when waiting would be unsafe. Endpoint resolution now uses the value provider caller and recursive resource dependency discovery to distinguish circular or unknown references from independent references that can remain lazily allocated.
The DCP path now:
RandomizePortsas an implicit default for proxying persistent endpoints without overriding explicit proxy settingsConnectionStringAvailableEventfor both eager fallback allocation and post-container dynamic allocation, and resets that event de-dupe state when a resource is recreated for restartUser-facing behavior
AppHost endpoint references that are safe to resolve later avoid unnecessary early fallback allocation. Circular, self, and unknown-caller references still resolve during startup when they need to. In isolated/randomized-port runs, persistent endpoints default to proxied behavior unless the app explicitly configured the endpoint as proxyless.
Validation
dotnet test --project tests/Aspire.Hosting.Tests/Aspire.Hosting.Tests.csproj --no-build --no-launch-profile -- --filter-class "*.DcpExecutorTests" --filter-not-trait "quarantined=true" --filter-not-trait "outerloop=true"dotnet test --project tests/Aspire.Hosting.Tests/Aspire.Hosting.Tests.csproj --no-launch-profile -- --filter-method "*.ResourceRestarted_EnvironmentCallbacksApplied" --filter-method "*.EndpointPortsContainerProxylessNoPortTargetPortSetPublishesAllocatedEndpointAfterServiceUpdate" --filter-method "*.EndpointPortsContainerProxylessNoPortTargetPortSetUsesTargetPortFallbackWhenResolvedBeforeContainerCreation" --filter-not-trait "quarantined=true" --filter-not-trait "outerloop=true"EndpointReferenceTestsgit diff --checkFixes: N/A
Checklist
<remarks />and<code />elements on your triple slash comments?