Commit f0fbf4a220a3041e504eb1b75fc6e6e2e9488ad6
clean up
wanderer committed on 7/27/2017, 10:12:35 PMParent: e08047273f81b45b7107bc0bc4fa2557d9f79eb0
Files changed
index.js | changed |
kernel.js | changed |
package.json | changed |
tests/index.js | changed |
index.js | ||
---|---|---|
@@ -3,12 +3,9 @@ | ||
3 | 3 | const Kernel = require('./kernel.js') |
4 | 4 | const Scheduler = require('./scheduler.js') |
5 | 5 | const DFSchecker = require('./dfsChecker.js') |
6 | 6 | const chunk = require('chunk') |
7 | -const flatten = require('flatten') | |
8 | 7 | |
9 | -const ROOT_ID = 'zdpuAm6aTdLVMUuiZypxkwtA7sKm7BWERy8MPbaCrFsmiyzxr' | |
10 | - | |
11 | 8 | module.exports = class Hypervisor { |
12 | 9 | /** |
13 | 10 | * The Hypervisor manages the container instances by instantiating them and |
14 | 11 | * destorying them when possible. It also facilitates localating Containers |
@@ -21,9 +18,10 @@ | ||
21 | 18 | this.state = state |
22 | 19 | this._containerTypes = {} |
23 | 20 | this._nodesToCheck = new Set() |
24 | 21 | |
25 | - this.MAX_DATA_BYTES = 6553 | |
22 | + this.ROOT_ID = 'zdpuAm6aTdLVMUuiZypxkwtA7sKm7BWERy8MPbaCrFsmiyzxr' | |
23 | + this.MAX_DATA_BYTES = 65533 | |
26 | 24 | } |
27 | 25 | |
28 | 26 | /** |
29 | 27 | * add a potaintail node in the state graph to check for garbage collection |
@@ -60,17 +58,22 @@ | ||
60 | 58 | // loads an instance of a container from the state |
61 | 59 | async _loadInstance (id) { |
62 | 60 | const state = await this.graph.get(this.state, id) |
63 | 61 | const container = this._containerTypes[state.type] |
62 | + let code | |
64 | 63 | |
65 | - // if (state.code && Array.isArray(state.code[0])) { | |
66 | - // state.code = flatten(state.code) | |
67 | - // } | |
64 | + if (state.code && state.code[0]['/']) { | |
65 | + await this.graph.tree(state.code, 1) | |
66 | + code = state.code.map(a => a['/']).reduce((a, b) => a + b) | |
67 | + } else { | |
68 | + code = state.code | |
69 | + } | |
68 | 70 | |
69 | 71 | // create a new kernel instance |
70 | 72 | const kernel = new Kernel({ |
71 | 73 | hypervisor: this, |
72 | 74 | state: state, |
75 | + code: code, | |
73 | 76 | container: container, |
74 | 77 | id: id |
75 | 78 | }) |
76 | 79 | |
@@ -95,8 +98,9 @@ | ||
95 | 98 | return instance |
96 | 99 | } else { |
97 | 100 | const resolve = this.scheduler.getLock(id) |
98 | 101 | const instance = await this._loadInstance(id) |
102 | + await instance.startup() | |
99 | 103 | resolve(instance) |
100 | 104 | return instance |
101 | 105 | } |
102 | 106 | } |
@@ -122,8 +126,12 @@ | ||
122 | 126 | ports: {}, |
123 | 127 | type: type |
124 | 128 | } |
125 | 129 | |
130 | + if (message.data.length) { | |
131 | + state.code = message.data | |
132 | + } | |
133 | + | |
126 | 134 | // save the container in the state |
127 | 135 | await this.graph.set(this.state, idHash, state) |
128 | 136 | // create the container instance |
129 | 137 | const instance = await this._loadInstance(idHash) |
@@ -136,10 +144,8 @@ | ||
136 | 144 | return { |
137 | 145 | '/': chk |
138 | 146 | } |
139 | 147 | }) |
140 | - } else { | |
141 | - console.log(state.code) | |
142 | 148 | } |
143 | 149 | |
144 | 150 | return instance |
145 | 151 | } |
@@ -151,13 +157,12 @@ | ||
151 | 157 | * @returns {Promise} |
152 | 158 | */ |
153 | 159 | async createStateRoot (ticks) { |
154 | 160 | await this.scheduler.wait(ticks) |
155 | - const unlinked = await DFSchecker(this.graph, this.state, ROOT_ID, this._nodesToCheck) | |
161 | + const unlinked = await DFSchecker(this.graph, this.state, this.ROOT_ID, this._nodesToCheck) | |
156 | 162 | unlinked.forEach(id => { |
157 | 163 | delete this.state[id] |
158 | 164 | }) |
159 | - console.log(this.state) | |
160 | 165 | return this.graph.flush(this.state) |
161 | 166 | } |
162 | 167 | |
163 | 168 | /** |
kernel.js | ||
---|---|---|
@@ -14,8 +14,9 @@ | ||
14 | 14 | * @param {Object} opts.container - the container constuctor and argments |
15 | 15 | */ |
16 | 16 | constructor (opts) { |
17 | 17 | this.state = opts.state |
18 | + this.code = opts.code | |
18 | 19 | this.hypervisor = opts.hypervisor |
19 | 20 | this.id = opts.id |
20 | 21 | this.container = new opts.container.Constructor(this, opts.container.args) |
21 | 22 | this.timeout = 0 |
@@ -72,10 +73,13 @@ | ||
72 | 73 | } |
73 | 74 | |
74 | 75 | shutdown () { |
75 | 76 | this.hypervisor.scheduler.done(this.id) |
76 | - if (this.container.shutdown) { | |
77 | - this.container.shutdown() | |
77 | + } | |
78 | + | |
79 | + startup () { | |
80 | + if (this.container.startup) { | |
81 | + return this.container.startup() | |
78 | 82 | } |
79 | 83 | } |
80 | 84 | |
81 | 85 | /** |
package.json | ||
---|---|---|
@@ -32,9 +32,8 @@ | ||
32 | 32 | "dependencies": { |
33 | 33 | "binary-search-insert": "^1.0.3", |
34 | 34 | "bn.js": "^4.11.6", |
35 | 35 | "chunk": "0.0.2", |
36 | - "flatten": "^1.0.2", | |
37 | 36 | "ipld-graph-builder": "1.2.2", |
38 | 37 | "primea-abstract-container": "0.0.1", |
39 | 38 | "primea-message": "0.0.1" |
40 | 39 | }, |
tests/index.js | ||
---|---|---|
@@ -1,7 +1,8 @@ | ||
1 | 1 | const tape = require('tape') |
2 | 2 | const IPFS = require('ipfs') |
3 | 3 | const AbstractContainer = require('primea-abstract-container') |
4 | +const Message = require('primea-message') | |
4 | 5 | const Hypervisor = require('../') |
5 | 6 | |
6 | 7 | // start ipfs |
7 | 8 | const node = new IPFS({ |
@@ -1070,5 +1071,34 @@ | ||
1070 | 1071 | |
1071 | 1072 | rootContainer.send(portRef1, message) |
1072 | 1073 | rootContainer.ports.bind('response', rPort) |
1073 | 1074 | }) |
1075 | + | |
1076 | + tape('start up', async t => { | |
1077 | + t.plan(1) | |
1078 | + class testVMContainer extends BaseContainer { | |
1079 | + run () {} | |
1080 | + startup () { | |
1081 | + t.true(true, 'should start up') | |
1082 | + } | |
1083 | + } | |
1084 | + | |
1085 | + const hypervisor = new Hypervisor(node.dag) | |
1086 | + hypervisor.registerContainer('test', testVMContainer) | |
1087 | + await hypervisor.createInstance('test') | |
1088 | + hypervisor.getInstance(hypervisor.ROOT_ID) | |
1089 | + }) | |
1090 | + | |
1091 | + tape('large code size', async t => { | |
1092 | + t.plan(1) | |
1093 | + const content = Buffer.from(new ArrayBuffer(1000000)) | |
1094 | + class testVMContainer extends BaseContainer { | |
1095 | + run () {} | |
1096 | + } | |
1097 | + | |
1098 | + const hypervisor = new Hypervisor(node.dag) | |
1099 | + hypervisor.registerContainer('test', testVMContainer) | |
1100 | + await hypervisor.createInstance('test', new Message({data: content})) | |
1101 | + const instance = await hypervisor.getInstance(hypervisor.ROOT_ID) | |
1102 | + t.equals(content.length, instance.code.length) | |
1103 | + }) | |
1074 | 1104 | }) |
Built with git-ssb-web