Crypto platform update - Refactoring the backend servicesteemCreated with Sketch.

in crypto •  8 years ago  (edited)

As I briefly touched in my original post, my platform is roughly separated into a front-end webapp and a back-end set of node services. For my original tests, this served its purpose well enough. I was content with keeping a separation of concerns when it comes to processing different types of information, but communication between the various services relied on a common event bus in the front-end. I needed to change that.

My original strategy was based around simply creating a plain Javascript file and running it through node. This was simple, but inefficient. I couldn't take advantage of the neat features offered by babel and webpack. I added a new build step to the list, so the build process now includes:

  • Main - The main Electron process
  • Renderer - The Electron browser process
  • Web - Static files
  • Backend - The new service module

Instead of creating a Vue component for each service, I now have a single, narrowly-focused component that pipes data to/from the backend. I have removed the service bus completely, and added a test page within my app to monitor data within the service.

I can now refactor my backend to include some neat features from both babel for ES6 support and webpack for its additional require options. It allows me to write a series of interfaces (coming from C++ background) that define common functionality. Currently, I have the following interfaces:

  • base-wallet.js
  • base-exchange.js
  • base-indicator.js
  • base-bot-strategy.js

I can utilize ES6's classes to extend these interfaces for each supported module.

  • wallets/btc.js
  • wallets/doge.js
  • exchanges/bittrex.js
  • exchanges/gdax.js

Finally, I can load them all in cleanly:

const wallets = {};
const exchanges = {};

const wallet_files = require.context('./wallets', false, /\.js$/)
const exchange_files = require.context('./exchanges', false, /\.js$/)

wallet_files.keys().forEach(key => {
    try {
        wallets[key.replace(/(\.\/|\.js)/g, '')] = wallet_files(key).default;
    } catch(err) {
        process.send({message:`unable to add wallet ${key}`});
    }
});

exchange_files.keys().forEach(key => {
    try {
        exchanges[key.replace(/(\.\/|\.js)/g, '')] = exchange_files(key).default;
    } catch(err) {
        process.send({message:`unable to add exchange ${key}`});
    }
});

// Module validation goes here

The biggest benefit here is that I can keep a separation between local and remote backends. My webpack configuration allows me to build both variations easily, with minor adjustments to account for differences between a local IPC channel and a remote websockets connection.

On IPC

I love how gracefully nodejs handles this. I have attempted to replicate Chromium's IPC setup in past C++ projects, and they became unwieldy and difficult to work with. I would need to hunt down and bring in another library, such as Boost's wonderful IPC library. I would then need to add it to CMake, test the various configurations to ensure it builds properly, and then I can actually use the library. Then I need to deal with creating a shared memory pool, serializing/deserializing objects, and all the associated headaches.

Here, the IPC channel is setup for me the moment I fork the child process. It automatically handles Javascript objects for me

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

Very interesting