git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: a977e58eb3a89178bf97c0a5b20a7172be8c9b5f

Files: a977e58eb3a89178bf97c0a5b20a7172be8c9b5f / index.js

3239 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 /**
17 * get a contrainer instance given its entry port and its mounting port
18 * @param {Object} port the entry port for the container
19 * @param {Object} parentPort the entry port of the parent container
20 */
21 async getOrCreateInstance (port, parentPort) {
22 let instance = this._runningContainers.get(port)
23 // if there is no container running crceate one
24 if (!instance) {
25 instance = await this.createInstance(port.type, port.link, port, parentPort)
26 instance.on('idle', () => {
27 // once the container is done shut it down
28 this._runningContainers.delete(port)
29 })
30 }
31 return instance
32 }
33
34 /**
35 * given a port, wait untill its source contract has reached the threshold
36 * tick count
37 * @param {Object} port the port to wait on
38 * @param {Number} threshold the number of ticks to wait before resolving
39 * @param {Object} fromPort the entryPort of the container requesting the
40 * wait. Used internally so that waits don't become cyclic
41 */
42 async wait (port, threshold, fromPort) {
43 let instance = this._runningContainers.get(port)
44 if (instance) {
45 return instance.wait(threshold, fromPort)
46 } else {
47 return threshold
48 }
49 }
50
51 /**
52 * creates an instance given the container type, starting state, entry port
53 * and the parentPort
54 * @param {String} the type of VM to load
55 * @param {Object} the starting state of the VM
56 * @param {Object} the entry port
57 * @param {Object} the parent port
58 */
59 async createInstance (type, state, entryPort = null, parentPort) {
60 const Container = this._containerTypes[type]
61
62 if (!state) {
63 state = {
64 '/': Container.createState()
65 }
66 }
67
68 // create a new kernel instance
69 const exoInterface = new ExoInterface({
70 entryPort: entryPort,
71 parentPort: parentPort,
72 hypervisor: this,
73 state: state,
74 Container: Container
75 })
76
77 // save the newly created instance
78 this._runningContainers.set(entryPort, exoInterface)
79 await exoInterface.start()
80 return exoInterface
81 }
82
83 /**
84 * creates a state root starting from a given container and a given number of
85 * ticks
86 * @param {Container} container an container instance
87 * @param {Number} ticks the number of ticks at which to create the state root
88 */
89 async createStateRoot (container, ticks) {
90 await container.wait(ticks)
91 return this.graph.flush(container.state)
92 }
93
94 /**
95 * regirsters a container with the hypervisor
96 * @param {String} the name of the type
97 * @param {Class} a Class for instantiating the container
98 */
99 registerContainer (type, vm) {
100 this._containerTypes[type] = vm
101 }
102}
103

Built with git-ssb-web