Skip to content

Fix telemetry streaming to wait for resource to appear#17821

Merged
JamesNK merged 4 commits into
mainfrom
fix/telemetry-stream-wait-for-resource
Jun 2, 2026
Merged

Fix telemetry streaming to wait for resource to appear#17821
JamesNK merged 4 commits into
mainfrom
fix/telemetry-stream-wait-for-resource

Conversation

@JamesNK
Copy link
Copy Markdown
Member

@JamesNK JamesNK commented Jun 2, 2026

Summary

Fixes #17802

When streaming spans/logs with a resource filter via follow=true, if the resource hasn't sent any telemetry yet, the stream would immediately return empty (HTTP 200 with closed NDJSON stream). This is a problem because the dashboard starts streaming before the resource has had a chance to emit telemetry.

Changes

src/Aspire.Dashboard/Api/TelemetryApiService.cs

  • Added WaitForResourceKeysAsync method that subscribes to OnNewResources notifications and waits for the requested resource(s) to appear before starting the span/log watcher
  • Uses a bounded channel (capacity 1, DropOldest) as the signaling mechanism to avoid race conditions between notifications and state checks
  • Both FollowSpansAsync and FollowLogsAsync now call this instead of immediately yielding break on unknown resources

tests/Aspire.Dashboard.Tests/TelemetryApiServiceTests.cs

  • Added FollowSpansAsync_WaitsForResourceToAppear_ThenStreams - verifies that streaming waits for a resource and yields data once it appears
  • Added FollowLogsAsync_WaitsForResourceToAppear_ThenStreams - same for logs

Design

The subscribe-before-check pattern ensures no notification is lost:

  1. Subscribe to OnNewResources channel signal first
  2. Check if resources are already available (fast path)
  3. If not, loop: await channel read → re-check state → return or continue waiting
  4. OperationCanceledException propagates naturally when the client disconnects

The bounded channel with DropOldest collapses multiple rapid resource notifications into a single "wake up and re-check" signal, which is simpler and more robust than a TCS-reset approach.

When streaming spans/logs with a resource filter via follow=true, if the
resource hasn't sent any telemetry yet, the stream would immediately return
empty. This fixes the issue by waiting for the resource to appear via the
OnNewResources subscription before starting the watcher.

Uses a bounded channel (capacity 1, DropOldest) as the signaling mechanism
to avoid race conditions between notifications and state checks.

Fixes #17802
@JamesNK JamesNK requested a review from adamint as a code owner June 2, 2026 04:01
Copilot AI review requested due to automatic review settings June 2, 2026 04:01
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 2, 2026

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 17821

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 17821"

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes telemetry streaming behavior in the Aspire Dashboard so that follow=true span/log streams don’t immediately end when a resource filter is specified but the resource hasn’t emitted telemetry yet. Instead, the service now waits for the resource(s) to appear and then begins streaming.

Changes:

  • Updated FollowSpansAsync and FollowLogsAsync to wait for resource discovery via a new WaitForResourceKeysAsync helper rather than returning an empty, closed stream.
  • Added WaitForResourceKeysAsync which subscribes to resource-add notifications and blocks (cancellable) until the requested resource key(s) can be resolved.
  • Added new unit tests validating that streaming started before telemetry arrival will later yield data once the resource appears.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/Aspire.Dashboard/Api/TelemetryApiService.cs Adds a resource-wait mechanism before starting span/log watchers, preventing premature stream termination for filtered follow streams.
tests/Aspire.Dashboard.Tests/TelemetryApiServiceTests.cs Adds tests covering “subscribe before emission” scenarios for both spans and logs.

Comment thread src/Aspire.Dashboard/Api/TelemetryApiService.cs Outdated
Comment thread tests/Aspire.Dashboard.Tests/TelemetryApiServiceTests.cs Outdated
Comment thread tests/Aspire.Dashboard.Tests/TelemetryApiServiceTests.cs Outdated
Copy link
Copy Markdown
Member

@adamint adamint left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reviewed with gpt-5.5 and opus 4.8/4.7/4.6. I don't see anything high severity here, so approving.

