mirror of
https://github.com/stablyai/orca.git
synced 2026-09-21 16:02:20 +00:00
fix(mobile): let dispose re-read the tag set once its turn comes
Queueing dispose behind each tag's own operations introduced a call the module says it does not make: a release already in flight can give the tag back before dispose runs, and deactivating an unheld tag is a native call whose failure would read to the page as a lock it could not drop. Re-reads the set when the queued action runs rather than trusting what it held when dispose was called. Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb
This commit is contained in:
@@ -115,4 +115,26 @@ describe('a release issued while its own activate is still in flight', () => {
|
||||
gated.settle('activate:orca-mobile-dictation:1:c')
|
||||
await expect(first).resolves.toEqual({ active: true })
|
||||
})
|
||||
|
||||
it('does not ask the device again for a tag a queued release already gave back', async () => {
|
||||
// `dispose` queues behind the tag's own operations, so by the time it runs the release ahead
|
||||
// of it may have returned the tag. Deactivating an unheld tag is a native call this module
|
||||
// does not make: its failure would read to the page as a lock it could not drop.
|
||||
const gated = createGatedDevice()
|
||||
const server = createNativeWakelockServer(gated.device)
|
||||
const activated = server.serve({ active: true, tag: 'orca-mobile-dictation:1:e' })
|
||||
await settleMicrotasks()
|
||||
gated.settle('activate:orca-mobile-dictation:1:e')
|
||||
await expect(activated).resolves.toEqual({ active: true })
|
||||
const released = server.serve({ active: false, tag: 'orca-mobile-dictation:1:e' })
|
||||
await settleMicrotasks()
|
||||
server.dispose()
|
||||
gated.settle('deactivate:orca-mobile-dictation:1:e')
|
||||
await expect(released).resolves.toEqual({ active: false })
|
||||
await settleMicrotasks()
|
||||
expect(gated.calls).toEqual([
|
||||
'activate:orca-mobile-dictation:1:e',
|
||||
'deactivate:orca-mobile-dictation:1:e'
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
@@ -104,8 +104,13 @@ export function createNativeWakelockServer(device: WakelockDevice): NativeWakelo
|
||||
// Quiet, for the reason every other dispose here is: this runs while a screen is going
|
||||
// away, and a device that would not drop a tag is not something the page can be told about.
|
||||
// Forgotten only on success, so one this device refused stays recorded and a later release
|
||||
// still reaches it. Queued behind that tag's own operations rather than racing them.
|
||||
// still reaches it. Queued behind that tag's own operations rather than racing them, and
|
||||
// re-reading the set once it runs: a release already in flight may have given it back, and
|
||||
// deactivating an unheld tag is a native call this module does not make.
|
||||
void enqueue(tag, async () => {
|
||||
if (!held.has(tag)) {
|
||||
return
|
||||
}
|
||||
await device.deactivate(tag)
|
||||
held.delete(tag)
|
||||
}).catch(() => undefined)
|
||||
|
||||
Reference in New Issue
Block a user