git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: 420c091edd500452248946f7f519a3f0bd7b3a3e

Files: 420c091edd500452248946f7f519a3f0bd7b3a3e / index.js

2468 bytesRaw
1const Graph = require('ipld-graph-builder')
2const multibase = require('multibase')
3const Kernel = require('./kernel.js')
4
5module.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 = true) {
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 const parentID = await this.generateID({id: 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 kernel.id = id
24 kernel.on('idle', () => {
25 this._vmInstances.delete(id)
26 })
27 }
28 return kernel
29 }
30
31 // given a port, wait untill its source contract has reached the threshold
32 // tick count
33 async wait (port, threshold, fromPort) {
34 let kernel = await this.getInstance(port, false)
35 if (kernel) {
36 return kernel.wait(threshold, fromPort)
37 } else {
38 return threshold
39 }
40 }
41
42 async createInstance (type, state, entryPort = null, parentPort) {
43 const VM = this._VMs[type]
44 if (!state) {
45 state = {
46 '/': VM.createState()
47 }
48 }
49
50 // create a new kernel instance
51 const kernel = new Kernel({
52 entryPort: entryPort,
53 parentPort: parentPort,
54 hypervisor: this,
55 state: state,
56 VM: VM
57 })
58
59 const id = await this.generateID(entryPort)
60 // save the newly created instance
61 this._vmInstances.set(id, kernel)
62 await kernel.start()
63 return kernel
64 }
65
66 /**
67 * opts.entryPort
68 * opts.parentPort
69 */
70 async createInstanceFromPort (entryPort, parentPort) {
71 const state = entryPort.link
72 return this.createInstance(entryPort.type, state, entryPort, parentPort)
73 }
74
75 async createStateRoot (container, ticks) {
76 await container.wait(ticks)
77 return this.graph.flush(container.state)
78 }
79
80 async generateID (port) {
81 if (!port || !port.id) {
82 return null
83 }
84 let id = Object.assign({}, port.id)
85 id = await this.graph.flush(id)
86 id = id['/']
87 if (Buffer.isBuffer(id)) {
88 id = multibase.encode('base58btc', id).toString()
89 }
90 return id
91 }
92
93 registerContainer (type, vm) {
94 this._VMs[type] = vm
95 }
96}
97

Built with git-ssb-web