Threads without efforts in Odi (Node.js)
Tags: typescript, node, javascript, opensource
Published: 2019-02-05 15:48:31

---
title: Threads without efforts in Odi (Node.js)
published: true
cover_image: https://thepracticaldev.s3.amazonaws.com/i/6owov9uocp56t7g6kjvw.png
description: New features, some magic and plans
canonical_url: https://hackernoon.com/odi-threads-8bb9c3c94f6a
tags: #typescript, #node, #javascript, #opensource
---

## Introduction

Multithreading is a process of executing two or more threads simultaneously.The most programming languages provide an API for convenient work with threads and parallelism. The developer can focus on application logic, not on the communication channel, synchronization or architecture setup.

**Node 10.5** added support for `worker_threads` module with an experimental flag. But starting from **Node 11.7** this feature is available out of the box. It’s a good start for multithreading paradigm in Node.

`worker_threads` has a huge potential, so support for this module was added to Odi from early stages. As always, Odi goal is to provide convenient, clean and minimalistic API (with magic 🧙‍♂️), so developers can focus on development, not on setup.

## Project Setup

From the last article, Odi got new CLI command which initializes project,
defines scripts and installs all required dependencies.

```bash
    odi init
```

Currently, there are only a few options:
```bash
    -j, --jsx-templating  add jsx templates
    -d, --database        add typeorm integration
```
### Structure

By default, the project will have the following structure.

![](https://cdn-images-1.medium.com/max/800/1*rM0JN4xIll0-ZkYHi2-9Jw.png)

All required dependencies will be installed during command execution based on the template type. Also if `-j` flag was provided, **views** folder will be added in the project root directory.

### Source Files

There are 2 predefined source files in the basic template.

The `index.ts` file that contains basic Odi configuration. By default, the
server port is set to `8080`

{% gist https://gist.github.com/DanTsk/bd6104794962b6472212da0802aa39d3 %}

And the `home.controller.ts` file with a simple controller definition.

{% gist https://gist.github.com/DanTsk/7c36555197ab9327418e2a05a85f0b7a %}

That’s enough to start with Odi and development.

### Scripts

For now, the only `npm start` script is available out of the box. In the next
release, `npm test` command will be available using Mocha and Chai.

Simply run the following command
```bash
    npm start
```
This script includes compilation and actual running, so after completion, you can easily open the browser and check `http://localhost:8080` URL.

![](https://cdn-images-1.medium.com/max/800/1*r57qiTH3VLPszvUJit3S2g.png)


## Threads

By design, Node is single threaded with non-blocking I/O. Such approach has many pros and cons. The main advantage is simplicity. The developer does not need to care about threads manipulations, data synchronization and etc. But any resource-intensive tasks will block the event loop.

Worker threads can process resource-intensive operations, so the main thread is always available. It’s really important for Server-Side applications, as any blocking task will delay accepting and processing of new client requests.


### Task

Let’s create the resource-intensive (blocking) function for getting an answer
(*Yes* or *No*) based on random values generation.

{% gist https://gist.github.com/DanTsk/da0f1802a6a7d0fec2f7993daa7c5f93 %}

Mathematical operations in most cases CPU intensive, so it’s a great example for our goals. Running this function with `200_000_000` factor takes ~**5 sec** for execution.

### Blocking

As mentioned above, any blocking operation won’t allow other tasks to execute until it’s finished.

The best way to understand blocking is UI. Let’s add simple CLI loader to our application using `Ora` library, just for example.

First of all, we need to install it.

```bash
    npm install ora @types/ora
```

And change the Controller method in the following way. When the handler is triggered, the loader will appear in the terminal and will be spinning until our calculations are finished. Also, the time that was used for request processing will be printed.

{% gist https://gist.github.com/DanTsk/ddfcd7215926160e77b9ce3e72d5b1fd %}

Let’s start our server and trigger handler from the browser.

![](https://cdn-images-1.medium.com/max/800/1*ngdqa4ZF_i26RfR2PS3plA.gif)

The loader is not spinning, as our calculation blocked the process. The loader must have the possibility to re-render frames every `80` milliseconds but can’t do it, as the event loop is blocked by `getAnswer` call.

### Consequences

Let’s imagine that we have this code in the real application. The handler will block accepting and processing new clients requests. It will seriously affect the client experience. Such operations must be placed into other application or in the other thread.

## Workers

Odi provides convenient API for multithreading. The developer does not need to think about any type of setup.

### Definition

It’s really easy to define `Worker` in Odi application and container. There are
some similarities with `Service` definition. Let’s wrap `getAnswer` function.

{% gist https://gist.github.com/DanTsk/8d5bdaa436535f25fa7e7c42300d207e %}

Only `Worker` decorator is required for definition. Now we can inject it in the
controller as other dependencies.

{% gist https://gist.github.com/DanTsk/4752f0a290bbc9b638246026afc19dfa %}

Note, `await` keyword must be added before the worker method call, even if it’s not async, as communication between threads is done in an asynchronous way.

That’s all! 🧙‍♂️ The method will be executed in another thread and the result will be returned to the main.

### Review

Now, example with UI loader can be tested.

![](https://cdn-images-1.medium.com/max/800/1*5vuSyhjwYUO5jS9T3ZX7OQ.gif)

Everything is working. The loader is spinning, as the code is running in another thread, so UI can re-render frames.

### Check

To be sure that the method was processed in another thread, simply change `getAnswer` in the next way.

Information about thread will be available right in the console.

### Comparison

As you can see above, zero configuration is required for workes setup and processing.No event emitters, event handlers, filename and etc are required like in the official [example](https://nodejs.org/api/worker_threads.html#worker_threads_worker_threads). Odi cares about initialization, messaging, method calls and errors handling.

### Limitations

There are no limitations in addition to basic ones. Remember that the worker is something like another application, so runtime instances can’t be accessed between different threads. Also, **Dependency Injection** container can’t be accessed over the threads, so every single thread will have its own container.

## Use Cases

Basically, workers threads can be used in next approaches:

1.  Background and scheduled tasks
2.  Resource-intensive operations
3.  Queue-based processing

Those approaches can be easily improved and adapted for each particular need, but all of them leads to performance improvements and application flexibility.

## More


Thanks for reading! Feel free to [leave](https://odi.nolt.io/) any feedback, ideas or questions.

If you like Odi, simply support us with start on GitHub. 🌟✨
{% github odi-ts/odi %}

Keep reading, much more interesting things will be shipped in the next updates!
😉🧙‍♂️