-
Notifications
You must be signed in to change notification settings - Fork 114
Rewrite based around napi and context aware #127
Conversation
Hey @Julusian, Sorry for the delay. These are huge refactor changes that are daunting for me to pop-in and review. I've been putting it off and it would be nice if someone else can come help review this code as well. Mind putting some comments in places to explain any bits or why you chose that way, etc?
Very interesting edge case! I'd be fine with iterating this in another PR and make a major breaking change. Let's wait on that until I can manage this PR though. |
@MadLittleMods no problem, I havent gotten around to doing the work for mac or windows yet, I have gotten distracted on other projects. |
@MadLittleMods I think this is ready to be looked over. I would suggest not trying to read the diff, but instead reading just the new code, and having the old code to hand as a reference to explain why some things are as they are. A lot of it isnt new, but it has been shuffled around a lot so really confuses the diffs. I havent added much on comments, I shall try and give it another look over, but please do ask questions to help direct what need comments I have rewritten and tested all 3 platforms, but some additional testing and bugfixing is needed. I am aware of a segfault on mac that occurs when multiple worker_threads are constanting starting and stopping monitoring. I think I have checked for memory leaks when starting and stopping monitoring (revealing the mac segfault). My criteria for a leak was no notable memory usage change after at least an hour of starting and stopping monitoring every 100ms. I should note, that I have tested the mac version exclusively on M1, as that is what I have easier access to and it should behave the same. As part of this, the mac build is a multiarch binary, which will resolve #141 |
@thegecko I did not notice that node-usb supports hotplug events, and through libusb which should make everything simpler and much more maintainable. Can you think of any reason not to deprecate this library and instead point users to using node-usb? It looks like this project predates libusb hotplug detection by a few months, and there isnt any other reference to libusb, so I suspect it hasn't been considered moving to libusb before. Lack of official windows support is another issue that you appear to be handling. |
Thanks for raising this, this has come to my mind recently, too. There are reasons not to deprecate this library IMO, but it may be better to consider merging them somehow.
This is our major area of issues now. In my day-job, we develop a product which actually uses both of these libraries due to two issues, both of which are on Windows:
Is there a scenario where we can merge |
This is really a disccusion that @MadLittleMods needs to be involved in. I'm a user with no prior contribution history to this project. :) It occurred to me to check node-usb while I was sitting reviewing my rewritten mac code to find a memory leak, and I was surprised to see that it supported hotplug events. I guess I never thought to check, as why else would this library exist I can look at writing a PR for node-usb bringing the windows code across, doing that means I can test just the one platform for memory leaks and segfaults.
To clarify, does your product also run on other oses and they behave fine? |
Agreed
That would be awesome
Yes, MacOS and Linux and they both work fine. |
@@ -15,28 +15,6 @@ | |||
npm install usb-detection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a scenario where we can merge
node-usb-detection
intonode-usb
(or at least the windows implementation) to cover the deficiencies in libusb and align efforts? I'd love to see the JavaScript polling removed and native events used instead.
The reason I started using this project 6 years ago was because it was the only project that actually worked on Windows (and the other OS's). Although not my use case, it also seems like a lot of people use this with Electron so it would be good to have a compatible option there too.
The second criteria is documentation which looks to be available on https://github.com/node-usb/node-usb#usbdetection
A third criteria is it actually being able to be built and installed easily. This means prebuilds or ideally no C++ code necessary if that was even possible.
If those can be addressed(which some already are), then I could see this being deprecated in favor of usb
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@thegecko (repost that in this thread)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@MadLittleMods I believe with the v2.x.x
release of node-usb
, all of your criteria are now met
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@thegecko Tested and seems to work. I think we can move forward with deprecating as I'm running into a wall trying to get prebuilds to work anyway (#165 (comment)).
const { usb, getDeviceList} = require('usb');
const devices = getDeviceList();
console.log('devices', devices);
usb.on('attach', function(device) { console.log('attach', device) });
usb.on('detach', function(device) { console.log('detach', device) });
To note some differences and preemptively answer some peoples questions, how do we get deviceName
, manufacturer
, serialNumber
when using the usb
package? Maybe I'm just not understanding how to get a USBDevice
which seems to have those properties as described in the readme and somehow mixing the legacy API.
usb-detection
{
locationId: 336592896,
vendorId: 6353,
productId: 20193,
deviceName: 'Pixel 4a',
manufacturer: 'Google',
serialNumber: 'xxx',
deviceAddress: 7
}
usb
{
busNumber: 20,
deviceAddress: 5,
deviceDescriptor: {
bLength: 18,
bDescriptorType: 1,
bcdUSB: 512,
bDeviceClass: 0,
bDeviceSubClass: 0,
bDeviceProtocol: 0,
bMaxPacketSize0: 64,
idVendor: 6353,
idProduct: 20193,
bcdDevice: 1088,
iManufacturer: 1,
iProduct: 2,
iSerialNumber: 3,
bNumConfigurations: 1
},
portNumbers: [ 1 ]
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The legacy API returns the raw USB data which doesn't undertake further blocking calls to obtain the strings (e.g. serial number, device name, etc.).
You can get these in a manner of ways:
- Use the legacy device you got from
getDeviceList()
or your legacy event and call getStringDescriptor for each of the string IDs - Wrap the legacy device into a webusb compatible device which pre-populates these strings
- Use the WebUSB interface to request a device or register for events:
import { WebUSB } from 'usb';
(async () => {
const customWebUSB = new WebUSB({
// Bypass checking for authorised devices
allowAllDevices: true
});
customWebUSB.addEventListener('connect', event => console.log(event.device);
})();
I have just confirmed this is no longer the case with the latest
https://github.com/node-usb/node-usb-example-electron
Docs do exist. Making these better (especially as we introduce the v2 APIs) is next on my todo list.
The recent move to
Does
👍 |
Hi all, Apart from that, it works great and I'd really like to see this merged to this lib ;-) Edit: I also find that the |
@Julusian I've started to think about replacing the windows hotplug polling in node-usb with a native implementation. I'm not a C/C++ guru so wondered if you had started this at all? My first step would be to take the Windows parts of your NAPI port in this PR... |
@thegecko I haven't started on anything. Its on my todo list and I would really like for it to be done, but windows is my least favourite platform to write c++ on so its been hard to motivate getting started |
Moved node-usb discussion to node-usb/node-usb#488 |
Since this PR also mentions making node-usb-detection context-aware, cross-linking to the equivalent node-usb issue: node-usb/node-usb#491. |
@Julusian I am not sure to understand the state and the future of this PR. It is marked as draft, and the only expected issue seems to be
Is it still draft because of the lack of reviews or do you plan to continue working on this PR? I saw your latest efforts was to merge things into node-usb. If you manage to do it, would it means that node-usb would supersede node-usb-detection? In that case do you have guidelines in order to move from node-usb-detection to node-usb? Context: my goal is only to use https://github.com/LedgerHQ/ledger-live/tree/develop/libs/ledgerjs/packages/hw-transport-node-hid-singleton in an electron14+ app. I saw this: cryptogarageinc/ledger-liquid-lib@25e57a1 but do not know if it is the way to achieve this or not. Thank you. cc @thegecko (and please excuse me if this cc is not relevant) |
I do not expect this PR to make any more progress, the current aim is to merge the relevant portions of this into node-usb. I have left it open for visibility until node-usb is capable of proper windows hotplug detection. Once node-usb/node-usb#524 is merged and released, then some documentation can be written and this library can be deprecated |
As @Julusian mentioned, some docs have now been added to https://github.com/node-usb/node-usb#migrating-from-node-usb-detection |
Hi @Julusian, Could you give me a hint what build config to change in order to create a mach-o file for MacOS? Best regards |
Never mind. It seems like |
fixes: #102, #119, #57, #116, #42, #53
replaces: #113, #125, #118
I haven't fixed up mac or windows yet, but shall get to that soon.
This has become quite a large rewrite due to how parts were written.
I have tried to split it across commits in different phases to make it easier to understand.
Support for anything below node 10 has been dropped, due to limitations of napi. I dont see this as a problem as everything still officially supported is covered. The benefit to this is that the builds are guaranteed to work in future versions of node without needing to be recompiled. There is also no need to recompile for electron, as it will use the same binaries
All the usages of
#include<uv.h>
have to be replaced as they are not abi safe. Because of this I have pretty much rewritten the contents ofdetection_linux.cpp
, taking inspiration and reusable snippets from the old file.To be context aware, nothing can be in the global scope so various bits had to be refactored to remove any use of statics.
For now this change is not trying to optimise for multiple threads, so is initialising a new listener/watcher for each thread. This can be improved on later.
For now this I have avoided any api changes, but it would be nice to make some to better reflect ownership of the listener. One concern I have is that if two libraries uses this and one calls stopMonitoring, that will stop events for the other or the root application. It would be nice to be able to scope listeners instead, by returning something from the start function that will allow for manual stopping and restarting, and will auto-stop when it gets garbage collected.