Closed odejesush closed 6 years ago
Exposing WebUSB on dedicated and shared workers doesn't feel like it poses any new architectural issues over those posed by WebUSB itself, beyond making sure that the API behaves appropriately if it's being accessed from more than one thread at the same time. That sounds like it might be difficult... though it's not clear if it's something that the TAG would be effective at reviewing.
I assume there is interest in doing something similar for Web Bluetooth, and we have also thought about doing something like that for Generic Sensor API.
In Chrome at least, these implementations already run in a separate thread as the main browser UI, and communicate via IPC / shared memory, so whether something is being accessed from the main browser thread or a worker shouldn't matter that much. With the Generic Sensors, each physical sensor can be accessed from multiple sensor objects, sharing the data. I think that makes sense when using from the same context, and in the case of sensors, but both Web Bluetooth and Web USB create single connections, so they should only be accessed from one place.
In this case (looking at the explainer) there is a "transfer" involved. Ie. you request the device on the main browser / UI thread, and then you are able to access it from the worker. So I would say that is solved here, and I think the solution is okay. (more below)
I am also interested in what happens when the browser tab (or site on mobile) gets backgrounded - I assume that it will share the same behavior as when running in the main browser thread as today, and thus loose connection? Do you intent on looking at making changes around this in the future?
Also I don't get why you have to request a device on the browser main thread and then still list all devices on the worker and find the one that matched and then open() it. Can't we not just transfer over the object instead, somehow? Like can't it be a Transferable object like ArrayBuffer, MessagePort and ImageBitmap?
ie. this code seems a bit clumbersome:
on worker:
case 'get-device':
let devices = await navigator.usb.getDevices();
foreach (let device of devices) {
if (device.vendorId === event.data.vendorId
&& device.productId === event.data.productId) {
selectedDevice = device;
selectedDevice.open();
break;
}
}
@dbaron A Shared Worker should be able to handle multiple requests to access the USB device. If I understand correctly, the worker would handle one message at a time in its event loop.
@kenchris WebUSB should behave the same in a worker as with the main thread when the tab is backgrounded. There is a tab indicator that shows when a tab is connected to a USB device, so the backgrounded tab will display the indicator if it is still connected to a USB device.
As for your second question, being able to transfer over the object is something that we're considering so that we don't have to use getDevices in the worker if it's not too difficult to implement.
Thank you for the feedback.
@odejesush pretty sure @dbaron was wondering about multiple workers accessing the USB device concurrently. If they cannot, it sounds like you should make use of a parallel queue: https://html.spec.whatwg.org/#parallelism.
Thanks @annevk for the clarification. USB devices are unable to distinguish requests from multiple sources so operating systems only allow an interface to have a single owning user-space or kernel-space driver. In WebUSB, the UA acts as a user-space driver and only allows a single JavaScript execution context to claim an interface at a time. Therefore, it shouldn't be possible for multiple workers to access the same USB device concurrently. I hope that this answers your question @dbaron.
@odejesush That sounds pretty reasonable -- though maybe the spec should be clearer that that's the case?
@kenchris to open issue in WebUSB repo or reference appropriate issue.
Hi, I just wanted to provide a quick update. I submitted a pull request for clarifying how WebUSB on workers deals with multiple threads accessing a USB device. Additionally, there was some discussion from the chrome worker team about potentially deprecating shared workers in Chrome. The discussion is summarized in the blink-dev Google group. It would still be beneficial to get the feature reviewed for both Dedicated and Shared Workers. Thank you again!
Sorry for the delay here.
Thanks for making that update to the spec. We don't think there's anything else here that we feel the need to review, so we're closing this issue now.
Thanks for bringing this to the TAG.
Hello TAG!
I'm requesting a TAG review of:
Further details (optional):
You should also know that...
The change to the spec was small, I only added Exposed extended attributes for the USB and Navigator interfaces, and a partial interface for WorkerNavigator with a usb attribute. The change can be seen in this pull request. Chrome implementation has started and will be implemented under a runtime enabled flag.
We'd prefer the TAG provide feedback as (please select one):
Thank you