One non-blocking issue I think is worth looking at: WaitForResourceKeysAsync waits on OnNewResources, but TelemetryRepository.GetResources() excludes uninstrumented peers. If a resource already exists only as an uninstrumented peer, later telemetry upgrades it via SetUninstrumentedPeer(false) without raising OnNewResources because the resource wasn't newly added. A follow stream for that resource can stay stuck until some unrelated resource is added. Maybe the wait path should include uninstrumented peers when resolving names, or promotion should raise the resource subscription.

I also saw the fixed-delay test comments that the bot already left. I don't think those block this PR.

@adamint
Copy link
Copy Markdown
Member

adamint commented Jun 2, 2026

Tested this locally:

  • dogfood CLI installed and matched the PR build: 13.5.0-pr.17821.g5c5f36d1
  • dotnet test --project tests/Aspire.Dashboard.Tests/Aspire.Dashboard.Tests.csproj --no-launch-profile -- --filter-class "*.TelemetryApiServiceTests" --filter-not-trait "quarantined=true" --filter-not-trait "outerloop=true" passed: 32/32
  • aspire new aspire-starter using the PR hive completed successfully

I tried to do the dashboard Playwright smoke check too, but couldn't get a dashboard app running for a reason that looks unrelated to this PR: the generated starter app fails to compile with Pr17821Smoke.Web.Components namespace errors, and TestingAppHost1 failed under the dogfood CLI before exposing a dashboard. So the code/test validation passed, but the browser smoke was blocked by app startup/template issues rather than this change.

@davidfowl
Copy link
Copy Markdown
Contributor

Is there a PR testing report?

@mitchdenny
Copy link
Copy Markdown
Member

PR Testing Report

PR Information

CLI Version Verification

  • Expected Commit: 5c5f36d...
  • Installed Version: 13.5.0-pr.17821.g5c5f36d1
  • Status: ✅ Verified — short SHA matches

Changes Analyzed

Files Changed

  • src/Aspire.Dashboard/Api/TelemetryApiService.cs — adds WaitForResourceKeysAsync; FollowSpansAsync/FollowLogsAsync now wait for resources instead of yield-breaking
  • tests/Aspire.Dashboard.Tests/TelemetryApiServiceTests.cs — two new unit tests covering the wait-then-stream behavior

Change Categories

  • CLI changes
  • Hosting integration changes
  • Dashboard changes — telemetry follow API behavior
  • Template changes
  • Client/Component changes
  • Test changes

Test Setup

  • Template: aspire-starter (csharp)
  • AppHost run directly via dotnet run against PrSmoke.AppHost (after aspire start hit a flaky parallel-build issue — unrelated to this PR, see Observations)
  • Dashboard pinned to http://localhost:18888 with DOTNET_DASHBOARD_UNSECURED_ALLOW_ANONYMOUS=true so the /api/telemetry/* endpoints accept anonymous requests for the test
  • Scenarios driven by curl against the live NDJSON streaming endpoints

Test Scenarios Executed

Scenario 1: Follow logs for an already-running resource (regression check)

Objective: Verify the fix didn't break the existing case where the resource is already known.
Coverage: Happy path
Status: ✅ Passed

