git ssb

0+

wanderer🌟 / js-primea-hypervisor



Commit 158d5b428af69e19901680edef92ece0a876a97c

add drivers

wanderer committed on 3/21/2018, 11:27:12 PM
Parent: 8cd3e3af7c391f083f5f83593a260f831c7083af

Files changed

index.jschanged
scheduler.jschanged
systemObjects.jschanged
tests/index.jschanged
wasmContainer.jschanged
egressDriver.jsadded
index.jsView
@@ -1,25 +1,26 @@
1+const crypto = require('crypto')
12 const Actor = require('./actor.js')
23 const Scheduler = require('./scheduler.js')
34 const {ID} = require('./systemObjects.js')
4-const crypto = require('crypto')
55
66 module.exports = class Hypervisor {
77 /**
88 * The Hypervisor manages the container instances by instantiating them and
99 * destorying them when possible. It also facilitates localating Containers
1010 * @param {Tree} tree - a [radix tree](https://github.com/dfinity/js-dfinity-radix-tree) to store the state
1111 */
12- constructor (tree, nonce = 0) {
12+ constructor (tree, containers = [], drivers = [], nonce = 0) {
1313 this.tree = tree
1414 this.scheduler = new Scheduler(this)
1515 this._containerTypes = {}
1616 this.nonce = nonce
17+ containers.forEach(container => this.registerContainer(container))
18+ drivers.forEach(driver => this.registerDriver(driver))
1719 }
1820
1921 /**
2022 * sends a message
21- * @param {Object} cap - the capabilitly used to send the message
2223 * @param {Object} message - the [message](https://github.com/primea/js-primea-message) to send
2324 * @returns {Promise} a promise that resolves once the receiving container is loaded
2425 */
2526 send (messages) {
@@ -119,8 +120,12 @@
119120 */
120121 registerContainer (Constructor) {
121122 this._containerTypes[Constructor.typeId] = Constructor
122123 }
124+
125+ registerDriver (driver) {
126+ this.scheduler.drivers.set(driver.id.id.toString('hex'), driver)
127+ }
123128 }
124129
125130 function encodedID (id) {
126131 const nonce = Buffer.from([id.nonce])
scheduler.jsView
@@ -21,8 +21,9 @@
2121 this.hypervisor = hypervisor
2222 this._messages = []
2323 this._times = []
2424 this.actors = new Map()
25+ this.drivers = new Map()
2526 this._running = false
2627 }
2728
2829 queue (messages) {
@@ -47,9 +48,9 @@
4748 }
4849
4950 async _processMessage (message) {
5051 const to = message.funcRef.destId.id.toString('hex')
51- let actor = this.actors.get(to)
52+ let actor = this.actors.get(to) || this.drivers.get(to)
5253 if (!actor) {
5354 actor = await this.hypervisor.loadActor(message.funcRef.destId)
5455 this.actors.set(to, actor)
5556 }
systemObjects.jsView
@@ -19,9 +19,9 @@
1919 const decoder = new cbor.Decoder({
2020 tags: {
2121 [TAGS.id]: val => new ID(val),
2222 [TAGS.func]: val => new FunctionRef(...val),
23- [TAGS.mod]: val => new ModuleRef(...val),
23+ [TAGS.mod]: val => new ModuleRef(...val)
2424 }
2525 })
2626
2727 class Serializable {
@@ -36,17 +36,18 @@
3636 }
3737 }
3838
3939 class FunctionRef extends Serializable {
40- constructor (privateFunc, identifier, params, id, gas=0) {
40+ constructor (opts) {
4141 super()
42- this.private = privateFunc
43- this.identifier = identifier
44- if (!(id instanceof ID))
45- id = new ID(id)
46- this.destId = id
47- this.params = params
48- this.gas = gas
42+ this.private = opts.private
43+ this.identifier = opts.identifier
44+ if (!(opts.id instanceof ID)) {
45+ opts.id = new ID(opts.id)
46+ }
47+ this.destId = opts.id
48+ this.params = opts.params
49+ this.gas = opts.gas
4950 }
5051
5152 encodeCBOR (gen) {
5253 return gen.write(new cbor.Tagged(TAGS.func, [
@@ -69,9 +70,14 @@
6970 this.id = id
7071 }
7172
7273 getFuncRef (name) {
73- return new FunctionRef(false, name, this.exports[name], this.id)
74+ return new FunctionRef({
75+ private: false,
76+ identifier: name,
77+ params: this.exports[name],
78+ id: this.id
79+ })
7480 }
7581
7682 encodeCBOR (gen) {
7783 return gen.write(new cbor.Tagged(TAGS.mod, [this.exports, this.id]))
tests/index.jsView
@@ -1,9 +1,11 @@
11 const tape = require('tape')
22 const Message = require('../message.js')
33 const Hypervisor = require('../')
4+const {FunctionRef} = require('../systemObjects')
45
56 const level = require('level-browserify')
7+const EgressDriver = require('../egressDriver')
68 const RadixTree = require('dfinity-radix-tree')
79 const db = level('./testdb')
810
911 class BaseContainer {
@@ -44,11 +46,9 @@
4446 t.equals(m, 1, 'should recive a message')
4547 }
4648 }
4749
48- const hypervisor = new Hypervisor(tree)
49- hypervisor.registerContainer(testVMContainer)
50-
50+ const hypervisor = new Hypervisor(tree, [testVMContainer])
5151 const {module} = hypervisor.createActor(testVMContainer.typeId)
5252
5353 const message = new Message({
5454 funcRef: module.main,
@@ -89,11 +89,9 @@
8989 return 8
9090 }
9191 }
9292
93- const hypervisor = new Hypervisor(tree)
94- hypervisor.registerContainer(testVMContainerA)
95- hypervisor.registerContainer(testVMContainerB)
93+ const hypervisor = new Hypervisor(tree, [testVMContainerA, testVMContainerB])
9694
9795 const {module: moduleB} = hypervisor.createActor(testVMContainerB.typeId)
9896 const {module: moduleA} = hypervisor.createActor(testVMContainerA.typeId)
9997
@@ -137,11 +135,9 @@
137135 return 8
138136 }
139137 }
140138
141- const hypervisor = new Hypervisor(tree)
142- hypervisor.registerContainer(testVMContainerA)
143- hypervisor.registerContainer(testVMContainerB)
139+ const hypervisor = new Hypervisor(tree, [testVMContainerA, testVMContainerB])
144140
145141 let {module: moduleB} = hypervisor.createActor(testVMContainerB.typeId)
146142 let {module: moduleA0} = hypervisor.createActor(testVMContainerA.typeId)
147143 let {module: moduleA1} = hypervisor.createActor(testVMContainerA.typeId)
@@ -193,11 +189,9 @@
193189 return 8
194190 }
195191 }
196192
197- const hypervisor = new Hypervisor(tree)
198- hypervisor.registerContainer(testVMContainerA)
199- hypervisor.registerContainer(testVMContainerB)
193+ const hypervisor = new Hypervisor(tree, [testVMContainerA, testVMContainerB])
200194
201195 let actorB = hypervisor.createActor(testVMContainerB.typeId)
202196 let actorA0 = hypervisor.createActor(testVMContainerA.typeId)
203197 let actorA1 = hypervisor.createActor(testVMContainerA.typeId)
@@ -511,8 +505,40 @@
511505 const stateRoot = await hypervisor.createStateRoot()
512506 t.deepEquals(stateRoot, expectedState, 'expected root!')
513507 })
514508
509+tape('driver', async t => {
510+ const tree = new RadixTree({
511+ db
512+ })
513+
514+ const egress = new EgressDriver()
515+
516+ egress.on('message', msg => {
517+ t.equals(msg.funcArguments[0], 'hello')
518+ t.end()
519+ })
520+
521+ class testVMContainer extends BaseContainer {
522+ main (funcRef) {
523+ this.actor.send(new Message({
524+ funcRef,
525+ funcArguments: ['hello']
526+ }))
527+ }
528+ }
529+
530+ const hypervisor = new Hypervisor(tree, [testVMContainer], [egress])
531+ const {module} = hypervisor.createActor(testVMContainer.typeId)
532+
533+ const message = new Message({
534+ funcRef: module.main,
535+ funcArguments: [new FunctionRef({id: egress.id})]
536+ })
537+
538+ hypervisor.send(message)
539+})
540+
515541 tape('random', async t => {
516542 const numOfActors = 10
517543 const depth = 10
518544 const messageOrder = {}
wasmContainer.jsView
@@ -30,10 +30,8 @@
3030 }
3131 const message = new Message({
3232 funcRef: self,
3333 funcArguments: checkedArgs
34- }).on('execution:error', e => {
35- console.log(e)
3634 })
3735 container.actor.send(message)
3836 }
3937 }
@@ -90,9 +88,14 @@
9088 // externalize a pervously internalized function
9189 return self.refs.add(object)
9290 } else {
9391 const params = self.json.types[self.json.indexes[func.name - FUNC_INDEX_OFFSET]].params
94- const ref = new FunctionRef(true, func.tableIndex, params, self.actor.id)
92+ const ref = new FunctionRef({
93+ private: true,
94+ identifier: func.tableIndex,
95+ params,
96+ id: self.actor.id
97+ })
9598 return self.refs.add(ref, 'func')
9699 }
97100 },
98101 internalize: (index, ref) => {
@@ -123,9 +126,8 @@
123126 unwrap: async (ref, cb) => {
124127 const obj = this.refs.get(ref, 'link')
125128 const promise = this.actor.tree.dataStore.get(obj)
126129 await this._opsQueue.push(promise)
127- // todo
128130 }
129131 },
130132 module: {
131133 new: dataRef => {
egressDriver.jsView
@@ -1,0 +1,13 @@
1+const {ID} = require('./systemObjects')
2+const EventEmitter = require('events')
3+
4+module.exports = class Egress extends EventEmitter {
5+ constructor () {
6+ super()
7+ this.id = new ID(Buffer.from([0]))
8+ }
9+
10+ runMessage (message) {
11+ this.emit('message', message)
12+ }
13+}

Built with git-ssb-web