Skip to content

fix(ios): join write requests and screen loads to the traces they belong to - #561

Merged
Makisuo merged 1 commit into
mainfrom
fix/ios-trace-parenting
Aug 21, 2026
Merged

fix(ios): join write requests and screen loads to the traces they belong to#561
Makisuo merged 1 commit into
mainfrom
fix/ios-trace-parenting

Conversation

@Makisuo

@Makisuo Makisuo commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

push.sync rendered as a single childless root span — no HTTP child, no maple-api server span. Two separate causes, both fixed here.

Writes were never traced

The Swift SDK's URLProtocol interceptor declined any request with an httpBodyStream, on the theory that it only skipped streamed uploads. Foundation hands a URLProtocol every body as a stream — httpBody, from: Data, fromFile: and a delegate-fed stream alike — so it skipped every POST, PUT and PATCH the app makes: no client span, and no traceparent, which left the API's server span in a trace of its own.

Three days of production traffic, org-scoped:

Span Count Roots
GET (Client) 893 331
POST (Client) 0
push.sync 19 19, all childless

Fixed in maple-swift 0.3.3 (the relay now carries the body across, preserving the app's framing); this bumps the pin.

ui.screen was never a parent

trackScreen returns the span but nothing carries it, and the SDK is right not to make it ambient — a span that runs for the whole visit is not a scope anything can nest inside. So all 347 ui.screen spans arrived as childless roots while the load each one caused sat in its own trace.

Telemetry.Visit registers the open span by screen name and screenLoad hangs under it — the same shape PushOpen already uses to parent a load to the notification tap that asked for it. A tapped notification still wins when there is one, and a span the SDK closed on backgrounding is skipped rather than adopted as a parent that ended before its child began.

Verification

  • 107 MapleTracingTests pass, including new cases asserting traceparent and byte-identical bodies on what actually left the process, one per URLSession body API.
  • xcodebuild build -scheme Maple succeeds against 0.3.3.
  • Post-merge check: POST Client spans should appear with roots = 0, and push.sync traces should contain a maple-api http.server POST span.

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

…ong to

Two detachments, one screen. `push.sync` showed up as a single childless root:
the POST it exists to measure carried no client span and no `traceparent`,
because the SDK's interceptor declined every request with a body. Fixed in
maple-swift 0.3.3, which this bumps to — the app's writes now reach the API's
server spans in the same trace, the way its reads already did.

The second is ours. `trackScreen` hands back a `ui.screen` span but nothing
carries it, and the SDK is right not to make it ambient: a span that runs for
the whole visit is not a scope anything can nest inside. So every `ui.screen`
arrived as a childless root — 347 of 347 over three days — while the load it
caused sat in a trace of its own. `Telemetry.Visit` registers the open span by
screen name and `screenLoad` hangs under it, the same shape `PushOpen` already
uses to parent a load to the notification tap that asked for it. A tapped
notification still wins when there is one; a span the SDK closed on
backgrounding is skipped rather than adopted as a parent that ended first.
@Makisuo
Makisuo merged commit 5ca5011 into main Aug 21, 2026
26 checks passed
@Makisuo
Makisuo deleted the fix/ios-trace-parenting branch August 21, 2026 16:34
@Makisuo
Makisuo deployed to pr-preview August 21, 2026 16:34 — with GitHub Actions Active
@github-actions

Copy link
Copy Markdown

🍁 Maple PR preview

Note

Preview resources were removed when this pull request closed.

Final commit a8579a6 · View workflow run

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant