techninja / cncserver

A RESTful API server for driving serial based CNC devices
133 stars 39 forks source link

Improve core performance #70

Closed techninja closed 8 years ago

techninja commented 8 years ago

Three years along and we still have the same problem: streaming lots of items in via any method does too much work in our single thread. I've opened a stack overflow question on the best ideas to make this happen given our limitations, with so far little immediate return beyond what I had already surmised:

My proposal is to create a new performance branch where I build out a separate node.js application spawned and controlled via an inter-process-communication (IPC) channel from the main application that ONLY handles the following:

I won't push the branch until I have an idea that this crazy idea is worth doing, and can be implemented sanely. Best case scenario is that I can get it to work just like before, except buffer running performance will be completely untouchable on a multi-processor system. Worst case scenario is we get an interesting idea without much merit.

Should be interesting!

oskay commented 8 years ago

This sounds reasonable; it's not so different from many standard CNC serving software packages, which do take in a full toolpath file, and serve only that.

techninja commented 8 years ago

...that's true! Though I might certainly miss the "live" aspect of changing the speed, it would directly suffer from this. Course if it's the only thing that would, it would be relatively trivial to write around this to allow modification of rendered data... maybe? Hrmm

techninja commented 8 years ago

Only took a few months... but it's working!

Latest push to the performance branch uses node-ipc to manage the client/server relationship between cncserver (now simply a steward of serial data and the bot state), and a runner process that manages all direct serial data and the running state of the buffer, talking about only what it needs to via interprocess communication calls.

WAYYYY more had to change than I thought, but it's REALLY going to be worth it. I've already done a few preliminary tests, and there is ZERO slowdown at all. The stuttering is gone, and so is the preloading. I'm going to take a wild guess that if you ran on a machine with only a single core it'd come right back with a vengeance, so I'm likely to leave in the RP support for preloading the buffer while paused, but ensure it's default OFF. No need to make people wait.

I wasn't sure at first how you would run the separate process in Electron, but apparently you can just open a new webview and BAM, new process. This would suffer from the same slowdowns as the "background process" issues we've seen, but the really cool thing is we can likely add a switch you can flick, so if you have node installed and available on the command line, you can have the runner process execute in its own low level node context, ensuring it would never have to wait around or even deal with Electron when executing.

There's still a lot missing here, but another great benefit in doing this, I've made the code about 10x more maintainable, splitting it out into ~10 categorized "modules", and paving the way to a far more modular and pluggable and abstracted system.

oskay commented 8 years ago

Sweet! I am now in an excited state.

techninja commented 8 years ago

This work is done and merged, and soon to massively improve RP Beta 2