git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: 85e4fb4229773cb638ebe9e8f193c4837521baf3

Files: 85e4fb4229773cb638ebe9e8f193c4837521baf3 / actor.js

3272 bytesRaw
1const errors = require('./errors.json')
2const nope = () => {}
3const debug = require('debug')('lifecycle:error')
4
5module.exports = class Actor {
6 /**
7 * the Actor manages the various message passing functions and provides
8 * an interface for the containers to use
9 * @param {Object} opts
10 * @param {ID} opts.id - the UUID of the Actor
11 * @param {Object} opts.module - the module this actor was created from
12 * @param {Object} opts.state - the state of the module
13 * @param {Object} opts.storage - the actor's persistent storage
14 * @param {Object} opts.hypervisor - the instance of the hypervisor
15 * @param {Number} opts.nonce
16 * @param {Function} opts.Container - the module constructor and arguments
17 */
18 constructor (opts) {
19 Object.assign(this, opts)
20
21 this.ticks = 0
22 this.running = false
23 this.container = new this.Container(this)
24 if (!this.hypervisor.meter) {
25 this.incrementTicks = nope
26 }
27 }
28
29 /**
30 * Runs the shutdown routine for the actor
31 */
32 shutdown () {
33 // saves the nonce and storage to the state
34 this.state.value[1] = this.nonce
35 this.state.node[2] = {'/': this.storage}
36 }
37
38 /**
39 * Runs the startup routine for the actor
40 */
41 startup () {
42 return this.container.onStartup()
43 }
44
45 /**
46 * run the Actor with a given message
47 * @param {object} message - the message to run
48 * @param {String} method - which method to run
49 * @returns {Promise}
50 */
51 async runMessage (message) {
52 if (message._fromTicks > this.ticks) {
53 this.ticks = message._fromTicks
54 }
55 try {
56 this.currentMessage = message
57 await this.container.onMessage(message)
58 } catch (e) {
59 debug(e)
60 message.emit('execution:error', e)
61 }
62 message.emit('done', this)
63 }
64
65 /**
66 * updates the number of ticks that the actor has run
67 * @param {Number} count - the number of ticks to add
68 */
69 incrementTicks (count) {
70 this.currentMessage.funcRef.gas -= count
71 if (this.currentMessage.funcRef.gas < 0) {
72 throw new Error(errors.OUT_OF_GAS)
73 }
74 this.ticks += count
75 }
76
77 /**
78 * creates an actor from a module and code
79 * @param {Module} mod - the module
80 * @param {Buffer} code - the code
81 * @return {ActorRef}
82 */
83 newActor (mod, code) {
84 const modRef = this.createModule(mod, code)
85 return this.createActor(modRef)
86 }
87
88 /**
89 * creates a modref from a module and code
90 * @param {Module} mod - the module
91 * @param {Buffer} code - the code
92 * @return {ModuleRef}
93 */
94 createModule (mod, code) {
95 const id = this._generateNextId()
96 return this.hypervisor.createModule(mod, code, id)
97 }
98
99 /**
100 * creates an actor from a modref
101 * @param {ModuleRef} modRef - the modref
102 * @return {ActorRef}
103 */
104 createActor (modRef) {
105 const id = this._generateNextId()
106 return this.hypervisor.createActor(modRef, id)
107 }
108
109 _generateNextId () {
110 const id = {
111 nonce: this.nonce,
112 parent: this.id
113 }
114
115 this.nonce++
116 return id
117 }
118
119 /**
120 * sends a message
121 * @param {Message} message - the message
122 */
123 send (message) {
124 message._fromTicks = this.ticks
125 message._fromId = this.id
126
127 this.incrementTicks(message.funcRef.gas)
128 this.hypervisor.scheduler.queue([message])
129 }
130}
131

Built with git-ssb-web