Files: c091abb0870d405499f6c16a44b7e83135f443d2 / index.js
2058 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, createIfNotFound, parentPort) { |
13 | const id = await this.generateID(port) |
14 | let kernel = this._vmInstances.get(id) |
15 | if (!kernel && createIfNotFound) { |
16 | // load the the ID from the merkle store |
17 | await this.graph.tree(port.id, 1) |
18 | |
19 | kernel = await this.createInstance(port.type, port.link, port, parentPort) |
20 | kernel.on('idle', () => { |
21 | this._vmInstances.delete(id) |
22 | }) |
23 | } |
24 | return kernel |
25 | } |
26 | |
27 | // given a port, wait untill its source contract has reached the threshold |
28 | // tick count |
29 | async wait (port, threshold, fromPort) { |
30 | let kernel = await this.getInstance(port, false) |
31 | if (kernel) { |
32 | return kernel.wait(threshold, fromPort) |
33 | } else { |
34 | return threshold |
35 | } |
36 | } |
37 | |
38 | async createInstance (type, state, entryPort = null, parentPort) { |
39 | const VM = this._VMs[type] |
40 | |
41 | if (!state) { |
42 | state = { |
43 | '/': VM.createState() |
44 | } |
45 | } |
46 | |
47 | // create a new kernel instance |
48 | const kernel = new Kernel({ |
49 | entryPort: entryPort, |
50 | parentPort: parentPort, |
51 | hypervisor: this, |
52 | state: state, |
53 | VM: VM |
54 | }) |
55 | |
56 | const id = await this.generateID(entryPort) |
57 | // save the newly created instance |
58 | this._vmInstances.set(id, kernel) |
59 | await kernel.start() |
60 | return kernel |
61 | } |
62 | |
63 | async createStateRoot (container, ticks) { |
64 | await container.wait(ticks) |
65 | return this.graph.flush(container.state) |
66 | } |
67 | |
68 | async generateID (port) { |
69 | if (!port || !port.id) { |
70 | return null |
71 | } |
72 | |
73 | let id = Object.assign({}, port.id) |
74 | id = await this.graph.flush(id) |
75 | id = id['/'] |
76 | if (Buffer.isBuffer(id)) { |
77 | id = multibase.encode('base58btc', id).toString() |
78 | } |
79 | return id |
80 | } |
81 | |
82 | registerContainer (type, vm) { |
83 | this._VMs[type] = vm |
84 | } |
85 | } |
86 |
Built with git-ssb-web