You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The implementation of the generic write() method which is called by the various XKeys methods (e.g. setting backlights) is asynchronous in nature, yet resolves synchronously before the promise returned by the underlying call to sendReport() has resolved:
Promise rejections are handled by emitting them as error events.
This forces usage of the API to always have an error listener registered for the duration of the program in order for the code to be safe; if the listener is removed at any point, it is possible that a pending promise rejects and emits an error event which would be unhandled.
This makes it near impossible to clean up an XKeys object by calling methods on it such as setAllBacklights() before un-registering the listeners such that it can be GC'd:
// setupconstxKeys=setupXKeysPanel(device)consterrorListener=(e)=>console.error(e)xKeys.on('error',errorListener)// ... later, after an abnormal event// cleanupxKeys.setAllBacklights(false)xKeys.removeListener('error',errorListener)// the promise indirectly created from the call to `setAllBacklights` resolves at some point after the synchronous code, when the error listener has already been un-registered
A workaround is to keep the listener registered for an arbitrary amount of time to handle any pending promises:
A proper solution would be to allow checking that all sendReport promises have settled before cleaning up the device, which would entail making the API methods async.
The text was updated successfully, but these errors were encountered:
loucadufault
changed the title
WebHID: methods which call write (sendReport) to the device should be async
WebHID: methods which write (sendReport) to the device should be async
Aug 12, 2024
loucadufault
changed the title
WebHID: methods which write (sendReport) to the device should be async
WebHID: methods which write (sendReport) to the device should be async
Aug 12, 2024
After some consideration, I propose these changes to address this:
Add a flush(): Promise<void> method to wait for any lingering writes.
Also: Once close() is called, promise to never emit any errors anymore.
With these changes, you should be able to acheive a proper cleanup like so:
constxKeys=setupXKeysPanel()consterrorListener=(e)=>console.error(e)xKeys.on('error',errorListener)xKeys.setAllBacklights(false)// cleanup:awaitxKeys.flush()// waits for all writes to finishawaitxKeys.close()// close the device.xKeys.off('error',errorListener)
The implementation of the generic
write()
method which is called by the variousXKeys
methods (e.g. setting backlights) is asynchronous in nature, yet resolves synchronously before the promise returned by the underlying call tosendReport()
has resolved:xkeys/packages/webhid/src/web-hid-wrapper.ts
Lines 24 to 32 in e9d925e
Promise rejections are handled by emitting them as
error
events.This forces usage of the API to always have an
error
listener registered for the duration of the program in order for the code to be safe; if the listener is removed at any point, it is possible that a pending promise rejects and emits anerror
event which would be unhandled.This makes it near impossible to clean up an
XKeys
object by calling methods on it such assetAllBacklights()
before un-registering the listeners such that it can be GC'd:A workaround is to keep the listener registered for an arbitrary amount of time to handle any pending promises:
A proper solution would be to allow checking that all
sendReport
promises have settled before cleaning up the device, which would entail making the API methods async.The text was updated successfully, but these errors were encountered: