git ssb

0+

wanderer🌟 / js-primea-hypervisor



Commit d2f195c509c6bd320e14ede5acde3dcc6370530f

Merge pull request #133 from primea/chunker

added chunking for code stored in the state
wanderer authored on 7/27/2017, 11:05:34 PM
GitHub committed on 7/27/2017, 11:05:34 PM
Parent: 6723a3ab125343529593a107313cd31c8eb38d7a
Parent: 88bcb9d3485311c1a0878dbe733373a1e5750698

Files changed

index.jschanged
kernel.jschanged
package.jsonchanged
tests/index.jschanged
index.jsView
@@ -2,11 +2,10 @@
22 const Message = require('primea-message')
33 const Kernel = require('./kernel.js')
44 const Scheduler = require('./scheduler.js')
55 const DFSchecker = require('./dfsChecker.js')
6+const chunk = require('chunk')
67
7-const ROOT_ID = 'zdpuAm6aTdLVMUuiZypxkwtA7sKm7BWERy8MPbaCrFsmiyzxr'
8-
98 module.exports = class Hypervisor {
109 /**
1110 * The Hypervisor manages the container instances by instantiating them and
1211 * destorying them when possible. It also facilitates localating Containers
@@ -18,8 +17,11 @@
1817 this.scheduler = new Scheduler()
1918 this.state = state
2019 this._containerTypes = {}
2120 this._nodesToCheck = new Set()
21+
22+ this.ROOT_ID = 'zdpuAm6aTdLVMUuiZypxkwtA7sKm7BWERy8MPbaCrFsmiyzxr'
23+ this.MAX_DATA_BYTES = 65533
2224 }
2325
2426 /**
2527 * add a potaintail node in the state graph to check for garbage collection
@@ -56,13 +58,24 @@
5658 // loads an instance of a container from the state
5759 async _loadInstance (id) {
5860 const state = await this.graph.get(this.state, id)
5961 const container = this._containerTypes[state.type]
62+ let code
6063
64+ // checks if the code stored in the state is an array and that the elements
65+ // are merkle link
66+ if (state.code && state.code[0]['/']) {
67+ await this.graph.tree(state.code, 1)
68+ code = state.code.map(a => a['/']).reduce((a, b) => a + b)
69+ } else {
70+ code = state.code
71+ }
72+
6173 // create a new kernel instance
6274 const kernel = new Kernel({
6375 hypervisor: this,
6476 state: state,
77+ code: code,
6578 container: container,
6679 id: id
6780 })
6881
@@ -114,16 +127,28 @@
114127 ports: {},
115128 type: type
116129 }
117130
131+ if (message.data.length) {
132+ state.code = message.data
133+ }
134+
118135 // save the container in the state
119136 await this.graph.set(this.state, idHash, state)
120137 // create the container instance
121138 const instance = await this._loadInstance(idHash)
122139 resolve(instance)
123140 // send the intialization message
124141 await instance.initialize(message)
125142
143+ if (state.code && state.code.length > this.MAX_DATA_BYTES) {
144+ state.code = chunk(state.code, this.MAX_DATA_BYTES).map(chk => {
145+ return {
146+ '/': chk
147+ }
148+ })
149+ }
150+
126151 return instance
127152 }
128153
129154 /**
@@ -133,9 +158,9 @@
133158 * @returns {Promise}
134159 */
135160 async createStateRoot (ticks) {
136161 await this.scheduler.wait(ticks)
137- const unlinked = await DFSchecker(this.graph, this.state, ROOT_ID, this._nodesToCheck)
162+ const unlinked = await DFSchecker(this.graph, this.state, this.ROOT_ID, this._nodesToCheck)
138163 unlinked.forEach(id => {
139164 delete this.state[id]
140165 })
141166 return this.graph.flush(this.state)
kernel.jsView
@@ -14,8 +14,9 @@
1414 * @param {Object} opts.container - the container constuctor and argments
1515 */
1616 constructor (opts) {
1717 this.state = opts.state
18+ this.code = opts.code
1819 this.hypervisor = opts.hypervisor
1920 this.id = opts.id
2021 this.container = new opts.container.Constructor(this, opts.container.args)
2122 this.timeout = 0
package.jsonView
@@ -31,10 +31,11 @@
3131 "license": "MPL-2.0",
3232 "dependencies": {
3333 "binary-search-insert": "^1.0.3",
3434 "bn.js": "^4.11.6",
35+ "chunk": "0.0.2",
3536 "ipld-graph-builder": "1.2.2",
36- "primea-abstract-container": "0.0.1",
37+ "primea-abstract-container": "0.0.2",
3738 "primea-message": "0.0.1"
3839 },
3940 "devDependencies": {
4041 "coveralls": "^2.13.1",
tests/index.jsView
@@ -1,7 +1,8 @@
11 const tape = require('tape')
22 const IPFS = require('ipfs')
33 const AbstractContainer = require('primea-abstract-container')
4+const Message = require('primea-message')
45 const Hypervisor = require('../')
56
67 // start ipfs
78 const node = new IPFS({
@@ -1070,5 +1071,19 @@
10701071
10711072 rootContainer.send(portRef1, message)
10721073 rootContainer.ports.bind('response', rPort)
10731074 })
1075+
1076+ tape('large code size', async t => {
1077+ t.plan(1)
1078+ const content = Buffer.from(new ArrayBuffer(1000000))
1079+ class testVMContainer extends BaseContainer {
1080+ run () {}
1081+ }
1082+
1083+ const hypervisor = new Hypervisor(node.dag)
1084+ hypervisor.registerContainer('test', testVMContainer)
1085+ await hypervisor.createInstance('test', new Message({data: content}))
1086+ const instance = await hypervisor.getInstance(hypervisor.ROOT_ID)
1087+ t.equals(content.length, instance.code.length)
1088+ })
10741089 })

Built with git-ssb-web