git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: 07c0df717b109d015093957f1176a824fe29d25a

Files: 07c0df717b109d015093957f1176a824fe29d25a / index.js

3469 bytesRaw
1const Graph = require('ipld-graph-builder')
2const ExoInterface = require('./exoInterface.js')
3
4module.exports = class Hypervisor {
5 /**
6 * The Hypervisor manages the container instances by instantiating them and
7 * destorying them when possible. It also facilitates localating Containers
8 * @param {Graph} dag an instance of [ipfs.dag](https://github.com/ipfs/interface-ipfs-core/tree/master/API/dag#dag-api)
9 */
10 constructor (dag) {
11 this.graph = new Graph(dag)
12 this._runningContainers = new Map()
13 this._containerTypes = {}
14 }
15
16 async getByPath (root, path) {
17 path = path.split('/')
18 for (const name of path) {
19 const portRef = root.ports.get(name)
20 root = await this.getOrCreateInstance(portRef, root.entryPort)
21 }
22 return root
23 }
24
25 /**
26 * get a contrainer instance given its entry port and its mounting port
27 * @param {Object} port the entry port for the container
28 * @param {Object} parentPort the entry port of the parent container
29 */
30 async getOrCreateInstance (port, parentPort) {
31 let instance = this._runningContainers.get(port)
32 // if there is no container running crceate one
33 if (!instance) {
34 instance = await this.createInstance(port.type, port.link, port, parentPort)
35 instance.on('idle', () => {
36 // once the container is done shut it down
37 this._runningContainers.delete(port)
38 })
39 }
40 return instance
41 }
42
43 /**
44 * given a port, wait untill its source contract has reached the threshold
45 * tick count
46 * @param {Object} port the port to wait on
47 * @param {Number} threshold the number of ticks to wait before resolving
48 * @param {Object} fromPort the entryPort of the container requesting the
49 * wait. Used internally so that waits don't become cyclic
50 */
51 async wait (port, threshold, fromPort) {
52 let instance = this._runningContainers.get(port)
53 if (instance) {
54 return instance.wait(threshold, fromPort)
55 } else {
56 return threshold
57 }
58 }
59
60 /**
61 * creates an instance given the container type, starting state, entry port
62 * and the parentPort
63 * @param {String} the type of VM to load
64 * @param {Object} the starting state of the VM
65 * @param {Object} the entry port
66 * @param {Object} the parent port
67 */
68 async createInstance (type, state, entryPort = null, parentPort) {
69 const Container = this._containerTypes[type]
70
71 if (!state) {
72 state = {
73 '/': Container.createState()
74 }
75 }
76
77 // create a new kernel instance
78 const exoInterface = new ExoInterface({
79 entryPort: entryPort,
80 parentPort: parentPort,
81 hypervisor: this,
82 state: state,
83 Container: Container
84 })
85
86 // save the newly created instance
87 this._runningContainers.set(entryPort, exoInterface)
88 await exoInterface.start()
89 return exoInterface
90 }
91
92 /**
93 * creates a state root starting from a given container and a given number of
94 * ticks
95 * @param {Container} container an container instance
96 * @param {Number} ticks the number of ticks at which to create the state root
97 */
98 async createStateRoot (container, ticks) {
99 await container.wait(ticks)
100 return this.graph.flush(container.state)
101 }
102
103 /**
104 * regirsters a container with the hypervisor
105 * @param {String} the name of the type
106 * @param {Class} a Class for instantiating the container
107 */
108 registerContainer (type, vm) {
109 this._containerTypes[type] = vm
110 }
111}
112

Built with git-ssb-web