Commit 463dc84f2cfff964ba0c0ea55de6f903a4f344a3
clean up state managment
wanderer committed on 5/7/2017, 5:12:44 PMParent: acc114f061e4e4c2cbede55a72d008b7e46c5cbc
Files changed
index.js | changed |
kernel.js | changed |
portManager.js | changed |
tests/index.js | changed |
index.js | ||
---|---|---|
@@ -12,21 +12,18 @@ | ||
12 | 12 | async getInstance (port) { |
13 | 13 | let id = await this.generateID(port) |
14 | 14 | let kernel = this._vmInstances.get(id) |
15 | 15 | if (!kernel) { |
16 | - // load the container from the state | |
17 | - await this.graph.tree(port, 3) | |
16 | + // load the the ID from the merkle store | |
17 | + await this.graph.tree(port.id, 1) | |
18 | 18 | const parentID = await this.generateID({id: port.id['/'].parent}) |
19 | 19 | const parentKernel = await this._vmInstances.get(parentID) |
20 | 20 | const parentPort = parentKernel.entryPort |
21 | 21 | |
22 | 22 | kernel = await this.createInstanceFromPort(port, parentPort) |
23 | - // don't delete the root contracts | |
24 | - if (id) { | |
25 | - kernel.on('idle', () => { | |
26 | - this._vmInstances.delete(id) | |
27 | - }) | |
28 | - } | |
23 | + kernel.on('idle', () => { | |
24 | + this._vmInstances.delete(id) | |
25 | + }) | |
29 | 26 | } |
30 | 27 | return kernel |
31 | 28 | } |
32 | 29 | |
@@ -39,10 +36,13 @@ | ||
39 | 36 | |
40 | 37 | async createInstance (type, state, entryPort = null, parentPort) { |
41 | 38 | const VM = this._VMs[type] |
42 | 39 | if (!state) { |
43 | - state = VM.createState() | |
40 | + state = { | |
41 | + '/': VM.createState() | |
42 | + } | |
44 | 43 | } |
44 | + | |
45 | 45 | // create a new kernel instance |
46 | 46 | const kernel = new Kernel({ |
47 | 47 | entryPort: entryPort, |
48 | 48 | parentPort: parentPort, |
@@ -51,8 +51,9 @@ | ||
51 | 51 | VM: VM |
52 | 52 | }) |
53 | 53 | |
54 | 54 | const id = await this.generateID(entryPort) |
55 | + // save the newly created instance | |
55 | 56 | this._vmInstances.set(id, kernel) |
56 | 57 | await kernel.start() |
57 | 58 | return kernel |
58 | 59 | } |
@@ -61,9 +62,9 @@ | ||
61 | 62 | * opts.entryPort |
62 | 63 | * opts.parentPort |
63 | 64 | */ |
64 | 65 | async createInstanceFromPort (entryPort, parentPort) { |
65 | - const state = entryPort.link['/'] | |
66 | + const state = entryPort.link | |
66 | 67 | return this.createInstance(entryPort.type, state, entryPort, parentPort) |
67 | 68 | } |
68 | 69 | |
69 | 70 | async createStateRoot (container, ticks) { |
kernel.js | ||
---|---|---|
@@ -15,9 +15,9 @@ | ||
15 | 15 | // create the port manager |
16 | 16 | this.ports = new PortManager({ |
17 | 17 | kernel: this, |
18 | 18 | hypervisor: opts.hypervisor, |
19 | - ports: opts.state.ports, | |
19 | + state: opts.state, | |
20 | 20 | entryPort: opts.entryPort, |
21 | 21 | parentPort: opts.parentPort |
22 | 22 | }) |
23 | 23 | |
@@ -53,18 +53,23 @@ | ||
53 | 53 | this.emit(vmState, message) |
54 | 54 | } |
55 | 55 | |
56 | 56 | async _runNextMessage () { |
57 | - const message = await this.ports.getNextMessage() | |
58 | - // if the vm is paused and it gets a message; save that message for use when the VM is resumed | |
59 | - if (message && this.vmState === 'paused') { | |
60 | - this.ports._portMap(message._fromPort).unshfit(message) | |
61 | - } else if (!message && this.vmState !== 'paused') { | |
62 | - // if no more messages then shut down | |
63 | - this._updateVmState('idle') | |
64 | - } else { | |
65 | - // run the next message | |
66 | - this._run(message) | |
57 | + console.log('run next message') | |
58 | + try { | |
59 | + const message = await this.ports.getNextMessage() | |
60 | + // if the vm is paused and it gets a message; save that message for use when the VM is resumed | |
61 | + if (message && this.vmState === 'paused') { | |
62 | + this.ports._portMap(message._fromPort).unshfit(message) | |
63 | + } else if (!message && this.vmState !== 'paused') { | |
64 | + // if no more messages then shut down | |
65 | + this._updateVmState('idle') | |
66 | + } else { | |
67 | + // run the next message | |
68 | + this._run(message) | |
69 | + } | |
70 | + } catch (e) { | |
71 | + console.log(e) | |
67 | 72 | } |
68 | 73 | } |
69 | 74 | |
70 | 75 | _updateEntryPort (entryPort) { |
@@ -141,13 +146,14 @@ | ||
141 | 146 | |
142 | 147 | async createPort (type, name) { |
143 | 148 | const VM = this.hypervisor._VMs[type] |
144 | 149 | const parentId = this.entryPort ? this.entryPort.id : null |
150 | + let nonce = await this.hypervisor.graph.get(this.state, 'nonce') | |
145 | 151 | const portRef = { |
146 | 152 | 'messages': [], |
147 | 153 | 'id': { |
148 | 154 | '/': { |
149 | - nonce: this.state.nonce, | |
155 | + nonce: nonce, | |
150 | 156 | parent: parentId |
151 | 157 | } |
152 | 158 | }, |
153 | 159 | 'type': type, |
@@ -158,11 +164,11 @@ | ||
158 | 164 | |
159 | 165 | // create the port instance |
160 | 166 | await this.ports.set(name, portRef) |
161 | 167 | // incerment the nonce |
162 | - const nonce = new BN(this.state.nonce) | |
168 | + nonce = new BN(nonce) | |
163 | 169 | nonce.iaddn(1) |
164 | - this.state.nonce = nonce.toArray() | |
170 | + this.state['/'].nonce = nonce.toArray() | |
165 | 171 | return portRef |
166 | 172 | } |
167 | 173 | |
168 | 174 | async send (portRef, message) { |
portManager.js | ||
---|---|---|
@@ -30,15 +30,16 @@ | ||
30 | 30 | } |
31 | 31 | |
32 | 32 | async start () { |
33 | 33 | // map ports to thier id's |
34 | - let ports = Object.keys(this.ports).map(name => { | |
34 | + this.ports = await this.hypervisor.graph.get(this.state, 'ports') | |
35 | + const promises = Object.keys(this.ports).map(name => { | |
35 | 36 | const port = this.ports[name] |
36 | 37 | this._mapPort(name, port) |
37 | 38 | }) |
38 | 39 | |
39 | 40 | // create the parent port |
40 | - await Promise.all(ports) | |
41 | + await Promise.all(promises) | |
41 | 42 | // skip the root, since it doesn't have a parent |
42 | 43 | if (this.parentPort !== undefined) { |
43 | 44 | const id = await this.hypervisor.generateID(this.parentPort) |
44 | 45 | this._portMap.set(id, new Port(ENTRY)) |
tests/index.js | ||
---|---|---|
@@ -53,9 +53,11 @@ | ||
53 | 53 | }) |
54 | 54 | |
55 | 55 | tape('one child contract', async t => { |
56 | 56 | let message = new Message() |
57 | - const expectedState = { '/': 'zdpuAqtY43BMaTCB5nTt7kooeKAWibqGs44Uwy9jJQHjTnHRK' } | |
57 | + const expectedState = { | |
58 | + '/': 'zdpuAtYQujwQMR9SpmFwmkr7d2cD4vzeQk2GCzcEku2nomWj6' | |
59 | + } | |
58 | 60 | let hasResolved = false |
59 | 61 | |
60 | 62 | class testVMContainer2 extends BaseContainer { |
61 | 63 | run (m) { |
@@ -71,53 +73,49 @@ | ||
71 | 73 | } |
72 | 74 | |
73 | 75 | class testVMContainer extends BaseContainer { |
74 | 76 | async run (m) { |
75 | - // console.log('here', this.kernel.entryPort) | |
76 | 77 | const port = await this.kernel.createPort('test2', 'child') |
77 | - try { | |
78 | - await this.kernel.send(port, m) | |
79 | - } catch (e) { | |
80 | - console.log('error!', e) | |
81 | - } | |
78 | + await this.kernel.send(port, m) | |
82 | 79 | this.kernel.incrementTicks(1) |
83 | 80 | } |
84 | 81 | } |
85 | 82 | |
83 | + const hypervisor = new Hypervisor({dag: node.dag}) | |
84 | + hypervisor.registerContainer('test', testVMContainer) | |
85 | + hypervisor.registerContainer('test2', testVMContainer2) | |
86 | + | |
87 | + let root = await hypervisor.createInstance('test') | |
88 | + let port = await root.createPort('test', 'first') | |
89 | + | |
90 | + await root.send(port, message) | |
91 | + const stateRoot = await hypervisor.createStateRoot(root, Infinity) | |
92 | + t.true(hasResolved, 'should resolve before generating the state root') | |
93 | + t.deepEquals(stateRoot, expectedState, 'expected state') | |
94 | + | |
95 | + // test reviving the state | |
96 | + class testVMContainer3 extends BaseContainer { | |
97 | + async run (m) { | |
98 | + const port = this.kernel.getPort('child') | |
99 | + this.kernel.send(port, m) | |
100 | + this.kernel.incrementTicks(1) | |
101 | + } | |
102 | + } | |
103 | + | |
86 | 104 | try { |
87 | - const hypervisor = new Hypervisor({dag: node.dag}) | |
88 | - hypervisor.registerContainer('test', testVMContainer) | |
89 | - hypervisor.registerContainer('test2', testVMContainer2) | |
105 | + hypervisor.registerContainer('test', testVMContainer3) | |
106 | + root = await hypervisor.createInstance('test', stateRoot) | |
107 | + port = await root.ports.getRef('first') | |
90 | 108 | |
91 | - const root = await hypervisor.createInstance('test') | |
92 | - const port = await root.createPort('test', 'first') | |
93 | - | |
94 | 109 | await root.send(port, message) |
110 | + console.log('creating SR') | |
95 | 111 | await hypervisor.createStateRoot(root, Infinity) |
96 | - console.log('state root generated') | |
97 | - t.true(hasResolved, 'should resolve before generating the state root') | |
112 | + console.log('end!') | |
113 | + // console.log(hypervisor._vmInstances) | |
98 | 114 | } catch (e) { |
99 | 115 | console.log(e) |
100 | 116 | } |
101 | - // t.deepEquals(port, expectedState, 'expected state') | |
102 | 117 | |
103 | - // test reviving the state | |
104 | - // class testVMContainer3 extends BaseContainer { | |
105 | - // async run (m) { | |
106 | - // const port = this.kernel.getPort(this.kernel.ports, 'child') | |
107 | - // this.kernel.send(port, m) | |
108 | - // this.kernel.incrementTicks(1) | |
109 | - // } | |
110 | - // } | |
111 | - | |
112 | - // hypervisor.addVM('test', testVMContainer3) | |
113 | - | |
114 | - // // revive ports | |
115 | - // message = new Message() | |
116 | - // await hypervisor.graph.tree(expectedState, 1) | |
117 | - // await hypervisor.send(expectedState['/'], message) | |
118 | - // await hypervisor.createStateRoot(expectedState['/'], Infinity) | |
119 | - | |
120 | 118 | t.end() |
121 | 119 | }) |
122 | 120 | |
123 | 121 | tape.skip('should wait on parent', async t => { |
Built with git-ssb-web