Repository navigation
Conversation
A final stop() with deactivatesAudioSessionOnStop schedules setActive(false) off the main actor, and that call alone takes about half a second on an Atmos passthrough route. Only a load() on the same engine cancels it. A host that tears one player down and opens another engine straight away could therefore have the old engine's late release deactivate the session the new player has just taken. This was reported but never reproduced, so the change is a defensive guard. Add audioSessionReleaseGate, an optional @sendable () -> Bool the engine reads when stop() schedules the release and calls right before setActive(false), after any renderer activation queued ahead of it. When it returns false the release is skipped and logged. With no gate set the release runs as before. Document it in docs/api.md and the changelog, and cover nil, false and true in the teardown policy tests. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…ase-gate Bring in the review fixes from #12: resolvers run off the cooperative pool, backward detour reads latch authorization refusals, resolver headers stay off cross-origin targets, and the failure docs separate pre-send from post-401 failures. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ase-gate Bring in the second round of #12 review fixes: detour reads honour a latched authorization refusal, the detour tests no longer race the pump, and the pool-parking resolver test runs in the main test group. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
4 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A final
stop()withdeactivatesAudioSessionOnStopschedulessetActive(false)off the main actor, and on an Atmos passthrough route that call alone takes about half a second. Only aload()on the same engine cancels it. A host that closes one player and opens another engine straight away could have the old engine's late release deactivate the session the new player just took. This was reported but never reproduced, so this PR is a defensive guard: it lets the host veto the release.Stacked on #12; review that first. Used by Silo-Server/silo-apple#611.
What changed
public var audioSessionReleaseGate: (@Sendable () -> Bool)?onAetherEngine, next todeactivatesAudioSessionOnStop, defaultnil.stop()schedules the release. Inside the queued release it calls the gate off the main actor just beforesetActive(false), after the existing cancel and load-generation checks. Ordering behind a pending renderer activation is unchanged.falseskips the release and logsAVAudioSession release skipped: audioSessionReleaseGate returned false. With no gate set, the release runs as before.docs/api.md(the "Now Playing and the audio session" table) andCHANGELOG.md.What this does not close: the gate is checked when the queued release starts, a few milliseconds after
stop(). AsetActive(false)already in flight cannot be cancelled, so fully ordering releases across engine instances would need coordination inside the engine. Silo's host-side ownership check blocks a release only when a newer load has started.Test plan
swift test). Not run on a device or on an Atmos or AirPlay route. The iOS/tvOS release path is covered through its policy function, becauseswift testruns on macOS.swift testpasses in both CONTRIBUTING.md groups ond0aa7c2b, which merges both rounds of fix(avio): refresh direct-play credentials on every range request #12's review fixes: 3,395 Swift Testing tests in 458 suites and 636 XCTest tests (1 skipped), plus 65 authorization tests. New tests inAudioSessionTeardownPolicyTests: gatenilreleases,falseskips,truereleases. The default-off test also checks that the gate isnil.Evidence: https://evidence.siloserver.org/r/aetherengine/audio-session-release-gate/
Checklist
CHANGELOG.mdupdatedfeat(...),fix(...),chore(...))audioSessionReleaseGate)AI disclosure
claude-opus-5-5🤖 Generated with Claude Code
Note
Add
audioSessionReleaseGateso hosts can veto a scheduled audio-session releaseaudioSessionReleaseGateclosure property onAetherEnginein AetherEngine.swift. It is read when the release is scheduled and invoked off the main actor right beforesetActive(false).scheduleAudioSessionDeactivationcaptures the gate at schedule time. After the existing cancellation and same-engine checks, afalseresult logs a skip and returns without deactivating.nil, absent, allowing, and refusing gates in AudioSessionTeardownPolicyTests.swift.nil, so existing hosts see no change; setting a gate tofalsenow skips the sharedAVAudioSessiondeactivation and logs the refusal.Macroscope summarized d0aa7c2.