Skip to content
This repository has been archived by the owner on Jun 13, 2024. It is now read-only.

Introduction

Daiyi Peng edited this page Jul 25, 2017 · 4 revisions

Following concepts are essential to understand how Napa.js works.

Zone

In Napa.js, all works related to multi-threading are around the concept of Zone, which is the basic unit to define policies and execute JavaScript code. A process may contain multiple zones, each consists of multiple JavaScript Workers.

Architecture

Within a zone, all workers are symmetrical: they load the same code, serve broadcast and execute requests in an indistinguishable manner. Basically, you cannot ask a zone to execute code on a specific worker. Workers across different zones are asymmetrical: they may load different code, or load the same code but reinforce different policies, like heap size, security settings, etc. Applications may need multiple zones for work loads of different purposes or different policies.

There are 2 types of zone:

  • Napa zone - zone consists of Napa.js managed JavaScript workers (V8 isolates). Can be multiple, each may contain multiple workers. Workers in Napa zone support partial Node.JS APIs.
  • Node zone - a 'virtual' zone which exposes Node.js eventloop, has access to full Node.js capabilities.

This complex enables you to use Napa zone for heavy-lifting work, and Node zone for IO. Node zone also compensates Napa zone on its incomplete support of Node APIs.

Transporting JavaScript values

V8 is not designed for running JavaScript across multiple isolates, which means every isolate manages their own heap. Passing values from one isolate to another has to be marshalled/unmarshalled. The size of payload and complexity of object will greatly impact communication efficiency. In Napa, we try to work out a design pattern for efficient object sharing, based on the fact that all JavaScript isolates (exposed as workers) reside in the same process, and native objects can be wrapped and exposed as JavaScripts objects.

Following concepts are introduced to implement this pattern:

Transportable types

Transportable types are JavaScript types that can be passed or shared transparently across workers. They are used as value types for passing arguments in broadcast and execute, as well as sharing objects in key/value pairs via set and get.

Transportable types are:

  • JavaScript primitive types: null, boolean, number, string
  • Object (TypeScript class) that implement Transportable interface
  • Array or plain JavaScript object that is composite pattern of above.
  • Single JavaScript value undefined

Cross-worker Storage

Store API is introduced as a necessary complement of sharing transportable types across JavaScript workers, on top of passing objects via arguments. During store.set, values marshalled into JSON and stored in process heap, so all threads can access it, and unmarshalled while users retrieve them via store.get.

Though very convenient, it's not recommended to use store to pass values within a transaction or request, since its overhead is more than passing objects by arguments (there are extra locking, etc.). Besides, developers have the obligation to delete the key after usage, while it's automatically managed by reference counting in passing arguments.

Clone this wiki locally