How to utilize an algorithm written in a different language in a (NodeJS) web service?

Viewed 31

I'm starting my work an a school full stack project and the NodeJS & React stack is a requirement. However, I have an algorithm written in C# which I need for this project. I'm creating an app where people upload MIDI files and the algorithm analyzes the MIDI and produces instructions how to play the song on a guitar (or other string instrument e.g ukulele).

The problem is that if I have a NodeJS backend I have no idea what is the best way to utilize this algorithm. My options are:

  1. Rewrite in TypeScript (not a fan of this option)
  2. Containerize the algorithm
  3. Host the algorithm as it's own web service with a single API endpoint
  4. WebAssembly??
  5. NodeJS C++ addons? (I'd much rather rewrite in C++)

The reason I don't want to use TypeScript for the algorithm is that it's not a great fit in my opinion. The algorithm is almost entirely bit operations and minimal size structs with bitmasks to enable efficient copying of data (it's essentially a search algorithm). I feel TypeScript would limit my ability to improve and extend it since these things are arguable easier to implement in lower level languages.

I'm asking for advice how to proceed. I will (most likely) be using Heroku as a hosting service and I have no clue which of these options, if any, would be the best choice. Any and all advice is appreciated.

1 Answers

The most performant option would be to rewrite the MIDI processor as a C++ NodeJS addon. If it's not too big and ugly, then this would be the way to go.

The easiest option, and the best alternative, is to wrap the C# algorithm in a simple little server that you can run from NodeJS with child_process.spawn().

I have a fair bit of experience doing things like that, so if you want to go that way, I can offer you this advice:

  • The child process should exit when it's standard input closes. This is the most convenient, reliable, cross-platform shutdown signal you have.
  • Stdin/stdout should be used for all other lifecycle-type communication between parent and child. If your child process opens a socket to listen on, it should send the port number to the parent on stdout, for example. Again, this is super easy for parent and child.
  • Each instance of the child process should be able to handle multiple operations. The easiest thing is that the child processes multiple requests in sequence from stdin, and writes each result to stdout. If you need the child to handle multiple requests simultaneously, then it can open a server socket that processes one request per connection.
  • The parent NodeJS process should manage a pool of running child processes. Always keep one alive so requests don't have to wait for child processes to start up.
Related