eelcocramer / node-bluetooth-serial-port

Serial I/O over bluetooth for NodeJS

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Why is BluetoothWorker a singleton?

djMax opened this issue · comments

I think some of the performance issues (and perhaps stability ones) resolve around the BluetoothWorker singleton and all the locking it's trying to do. Any reason why it isn't a simpler instance-per-address or instance-per-nodejs-instance model? The pipe stuff looks to be contained inside the worker so that seems fine...

I see that you might need the devicesLock across devices (though you could also leave that to the client to manage), but I think the ones that should be device specific are the connectLock and writeLock. True?

I can't really remember why I made it into a singleton. I remember that I did not design it to be singleton
to begin with as I do not like that pattern, but I was kind of forced to make it a singleton.

I had a hard time handling the OSX threading model and to make the library work in the background, not blocking the script execution.

The choice of having it handle multiple devices (and have the deviceLock) might have to do something with the fact that I did not want to change the API to much. The Linux (and Windows?) version was already there first. But this is speculating as I do not remember.

It might be worth investigating if it is possible to have separate threads for each device and have multiple instances of the worker but this would require serious refactoring.

I've made a simple "fix" for this by changing getInstance to take an address (or null for a non-device specific request). Seems to do the job though I'm also trying to hunt down this other bug. Code is on this branch:

https://github.com/djMax/node-bluetooth-serial-port/compare/eelcocramer:issue47...mm_multithread_worker?expand=1

I've taken your changes in pushed them to branch issue51. Currently the code in this branch also removes the locking mechanism for the devicesLock. I only lock around connecting, disconnecting and writing at this moment. This greatly improves writing lag (issue #35). Further testing (especially with reading data from BT connection is required before merging this).

I've did some write and read tests on my test device and everything seems to work fine.

Can you verify this branch with your setup as well? Your setup seems more complex then mine.

Crashes with a segfault here. Looking into it.

The number of changes in this branch are increasing. It might be worth working your way up from commit e8cba1de5fa572265cac596b392deb7f7199ecfd which holds only your changes with regards to the singleton.

yeah, mm_multithread on my fork does not crash. But it's also behaving strangely on the protocol front. Unfortunately I forgot my real test device, so trying with some others and not sure it's not the device. Any reason you yanked the logging? Just wondering in case I get this working so that I can submit proper pull for comparison.

Bah. Going back to issue47 makes it work, so something else is up. What's happening in the new code is it seems the commands aren't making it out to the device... I get inbound messages, but not outbound.

No reason. I did not cherry pick your changes but just made the changes to my own code and did not include the logging.

bah - never mind I just forgot to undo my "make this act like a singleton again" :)

Seems like a writing issue. If you checkout the e8cba1de5fa572265cac596b392deb7f7199ecfd commit all the locks are still in place (I removed them in a later commit).

So now back to the main task here... With a single device, everything is still fine. But with three, I get a segfault in my branch too. https://gist.github.com/djMax/4a39d9580e153d78cd52

Putting a singleton lock around the RFComm channel open is showing some promise.

Cool. Keep me updated. I've to leave now but I'll back later. As I've only 1 device I cannot really reproduce your setup.

will do, thanks for all the help. I've updated mm_multithread with latest. I'm going to try on Windows today too so we'll see if that was already fine.

And generally the performance for multi-device writes looks good now too. Connect can be problematic of course because everybody stacks up and it seems to take an arbitrary amount of time on osx. But better than everything stacking up.

Ok. I've cherry picked the commit that adds the global lock for opening the rfcomm channel.

When would be a good time to release the per-device worker? I think that if we don't, I'm not sure the app can quit normally because the worker thread will be dangling out there. (Or at least my app isn't quitting anymore and I'm not sure if this might be it)

And on my home machine (10.10.1 MBP), I've managed to hard crash the mac a few times seemingly around bluetooth, so I guess we've found an Apple bug along the way :)

I want to release next week. The branch has holds quite a lot of fixes for other issues as well and I hope for a response on some of these issues that are hopefully now fixed as well.

I also would like to have someone test the windows build on 0.10 and 0.11.

It this soon enough for you?