git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: d386ffea54d493af4f2eb1eeadc633dd579cdbe3

Files: d386ffea54d493af4f2eb1eeadc633dd579cdbe3 / actor.js

2907 bytesRaw
1const Pipe = require('buffer-pipe')
2const leb128 = require('leb128').unsigned
3
4module.exports = class Actor {
5 /**
6 * the Actor manages the varous message passing functions and provides
7 * an interface for the containers to use
8 * @param {Object} opts
9 * @param {Object} opts.id - the UUID of the Actor
10 * @param {Object} opts.state - the state of the container
11 * @param {Object} opts.hypervisor - the instance of the hypervisor
12 * @param {Object} opts.container - the container constuctor and argments
13 */
14 constructor (opts) {
15 Object.assign(this, opts)
16
17 this.inbox = []
18 this.ticks = 0
19 this.running = false
20 }
21
22 serializeMetaData () {
23 return Actor.serializeMetaData(this.type, this.nonce)
24 }
25
26 getFuncRef (name) {
27 return {
28 name,
29 destId: this.id
30 }
31 }
32
33 /**
34 * Runs the shutdown routine for the actor
35 */
36 async shutdown () {
37 await this.state.done()
38 this.state.root['/'][3] = this.serializeMetaData()
39 }
40
41 /**
42 * Runs the startup routine for the actor
43 */
44 async startup () {
45 this.instance = await this.container.instance(this)
46 }
47
48 /**
49 * run the Actor with a given message
50 * @param {object} message - the message to run
51 * @param {String} method - which method to run
52 * @returns {Promise}
53 */
54 async runMessage (message) {
55 if (message._fromTicks > this.ticks) {
56 this.ticks = message._fromTicks
57 }
58 try {
59 this.currentMessage = message
60 await this.instance.exports[message.funcRef.name](...message.funcArguments)
61 } catch (e) {
62 message.emit('execution:error', e)
63 }
64 message.emit('done')
65 }
66
67 /**
68 * updates the number of ticks that the actor has run
69 * @param {Number} count - the number of ticks to add
70 */
71 incrementTicks (count) {
72 this.ticks += count
73 }
74
75 /**
76 * creates an actor
77 * @param {Integer} type - the type id for the container
78 * @param {Object} message - an intial [message](https://github.com/primea/js-primea-message) to send newly created actor
79 */
80 createActor (type, code) {
81 const id = this._generateNextId()
82 return this.hypervisor.createActor(type, code, id)
83 }
84
85 _generateNextId () {
86 const id = {
87 nonce: this.nonce,
88 parent: this.id
89 }
90
91 this.nonce++
92 return id
93 }
94
95 /**
96 * sends a message to a given port
97 * @param {Object} portRef - the port
98 * @param {Message} message - the message
99 */
100 send (message) {
101 message._fromTicks = this.ticks
102 message._fromId = this.id
103
104 this.hypervisor.scheduler.queue([message])
105 }
106
107 static serializeMetaData (type, nonce = 0) {
108 const p = new Pipe()
109 leb128.write(type, p)
110 leb128.write(nonce, p)
111 return p.buffer
112 }
113
114 static deserializeMetaData (buffer) {
115 const pipe = new Pipe(buffer)
116 const type = leb128.read(pipe)
117 const nonce = leb128.read(pipe)
118 return {
119 nonce,
120 type
121 }
122 }
123}
124

Built with git-ssb-web