Files: 4b635551d20b7713c297b8e2e30ac37c8b830837 / index.js
2267 bytesRaw
1 | const Graph = require('ipld-graph-builder') |
2 | const multibase = require('multibase') |
3 | const Kernel = require('./kernel.js') |
4 | |
5 | module.exports = class Hypervisor { |
6 | constructor (opts) { |
7 | this.graph = new Graph(opts.dag) |
8 | this._vmInstances = new Map() |
9 | this._VMs = {} |
10 | } |
11 | |
12 | async getInstance (port) { |
13 | let id = await this.generateID(port) |
14 | let kernel = this._vmInstances.get(id) |
15 | if (!kernel) { |
16 | // load the container from the state |
17 | await this.graph.tree(port, 2) |
18 | const parentID = await this.generateID(port.id['/'].parent) |
19 | const parentKernel = await this._vmInstances.get(parentID) |
20 | const parentPort = parentKernel.entryPort |
21 | |
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 | } |
29 | } |
30 | return kernel |
31 | } |
32 | |
33 | // given a port, wait untill its source contract has reached the threshold |
34 | // tick count |
35 | async wait (port, threshold) { |
36 | let kernel = await this.getInstance(port) |
37 | return kernel.wait(threshold) |
38 | } |
39 | |
40 | async createInstance (type, state, entryPort, parentPort) { |
41 | const VM = this._VMs[type] |
42 | if (!state) { |
43 | state = VM.createState() |
44 | } |
45 | // create a new kernel instance |
46 | const kernel = new Kernel({ |
47 | entryPort: entryPort, |
48 | parentPort: parentPort, |
49 | hypervisor: this, |
50 | state: state, |
51 | VM: VM |
52 | }) |
53 | |
54 | const id = await this.generateID(entryPort) |
55 | this._vmInstances.set(id, kernel) |
56 | await kernel.start() |
57 | return kernel |
58 | } |
59 | |
60 | /** |
61 | * opts.entryPort |
62 | * opts.parentPort |
63 | */ |
64 | createInstanceFromPort (entryPort, parentPort) { |
65 | const state = entryPort.link['/'] |
66 | return this.createInstance(entryPort.type, state, entryPort, parentPort) |
67 | } |
68 | |
69 | async createStateRoot (container, ticks) { |
70 | await container.wait(ticks) |
71 | return this.graph.flush(container.state) |
72 | } |
73 | |
74 | async generateID (port) { |
75 | if (!port || !port.id) { |
76 | return null |
77 | } |
78 | let id = await this.graph.flush(port.id) |
79 | id = id['/'] |
80 | if (Buffer.isBuffer(id)) { |
81 | id = multibase.encode('base58btc', id).toString() |
82 | } |
83 | return id |
84 | } |
85 | |
86 | registerContainer (type, vm) { |
87 | this._VMs[type] = vm |
88 | } |
89 | } |
90 |
Built with git-ssb-web