Skip to content

Platform Notes Thread Safety and Performance

Husnain Ali edited this page Sep 27, 2026 · 3 revisions

Platform Notes, Thread Safety and Performance

Thread safety

  • NetworkClient is Sendable. Construct one and share it.
  • Shared mutable state lives in actors: TokenManager, RequestQueue, RequestRegistry, RequestDeduplicator, the cache stores, InMemoryMetrics, OfflineRequestQueue.
  • The concurrent 401 case is handled by TokenManager's single-flight refresh; there is an explicit deadlock test for "full queue plus expired token".
  • The only @unchecked Sendable types are the three URLSession delegate shims (whose callbacks are not async) and the test doubles; each guards a few lines with a lock and a comment.
  • SwiftUI NetworkResource / Paged are @MainActor.
  • The whole test suite runs green under ThreadSanitizer in CI.

Performance

  • URLSession connection reuse is preserved (one session per client, plus a dedicated session per upload/download for progress delegation).
  • maxConcurrentRequests (default 6, matching the URLSession per-host limit) bounds in-flight work; extra requests queue by Endpoint.priority.
  • Deduplication removes redundant identical GETs. See Request Management.
  • The cache short-circuits the network entirely for fresh cacheFirst / cacheOnly hits. See Caching.
  • Large multipart parts and downloads stream from and to disk rather than loading into memory.
  • Retry timing is computed, not busy-waited (NetworkClock), and the Retry-After date parser reuses one formatter instead of allocating one per request.

Known issues and platform notes

Apple-platform behaviors that shape the design or that you should be aware of:

Area Note
Upload/download progress The async URLSession.upload(for:from:) / download(for:) methods do not reliably forward didSendBodyData / didWriteData to a per-task delegate. SwiftNetworkKit works around this by running each transfer on a dedicated URLSession with a session-level delegate (TransportSessionDelegate). A side effect: uploads and downloads do not share the main client's connection pool, and a delegate, credential handler, or pinning attached directly to a caller-supplied URLSession does not apply to them.
Background transfers URLSessionConfiguration.background requires app-side wiring (an AppDelegate completion handler, an app-wide session identifier). SwiftNetworkKit does not configure background sessions automatically; download(_:to:) runs in-process.
Background sessions in the Simulator Historically flaky (rdar://26870455). Test background behavior on a device.
Keychain on macOS CI KeychainTokenStorage can be unavailable on headless CI runners with no keychain. KeychainTokenStorage.isAvailable guards this; the test suite skips those cases when it returns false.
URLProtocol + request bodies Custom URLProtocol subclasses (used by URLProtocolStub in tests) historically mishandle httpBodyStream (rdar://26849668). The stub asserts on URL, method, and headers rather than replaying streamed bodies.
TLS 1.3 0-RTT Not used. URLSession decides; the package does not opt into early data.
visionOS / watchOS / tvOS CI builds the library for every declared Apple platform, and runs the full test suite on iOS, macOS, and Linux (Foundation subset). tvOS / watchOS / visionOS are "builds green, test suite not run on-device".

If you hit a platform bug not listed here, please file an issue with the OS version and a minimal reproduction.

Clone this wiki locally