JXcore – A Node.JS Distribution with Multi-threading

jxcore_header

By Krzysztof Trzeciak

JXcore is a fork on Node.JS 0.12 which is 100% compatible with Node.JS v0.12 and also with all the projects and modules around it.

JXcore multithreading shouldn’t be confused with multiple threads running on top of the same JavaScript code. JXcore multithreading does not bring in any thread safety problem to your existing project. It creates a v8 thread pool and issues your tasks separately on different threads. All the results turn back to the main thread in the same order without compromising the thread safety of the main thread. It doesn’t change the way you develop a Node.JS project at all. It simply makes your project benefit from multiple cores as is. It’s not a simple web worker – a single JXcore task can run the whole server alone.

Using the new multithreaded tasks API, you can simply customize the multithreading feature for your own usage. On the other hand, if you simply want to scale your solution up, the image below shows how easy it is to make your existing Node.JS application multithreaded.

newjxcore

Note: mt-keep:4 means that the process will scale up to 4 threads. It’s up to you to define the best configuration for your servers.

JXcore also includes a proprietary packaging system putting all the sources, assets and dependencies into a single file. This makes JX load faster, consume less heap memory and be easy to deploy.

Here is a list of benefits when using JXcore:

  • Achieves multithreading simply by running your application on JXCore;
  • Built-in status aware process monitoring, specifically designed for server applications;
  • Significant performance gains over Node.JS and Node.JS Cluster as suggested by internal benchmarks;
  • Shares the http server load on the native C++ side instead V8 VM (Cluster handles the communication on V8 VM);
  • Multithreaded and isolated V8 instances keep V8 GC affecting the responsiveness of the whole process;
  • Small memory footprint compared to Node Cluster;
  • Automated deployment of Multiple processes with multiple threads behind an auto managed NGINX;
  • Secured JavaScript code on the server.

Why We Created JXcore

Early in 2013, we decided to extend our proprietary .NET based messaging technology and add features for turning it into a light-weight, easy-to-deploy mobile Backend-as-a-Service (mBaaS) platform. We had developed the core technology and expertise by collaborating with many customers in several different projects. But we didn’t want to restrict the server logic to .NET Framework languages only. Since one of the goals of this whole effort was to extend the usage to the largest number of developers, the idea of JavaScript development on both client and server side fit perfectly with our overall philosophy.

Node.JS was identified as a great option due to its simplicity, speed of development, active user community, as well as our previous experience with Google’s V8. Despite all these advantages, we had some concerns with overall consistency and efficiency.

Multithreading

Lack of multithreading was the biggest challenge. Not being able to utilize all cores on the servers was a big concern. The closest we could come was Node’s cluster module. This approach required a small update to define what would be done in the main process and its forks. The main process manages the load using fork processes. It can also recover forks when they are closed unexpectedly. It provides a basic level of control over processes and can utilize multiple cores. But there were still number of issues that could not be resolved with the cluster module:

  • The host process is not aware of the load on forks;
  • Forks are only useful when the host process is functioning;
  • Expensive memory usage;
  • Duplication of the whole process without optimizing the usage (waste of CPU cycles);
  • Inconsistent behavior on Windows compared to *ix platforms.

Running Node.JS in multiple contexts helps native add-ons switching between separate V8 contexts. Indeed, this feature is quite useful for the scenarios requiring context safety. On the other hand, it surely has a performance impact on the entire application. Switching among the V8 contexts has no benefit with the heap limits or performance numbers. The solution is still limited to a single thread. While some people recommend a single thread as beneficial, our internal tests showed that switching to multithreaded isolates brought more than 45% solid performance improvements. We developed our backend solution as single thread in mind but used our multithreaded Node.JS distribution to attain benefits from all the available cores.

Packaging & Code Security

Based on our past experience, most enterprise customers require offline installation without online dependencies. Considering the current package manager of Node.JS, we needed to implement a fully featured packaging tool that would keep all the dependencies together without requiring extra steps. We also wanted to provide a framework so that we could allow our developers to monetize their add-on work.

Modifying Node.JS

We were either going to accept the limitations of Node.JS with respect to our project or choose a different development platform. We decided to work on Node’s core library and see if we could change it enough to meet our requirements. We also knew that there was an attempt in the past by Node’s core contributors to make it multithreaded but it was abandoned.

After months of extensive development in Node’s core libraries and dependencies, we have achieved what we had set out to do. Unfortunately, the addition of our requirements called for major architectural changes in Node. The result was a major fork on Node project that we named JXcore. However, we are committed to keeping JXCore 100% compatible with all other Node.JS modules that work with the latest version of Node.JS available.

What’s Next with JXcore?

JXcore is close to meeting our initial requirements compared to Node.JS. It has multithreading support which allowed us to handle more requests on a multicore server than Node.JS. It also allowed us to meet enterprise deployment needs and protect proprietary JavaScript server modules.

We also released JXcore to the community as a free product.  Any Node.JS 0.12+ project can benefit from everything JXcore offers without any modifications. Moreover, projects using JXcore will directly benefit from the features on our roadmap. One of the major features in the pipeline that we are excited about is replacing Goggle V8 engine with LLVM (formerly Low Level Virtual Machine). Applications using JIT compilation (like V8) are not accepted to the Apple App Store and similar market stores which limits the usage of Node.JS projects being published as mobile apps.  However, JXcore with LLVM will enable JavaScript programmers to develop desktop applications as well as cross platform native (high performance) mobile and embedded apps.

You can download and try JXCore here.

Modern Web Newsletter

Subscribe to receive the Modern Web tutorials, sent out every second Wednesday.

Top