该文章介绍的概念对于理解Napa.js如何工作非常重要。想了解它的起源可以读这篇文章。
在Napa.js中,与多线程相关的工作都围绕Zone概念展开,它是定义 策略 和执行JavaScript代码的基本单元。一个程序包含多个zone,每一个zone包含多个JavaScript worker。

在一个zone中,所有的worker都是相等的的:它们以相同的方式加载同样的代码、为broadcast和execute请求服务。基本上,你无法指定zone中一个特定的worker来执行代码。不同zone之间的worker是不相等的:它们加载不同的代码,或者即使加载相同的代码也会使用不同的策略,比如堆的大小、安全策略的配置等。应用需要多个zone来完成不同目的或者不同策略的工作负载。
有两种类型的zone:
这种方式使你能够使用Napa zone来做繁重的计算任务,同时使用Node zone 来操作IO事务。Node zone也弥补了Napa zone对Node APIs支持不完整的不足。
下面的代码创建了一个包含8个worker的Napa zone:
var napa = require('napajs');var zone = napa.zone.create('sample-zone', { workers: 8 });下面的代码说明如何访问Node zone:
var zone = napa.zone.node;
在zone上可以执行两种操作:
Zone的操作都是基于“先进先出”原则,而且broadcast拥有比execute更高的优先级。
下面的代码说明了如何使用broadcast和execute来完成一个简单的任务:
function foo() { console.log('hi');} // This setups function definition of foo in all workers in the zone.zone.broadcast(foo.toString()); // This execute function foo on an arbitrary worker.zone.execute(() => { global.foo() });V8不是被设计用于在多个isolate之间执行JavaScript程序,也就意味着每个isolate管理各自拥有的堆栈。从一个isolate到另一个isolate之间传递的数据必须被封装和解封(marshalled/unmarshalled)。有效载荷的大小和对象的复杂度对isolate间的通信效率影响很大。在Napa中,我们尝试找到一个可实现对象高效共享的设计模式,它是基于所有的JavaScript isolate(也就是worker)都位于相同的进程中,而且原生对象能够被封装成JavaScripts对象对外暴露。
下面是为了实现该设计模式而引入的概念:
可传递类型是JavaScript类型中可以在Napa worker间被显式地传递和分享的数据类型。它们作为值类型传递给broadcast和execute的入参,也通过set和get方法共享键值对对象。
可传递类型是:
在通过参数传递数据方面,存储API的引入是对JavaScript worker 间共享可传递类型的必要补充。调用store.set,值按顺序以 JSON 的形式存入进程堆,因此所有的线程都可以访问它,而且用户可以通过调用store.get来得到这些值。
下面的代码展示了如何使用store来共享对象:
var napa = require('napajs'); var zone = napa.zone.create('zone1');var store = napa.store.create('store1'); // Set 'key1' in node.store.set('key1', { a: 1, b: "2", c: napa.memory.crtAllocator // transportable complex type.}; // Get 'key1' in another thread.zone.execute(() => { var store = global.napa.store.get('store1'); console.log(store.get('key1'));});尽管非常方便,但是在事务处理和请求时不推荐使用存储,因为它的消耗比通常传参要大(会额外带着锁等信息)。此外,虽然有垃圾回收机制,但是开发者还应该在使用完后删除key。
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删