• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

supabase / supabase-swift / 30458338125
84%

Build:
DEFAULT BRANCH: main
Ran 29 Jul 2026 02:10PM UTC
Jobs 1
Files 99
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

29 Jul 2026 01:55PM UTC coverage: 84.055% (+0.2%) from 83.865%
30458338125

push

github

web-flow
fix(realtime): fix AsyncValueSubject deadlock, then inline and delete it (#1155)

* fix(helpers): resume AsyncValueSubject continuations outside the lock

Fixes a lock-order-inversion deadlock: yield()/finish()/insert() resumed
AsyncStream continuations while holding the subject's lock. Resuming a
continuation can synchronously reach into the Swift runtime's task
status-record lock, while task cancellation takes that lock first and
calls back into remove()/insert() for the subject lock — inverted order,
deadlock. Hit in production as a fatal main-thread watchdog kill
(supabase/supabase-swift#1154).

Snapshot continuations under the lock, resume them after releasing it.

Adds a stress test that races withTimeout's group.cancelAll() against
concurrent yield() calls, reproducing the hang pre-fix (it ran well past
its own 60s timeLimit) and passing in ~3.5s post-fix.

* fix(helpers): preserve delivery ordering in AsyncValueSubject

Releasing mutableState's lock before resuming continuations (this PR's
prior commit) fixes the lock-order-inversion deadlock, but opens a new
gap CodeRabbit flagged: concurrent producers can now race each other to
resume, delivering values out of order relative to how their state
mutations were actually serialized.

Reimplements the delivery mechanism with a ticket turnstile: each
yield/finish/subscribe takes a monotonic ticket under the same lock
that mutates state, then a small NSCondition-based turnstile resumes
continuations strictly in ticket order. The turnstile never touches
mutableState, so cancellation's `remove` is never blocked by it —
preserving the deadlock fix.

(Two earlier approaches were tried and discarded: a DispatchQueue-based
serial queue mixed GCD with Swift concurrency for no good reason, and a
hand-rolled pending-event queue nested inside `mutableState` caused a
severe performance cliff — LockIsolated's copy-in/copy-out keeps the
old struct alive during the whole closure, so every mutation of a
growing c... (continued)

210 of 216 new or added lines in 6 files covered. (97.22%)

8424 of 10022 relevant lines covered (84.06%)

39.6 hits per line

Uncovered Changes

Lines Coverage ∆ File
3
88.1
0.01% Sources/RealtimeV2/RealtimeClientV2.swift
2
95.24
Sources/RealtimeV2/RealtimeClient+HeartbeatStatus.swift
1
67.65
0.35% Sources/RealtimeV2/RealtimeChannelV2.swift
Jobs
ID Job ID Ran Files Coverage
1 30458338125.1 29 Jul 2026 02:10PM UTC 99
84.06
GitHub Action Run
Source Files on build 30458338125
  • Tree
  • List 99
  • Changed 3
  • Source Changed 3
  • Coverage Changed 3
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Repo
  • Github Actions Build #30458338125
  • 0e91b2f0 on github
  • Prev Build on main (#30350131112)
  • Next Build on main (#30459456649)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc