Skip to content

Feat: Harden the async image URL pipeline#72

Open
phranck wants to merge 4 commits into
mainfrom
issue/27-async-image-pipeline
Open

Feat: Harden the async image URL pipeline#72
phranck wants to merge 4 commits into
mainfrom
issue/27-async-image-pipeline

Conversation

@phranck

@phranck phranck commented Jul 24, 2026

Copy link
Copy Markdown
Owner

Closes #27.

Summary

  • URLImageCoordinator (actor): coordinates URL image loads with an injectable URLImageDataTransport. Cache hits skip the transport, concurrent identical URLs share a single in-flight task (deduplication), caller cancellation forwards into the shared task, non-2xx responses fail with downloadFailed, and byte limits reject before decoding.
  • URLSessionImageTransport: default transport using async URLSession.data(for:) — no more DispatchSemaphore blocking the concurrency-runtime thread on Linux, no more nonisolated(unsafe) result variable.
  • PlatformImageLoader.loadImage(from urlString:...) is async throws now and delegates entirely to the coordinator. ImageLoader protocol updated; the _ImageCore mounted task awaits it. The obsolete BoundedURLImageDataLoader (semaphore + unsafe state) is deleted.
  • _ImageCore lifecycle (verified, unchanged): mounted task is a deferred effect keyed to identity + source; source changes cancel and restart, the stale-response guard (Task.isCancelled + explicit source match) already prevents older responses from overwriting newer view phases. Rendering never mutates state from within the traversal window.
  • Two runtimes get their own coordinator through their own PlatformImageLoader; caches and in-flight state remain runtime-scoped (existing TUIContextTests still cover isolation).

Test plan

  • 1378 tests green on macOS (Swift 6.0.3) and Linux (Docker 6.0.3-noble), warning-fatal, via ./scripts/test-linux.sh
  • New URLImageCoordinatorTests (6 tests): cache hit/miss, dedup, status validation, byte-limit rejection, cancellation forwarding — driven by a scripted RecordingURLTransport that observes fetch cancellations
  • New ImageAsyncPipelineTests: URL sources commit through the async loader without traversal diagnostics
  • verify-compatibility-manifest.sh passes against the regenerated manifest

phranck added 4 commits July 24, 2026 15:57
- Add the URLImageDataTransport protocol (internal) with a default
  URLSession-backed implementation that uses async data(for:) instead
  of a DispatchSemaphore + nonisolated(unsafe) result variable
- Add the URLImageCoordinator actor: cache hits skip the transport,
  concurrent identical URLs share one in-flight task, cancellation
  routes into the in-flight task, non-2xx responses fail with
  downloadFailed, and byte limits reject before decoding
- Cover cache hit/miss, deduplication, status validation, byte-limit
  rejection, and cancellation forwarding with a scripted recording
  transport that observes fetch cancellations
- ImageLoader.loadImage(from urlString:...) is async now; the default
  falls back to cache lookup and the platform loader delegates to
  URLImageCoordinator
- Delete the DispatchSemaphore + nonisolated(unsafe) BoundedURLImageDataLoader
- _ImageCore's mounted task awaits the async URL loader
- Update the RecordingRuntimeImageLoader stub and drop the byte-limit
  test that exercised the removed helper (coverage moved to the
  URLImageCoordinator suite)
- Add an actor-based SlowURLImageLoader that counts invocations and a
  URLImageApp fixture; asserts that reading a URL source triggers
  exactly one loader call, no state mutates during traversal, and no
  runtime diagnostics fire
…pipeline

- Drop overrides for the removed BoundedURLImageDataLoader helper
- Add overrides for the new async loadImage(from urlString:...)
  signature on ImageLoader and PlatformImageLoader
- Regenerate the manifest with TUIkitAPICheck against fresh 6.0.3
  macOS and Linux snapshots
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.

[P1-22] Harden and test the asynchronous image pipeline

1 participant