API Namespace transport

12 篇文章 0 订阅

原文链接:https://github.com/Microsoft/napajs/blob/master/docs/api/transport.md

Namespace transport

Table of Contents

  • Introduction

    • Transportable types
    • Constructor ID
    • Transport context
    • Transporting functions
  • API

    • isTransportable(jsValue: any): boolean
    • register(transportableClass: new(...args: any[]) => any): void
    • marshall(jsValue: any, context: TransportContext): string
    • unmarshall(json: string, context: TransporteContext): any
    • class TransportContext
      • context.saveShared(object: memory.Shareable): void
      • context.loadShared(handle: memory.Handle): memory.Shareable
      • context.sharedCount: number
    • interface Transportable
      • transportable.cid: string
      • transportable.marshall(context: TransportContext): object
      • transportable.unmarshall(payload: object, context: TransportContext): void
    • abstract class TransportableObject
      • transportableObject.cid: string
      • transportableObject.marshall(context: TransportContext): object
      • transportableObject.unmarshall(payload: object, context: TransportContext): void
      • abstract transportableObject.save(payload: object, context: TransportContext): void
      • abstract transportableObject.load(payload: object, context: TransportContext): void
    • decorator cid

介绍

已有的JavaScript引擎不支持在多个虚拟机之间运行JavaScript,也就是说每一个虚拟机单独管理自己的堆栈。虚拟机之间传递的数据必须被封装和拆封。载荷的大小和对象的复杂度将严重影响通信效率。而在Napa中,我们尝试设计一种模式高效的实现对象共享,而这种模式是基于JavaScript虚拟机(也就是worker)都位于同一个进程,而且原生对象能够被封装成JavaScripts对象对外暴露。

为实现这个模式而引入了下面这些概念:

可传递类型

可传递类型是JavaScript类型中可以在Napa worker间被显式地传递和分享的数据类型。它们作为值类型传递给broadcast和execute的入参,也通过set和get方法共享键值对对象。

可传递类型是:

  • JavaScript 原始类型:null,boolean,number,string
  • 实现了可传递接口的对象
  • 数组或由上述类型组成的简单JavaScript对象
  • 未引用闭包的方法

构造函数ID (cid)

对于实现了可传递接口的用户自定义类,Napa从字符串载荷中使用构造函数ID(cid)来查找构造函数创建正确的对象。cid被封装后作为有效载荷的一部分。在解封时,传输层会提取到cid并调用相关的构造函数创建对象实例,然后在这个对象上调用解封函数。

开发者为自定义的类选择合适的cid,为避免冲突,建议使用模块id和类名的组合作为cid。在使用带有装饰器功能的TypeScript时,开发者可以使用类装饰器cid自动注册用户可传递类。或者在模块初始化时手动调用transport.register来将用户自定义的类注册为可传递类。

传递上下文

因为有多种不能以序列化形式保存和加载的状态(比如std::shared_ptr),或者序列化是非常低效的(比如JavaScript方法)。引入传递上下文来解决这些问题。传递上下文对象可以在JavaScript虚拟机之间传递,也可以存储在本地内存,可以通过使用传递上下文延长共享的本地对象的生命周期。通过可传递上下文实现的可传递实例是可共享包。

传递方法

通过将它的定义封装在store里,JavaScript 方法就成了特殊的可传递类型,可以在目标线程上生成一个新方法。

可传递函数的重点是:

对同一个函数,在每个JavaScript线程上只做一次封装/解封。一旦一个方法已经被传递进来了,后续同一个函数被再次传入之前的JavaScript线程将不再耗费资源。 闭包不能被传递,但当传递的是一个函数时不会报错。实际上,当你在后续使用传入的这个方法时,会抛出运行时错误提示来自闭包里的一个变量未定义。

在传入的方法中可以访问到 __dirname / __filename,这是由方法的origin属性所决定的。默认的origin属性被设置为当前工作路径。

API

isTransportable(jsValue: any): boolean

该方法可以区别一个JavaScript值是否是可传递类型。

// JS primitives
assert(transport.isTransportable(undefined));
assert(transport.isTransportable(null));
assert(transport.isTransportable(1));
assert(transport.isTransportable('string'));
assert(transport.isTransportable(true));

// Transportable addon
assert(transport.isTransportable(napa.memory.crtAllocator));

// Composite of transportable types.
assert(transport.isTransportable([
    1, 
    "string", 
    { a: napa.memory.crtAllocator }
    ]));

class B {
    field1: number;
    field2: string;
}

// Not transportable JS class. (not registered with @cid).
assert(!transport.isTransportable(new B()));

register(transportableClass: new(...args: any[]) => any): void

该方法可以在传输层封装/解封类的实例之前将该类注册成一个可传输类。用户也可以使用类装饰器@cid注册类。 例如: class A extends transport.AutoTransportable { field1: string, method1(): string { return this.field1; } }

// Explicitly register class A in transport.
transport.register(A);

marshall(jsValue: any, context: TransportContext): string

该方法将JavaScript 值根据其TransportContext封装到JSON载荷中。如果该值不可传递,则会抛错。 例如: var context = transport.createTransportContext(); var jsonPayload = transport.marshall( [1, 'string', napa.memory.crtAllocator], context); console.log(jsonPayload);

unmarshall(json: string, context: TransportContext): any

该方法根据TransportContext将JSON载荷解封装为可传递的JavaScript值。如果cid属性存在但没有在传输层注册,则将会抛错。 例如: var value = transport.unmarshall(jsonPayload, context);

TransportContext类

在封装/解封期间,可传递上下文类存储了已共享的指针和方法。

context.saveShared(object: memory.Shareable): void

保存可共享对象

context.loadShared(handle: memory.Handle): memory.Shareable

加载上下文可共享的对象

context.sharedCount: number

统计当前上下文的可共享对象数量。

Transportable 接口

可传递对象的接口

transportable.cid: string

该接口可以访问 Constructor ID。用来查看当前当前类的载荷的构造器。

transportable.marshall(context: TransportContext): object

在TransportContext的协助下,将对象被封装转化成一个简单的JavaScript对象。

transportable.unmarshall(payload: object, context: TransportContext): void

将已封装的载荷解封转化成当前对象。

TransportableObject抽象类

TBD

装饰器 cid

TBD


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值