GET /api/telemetry/logs?resource=apiservice&follow=true (held open for 6s).

  • HTTP 200
  • Stream stayed open the full 6s (curl exit 28 = timeout reached)
  • 4 NDJSON entries received with real log content (e.g. Now listening on: http://localhost:54279 from Microsoft.Hosting.Lifetime)
  • Total bytes: 3099

Scenario 2: Follow logs before the resource emits telemetry (the bug being fixed)

Objective: Validate the PR's central intent — that a stream opened before a resource has emitted any telemetry waits and then delivers data once the resource appears.
Coverage: Happy path (the fix)
Status: ⚠️ Covered by unit tests in the PR, not by live E2E

Direct E2E reproduction would require either restarting the AppHost while a stream is open or adding a resource to the running model — neither is straightforward without invasive rigging. The PR includes targeted unit tests for this exact path:

  • FollowSpansAsync_WaitsForResourceToAppear_ThenStreams
  • FollowLogsAsync_WaitsForResourceToAppear_ThenStreams

These exercise the WaitForResourceKeysAsyncOnNewResources → re-resolve loop directly.

Scenario 3: Follow logs for a resource that never appears (key behavior change)

Objective: Validate the most important new behavior introduced by the PR — that an unresolvable resource name no longer terminates the stream immediately.
Coverage: Unhappy path
Status: ✅ Passed (with a noteworthy nuance — see below)

GET /api/telemetry/logs?resource=does-not-exist&follow=true (held open for 6s).

  • Curl exit 28 (timeout) — connection stayed open for the full 6s
  • http=000 — i.e. response headers were never flushed
  • 0 bytes downloaded
  • Server still alive after disconnect (verified with a follow-up /api/telemetry/resources returning 200)

Pre-fix behavior would have returned HTTP 200 with an immediately-closed empty NDJSON body. The fix achieves "stream stays open" as designed.

Important nuance for consumers: Because StreamNdjsonAsync only writes/flushes response headers when the first NDJSON line is enumerated, a follow stream for a never-appearing resource now produces no HTTP response at all (no status, no headers, no body) until either the resource appears or the client disconnects. This is a sharper version of the behavior change flagged in the code review:

  • Pre-fix: 200 OK immediately, body closed
  • Post-fix: connection open with no response sent at all, indefinitely

Consumers (the AI assistant / MCP-style tools) that wait on response headers as a readiness signal will hang. Most HTTP clients will treat this as a request timeout rather than a successful empty stream.

Scenario 4: Partial resolution — one resource exists, one doesn't (semantics preserved)

Objective: Confirm the all-or-nothing semantics of ResolveResourceKeys are intact: when the caller passes multiple names and any are missing, the stream must wait for all of them, not opportunistically stream data from the resolved subset.
Coverage: Unhappy / boundary path
Status: ✅ Passed

GET /api/telemetry/logs?resource=apiservice&resource=does-not-exist&follow=true (held open for 6s).

  • http=000, 0 bytes, full 6s elapsed
  • Confirms apiservice's already-flowing logs were not streamed because does-not-exist blocks resolution

Scenario 5: Spans endpoint symmetric check

Objective: Confirm both FollowSpansAsync and FollowLogsAsync got the fix (the PR changes both, but verifying both endpoints at runtime is cheap).
Coverage: Happy/sanity
Status: ✅ Passed

GET /api/telemetry/spans?resource=does-not-exist&follow=true (4s) → same http=000/0-byte/connection-open signature as scenario 3.

Summary

Scenario Status Notes
1. Follow logs (existing resource) ✅ Passed 4 NDJSON entries in 6s, no regression
2. Stream then resource appears ⚠️ Unit-tested only PR ships dedicated tests; live E2E impractical without intrusive setup
3. Resource never appears ✅ Passed Stream stayed open; behavior change confirmed
4. Partial resolution (any-missing → wait) ✅ Passed All-or-nothing semantics preserved
5. Spans endpoint symmetric ✅ Passed Same fix wired on spans path

Overall Result

✅ PR verified — fix behaves as advertised, with one notable refinement worth flagging:

Recommendations / things to consider

  1. Response-not-sent-until-data is a real consumer concern. For a follow stream against a typo'd / never-appearing resource the dashboard now sends no HTTP response at all (not even 200 + empty body). Any client that uses response headers as a "stream opened" signal will appear to hang. Two options worth considering:
    • Flush the NDJSON headers (200, Content-Type: application/x-ndjson, etc.) eagerly in StreamNdjsonAsync before awaiting the first item, so clients always see the response open.
    • Or, in WaitForResourceKeysAsync, apply a bounded wait (configurable) and fall back to yield break on timeout to preserve fast-fail for clearly wrong names.
  2. Consider adding an E2E test that hits the live HTTP endpoint (not just the service method) to lock in both the streaming behavior and the response-header-timing contract.
  3. Pre-existing flakiness not caused by this PR: aspire start against the freshly-scaffolded aspire-starter template intermittently failed with CS0234 'PrSmoke.Web.Components' does not exist and CS0006 metadata-file errors during its parallel build. The same projects build cleanly with dotnet build from the solution root. Likely a build-ordering race in aspire start's build orchestration. Worth filing as a separate issue if not already tracked.

@JamesNK JamesNK force-pushed the fix/telemetry-stream-wait-for-resource branch 2 times, most recently from 3142278 to 7af8f60 Compare June 2, 2026 06:30
@JamesNK JamesNK force-pushed the fix/telemetry-stream-wait-for-resource branch from 7af8f60 to 7e40583 Compare June 2, 2026 07:00
…ogsRequest to use ResourceKeys

Change ResourceKey? ResourceKey property to IReadOnlyList<ResourceKey> ResourceKeys
on all telemetry request types for consistency with GetLogsContext.

This pushes multi-resource filtering into the repository layer, eliminating
per-resource loops and client-side filtering in TelemetryApiService.
@JamesNK JamesNK force-pushed the fix/telemetry-stream-wait-for-resource branch 3 times, most recently from f096320 to 331ea74 Compare June 2, 2026 07:43
@JamesNK JamesNK force-pushed the fix/telemetry-stream-wait-for-resource branch from 331ea74 to 70d1d5e Compare June 2, 2026 07:46
@JamesNK JamesNK enabled auto-merge (squash) June 2, 2026 07:56
@JamesNK JamesNK merged commit 1ba5899 into main Jun 2, 2026
618 of 621 checks passed
@JamesNK JamesNK deleted the fix/telemetry-stream-wait-for-resource branch June 2, 2026 08:28
@github-actions github-actions Bot added this to the 13.5 milestone Jun 2, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 2, 2026

CLI E2E Tests unknown — 110 passed, 0 failed, 2 unknown (commit 70d1d5e)

View all recordings
Status Test Recording Job Artifacts
AddPackageInteractiveWhileAppHostRunningDetached Recording #79029282486 Logs
AddPackageWhileAppHostRunningDetached Recording #79029282486 Logs
AgentCommands_AllHelpOutputs_AreCorrect Recording #79029281627 Logs
AgentInitCommand_DefaultSelection_InstallsDefaultSkills Recording #79029281627 Logs
AgentInitCommand_MigratesDeprecatedConfig Recording #79029281627 Logs
AgentInitCommand_NonInteractive_BundleOnlySkillsBeyondCliCatalog_AreInstallable Recording #79029281627 Logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp Recording #79029281552 Logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp_DevLocalhost Recording #79029281552 Logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp_Isolated Recording #79029281552 Logs
AllPublishMethodsBuildDockerImages Recording #79029282175 Logs
AspireAddAndStartWorkAgainstLegacyAppHostTs Recording #79029280868 Logs
AspireAddPackageVersionToDirectoryPackagesProps Recording #79029282213 Logs
AspireInitSingleFileAppHostRunsViaDotnetRunAppHost Recording #79029281655 Logs
AspireInitWithExistingAppHostDirRecreatesMissingNuGetConfigAndPreservesFiles Recording #79029281906 Logs
AspireInitWithSolutionFileGeneratesAppHostThatBuildsAgainstChannelHive Recording #79029281906 Logs
AspireStartUpdatesStaleTypeScriptAppHostPath Recording #79029281183 Logs
AspireUpdateRemovesAppHostPackageVersionFromDirectoryPackagesProps Recording #79029282213 Logs
AspireUpdateRemovesOrphanAppHostPackageVersionWhenSdkAlreadyCurrent Recording #79029282213 Logs
Banner_DisplayedOnFirstRun Recording #79029281670 Logs
Banner_DisplayedWithExplicitFlag Recording #79029281670 Logs
Banner_NotDisplayedWithNoLogoFlag Recording #79029281670 Logs
CertificatesClean_RemovesCertificates Recording #79029281989 Logs
CertificatesTrust_WithNoCert_CreatesAndTrustsCertificate Recording #79029281989 Logs
CertificatesTrust_WithUntrustedCert_TrustsCertificate Recording #79029281989 Logs
ConfigSetGet_CreatesNestedJsonFormat Recording #79029282305 Logs
CreateAndRunAspireStarterProject Recording #79029281952 Logs
CreateAndRunAspireStarterProjectWithBundle Recording #79029281779 Logs
CreateAndRunEmptyAppHostProject Recording #79029281168 Logs
CreateAndRunJavaEmptyAppHostProject Recording #79029281105 Logs
CreateAndRunJsReactProject Recording #79029281831 Logs
CreateAndRunPolyglotAppHostWithDevLocalhostUrls Recording #79029281952 Logs
CreateAndRunPythonReactProject Recording #79029281592 Logs
CreateAndRunTypeScriptEmptyAppHostProject Recording #79029282018 Logs
CreateAndRunTypeScriptStarterProject Recording #79029281248 Logs
CreateJavaAppHostWithViteApp Recording #79029281199 Logs
CreateTypeScriptAppHostWithViteApp_AllowsGuestAppPackageManagerToDiffer Recording #79029281086 Logs
CreateTypeScriptAppHostWithViteApp_UsesConfiguredToolchain Recording #79029281086 Logs
DashboardRunWithAgentMcpListTracesReturnsNoTraces Recording #79029281623 Logs
DashboardRunWithAgentMcpListTracesReturnsNoTraces_DevLocalhost Recording #79029281623 Logs
DashboardRunWithOtelTracesReturnsNoTraces Recording #79029281623 Logs
DashboardRunWithOtelTracesReturnsNoTraces_DevLocalhost Recording #79029281623 Logs
DeployK8sBasicApiService Recording #79029281795 Logs
DeployK8sWithExternalHelmChart Recording #79029282248 Logs
DeployK8sWithGarnet Recording #79029281770 Logs
DeployK8sWithMongoDB Recording #79029281218 Logs
DeployK8sWithMySql Recording #79029282268 Logs
DeployK8sWithPostgres Recording #79029281310 Logs
DeployK8sWithRabbitMQ Recording #79029281750 Logs
DeployK8sWithRedis Recording #79029281246 Logs
DeployK8sWithSqlServer Recording #79029281780 Logs
DeployK8sWithValkey Recording #79029281468 Logs
DeployTypeScriptAppToKubernetes Recording #79029281713 Logs
DescribeCommandResolvesReplicaNames Recording #79029282166 Logs
DescribeCommandShowsRunningResources Recording #79029282166 Logs
DetachFormatJsonProducesValidJson Recording #79029281448 Logs
DetachFormatJsonProducesValidJsonWhenRestartingExistingInstance Recording #79029281448 Logs
DoPublishAndDeployListStepsWork Recording #79029282269 Logs
DocsCommand_RendersInteractiveMarkdownFromLocalSource Recording #79029281570 Logs
DoctorCommand_DetectsDeprecatedAgentConfig Recording #79029281627 Logs
DoctorCommand_TypeScriptAppHostReportsMissingConfiguredToolchain Recording #79029281075 Logs
DoctorCommand_WithSslCertDir_ShowsTrusted Recording #79029281075 Logs
DoctorCommand_WithoutSslCertDir_ShowsPartiallyTrusted Recording #79029281075 Logs
GatewayWithoutExternalEndpoint_FailsPublishWithGuidance Recording #79029281760 Logs
GeneratedAspireDevScript_StartsWatchMode_WithConfiguredToolchain Recording #79029281086 Logs
GlobalMigration_HandlesCommentsAndTrailingCommas Recording #79029282305 Logs
GlobalMigration_HandlesMalformedLegacyJson Recording #79029282305 Logs
GlobalMigration_PreservesAllValueTypes Recording #79029282305 Logs
GlobalMigration_SkipsWhenNewConfigExists Recording #79029282305 Logs
GlobalSettings_MigratedFromLegacyFormat Recording #79029282305 Logs
IngressWithoutExternalEndpoint_FailsPublishWithGuidance Recording #79029281760 Logs
InitTypeScriptAppHost_AugmentsExistingViteRepoInWorkspaceSubdirectory Recording #79029281086 Logs
InteractiveCSharpInitCreatesExpectedFiles Recording #79029281674 Logs
InvalidAppHostPathWithComments_IsHealedOnRun Recording #79029281175 Logs
JavaScriptHostingApisRunFromTypeScriptAppHost Recording #79029282175 Logs
LatestCliCanStartStableChannelAppHost Recording #79029281952 Logs
LatestCliCanStartStableChannelTypeScriptAppHost Recording #79029281952 Logs
LegacySettingsMigration_AdjustsRelativeAppHostPath Recording #79029281183 Logs
LogsCommandShowsResourceLogs Recording #79029281217 Logs
OtelLogsReturnsStructuredLogsFromStarterApp Recording #79029281950 Logs
OtelLogsReturnsStructuredLogsFromStarterAppIsolated Recording #79029281950 Logs
PsCommandListsRunningAppHost Recording #79029281696 Logs
PsFormatJsonOutputsOnlyJsonToStdout Recording #79029281696 Logs
PublishJavaScriptPatternsGeneratesExpectedDockerComposeArtifacts Recording #79029281774 Logs
PublishWithConfigureEnvFileUpdatesEnvOutput Recording #79029281774 Logs
PublishWithDockerComposeServiceCallbackSucceeds Recording #79029281774 Logs
PublishWithoutOutputPathUsesAppHostDirectoryDefault Recording #79029281774 Logs
ResourceCommand_FailedExecution_DisplaysAppHostLogPathAndLogContainsEntries Recording #79029281679 Logs
ResourceCommand_SetAndDeleteParameterUpdatesDescribeOutput Recording #79029281679 Logs
RestoreGeneratesSdkFiles Recording #79029282321 Logs
RestoreGeneratesSdkFiles_WithConfiguredToolchain Recording #79029282260 Logs
RestoreRefreshesGeneratedSdkAfterAddingIntegration Recording #79029282260 Logs
RestoreSupportsConfigOnlyHelperPackageAndCrossPackageTypes Recording #79029282286 Logs
RunFromParentDirectory_UsesExistingConfigNearAppHost Recording #79029282112 Logs
RunReportsSyntaxErrorsForDotNetAppHost Recording #79029281231 Logs
RunReportsSyntaxErrorsForTypeScriptAppHost Recording #79029281231 Logs
SecretCrudOnDotNetAppHost Recording #79029281162 Logs
SecretCrudOnTypeScriptAppHost Recording #79029281173 Logs
StagingChannel_ConfigureAndVerifySettings_ThenSwitchChannels Recording #79029281541 Logs
StartAndWaitForTypeScriptSqlServerAppHostWithNativeAssets Recording #79029281084 Logs
StartReportsSyntaxErrorsForDotNetAppHost Recording #79029281231 Logs
StartReportsSyntaxErrorsForTypeScriptAppHost Recording #79029281231 Logs
StopAllAppHostsFromAppHostDirectory Recording #79029282110 Logs
StopJavaPolyglotAppHostUsingApphostDirectory Recording #79029281056 Logs
StopNonInteractiveSingleAppHost Recording #79029282110 Logs
StopTypeScriptPolyglotAppHostUsingApphostDirectory Recording #79029282084 Logs
StopWithNoRunningAppHostExitsSuccessfully Recording #79029282486 Logs
TypeScriptAppHostRunDoesNotDeadlockWhenLazyOptionsInvokeAsyncCallback Recording #79029282018 Logs
UnAwaitedChainsCompileWithAutoResolvePromises Recording #79029282260 Logs
UpdateProjectChannelToStable_CSharpEmptyAppHost_PreservesAspireConfigChannel Recording #79029281711 Logs
UpdateProjectChannelToStable_CSharpSingleFileInit_PreservesAspireConfigChannel Recording #79029281711 Logs
UpdateProjectChannelToStable_TypeScriptSingleFileInit_PreservesAspireConfigChannel Recording #79029281711 Logs
UpdateProjectChannelToStable_TypeScript_PreviewsStablePackagesAndPreservesChannel Recording #79029281711 Logs

📹 Recordings uploaded automatically from CI run #26805992660

aspire-repo-bot Bot added a commit to microsoft/aspire.dev that referenced this pull request Jun 2, 2026
Document that when using ?follow=true with a resource filter, the
stream waits for the named resource(s) to appear in the dashboard
before streaming data. This matches the behavior fixed in
microsoft/aspire#17821.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@aspire-repo-bot
Copy link
Copy Markdown
Contributor

Pull request created: #1182

Generated by PR Documentation Check

@aspire-repo-bot
Copy link
Copy Markdown
Contributor

📝 Documentation has been drafted in microsoft/aspire.dev#1182 targeting release/13.4.

Updated src/frontend/src/content/docs/dashboard/apis.mdx to document that ?follow=true with a resource filter waits for the named resource(s) to appear before streaming data — the behavior fixed in this PR. The triggered signal was dashboard_api_endpoint_changed (evidence: src/Aspire.Dashboard/Api/TelemetryApiService.cs changed, adding WaitForResourceKeysAsync).

Note

This draft PR needs human review before merging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Streaming Http Telemetry API doesn't work if you start streaming before telemetry arrives.

5 participants