napajs icon indicating copy to clipboard operation
napajs copied to clipboard

How to share object between workers (include mutating object members)

Open Meigyoku-Thmn opened this issue 7 years ago • 1 comments

I tried to save an object into store, for example, the simple-quadtree lib:

var napa = require("napajs");
var zone = napa.zone.create('zone', { workers: 4});
var QuadTree = require('simple-quadtree');
var qt = QuadTree(0, 0, 100, 100);
var store = napa.store.create('my-store');
store.set('qt', qt);
let a = store.get('qt'); // empty object
a.put({x: 0, y: 0, w: 4, h: 4}); // other workers would do this too

or a simple object created from class:

class ABC {
   constructor() {
      console.log(1);
      this.a = 1;
      this.b = 7;
   }
   abc() {
      console.log();
   }
}
var sharedObject = new ABC();
var store = napa.store.create('my-store');
store.set('obj', sharedObject);
let a = store.get('obj'); // empty object
a.a = 2; // other workers would do this too

store.get() always return an empty object. According to the documentation, only Transportable types can be stored, but I don't know how to make a transportable object, the documentation don't show a specific way of how to do this.

Meigyoku-Thmn avatar Dec 20 '17 07:12 Meigyoku-Thmn

Values in store must be transportable, that means for user classes (TypeScript translates private members into closure so JSON.stringify cannot output them), you need to implement Transportable interface, a simple way is to extend TransportableObject.

in your case, you can try this:

import * as napa from 'napajs'

@napa.transport.cid('<guid-for-ABC>')
class ABC extends napa.transport.TransportableObject{
    private a: number;
    private b: number;

    constructor() {
      super();
      console.log(1);
      this.a = 1;
      this.b = 7;
    }
    save(payload: object): void {
        payload['a'] = this.a;
        payload['b'] = this.b;
    }

    load(payload: object): void {
        this.a = payload['a'];
        this.b = payload['b'];
    }

    abc() {
        console.log(`ABC: ${this.a}, ${this.b}`);
    }
}

let store = napa.store.create('s1');
store.set('key', new ABC());
let abc: ABC = store.get('key');
abc.abc();

It should print:

1
1
ABC: 1, 7

BTW, in order to compile the TypeScript, you need to add flag experimentalDecorators to compilerOptions.

daiyip avatar Dec 20 '17 13:12 daiyip