Files: 6b20ce6345f5cf4e554a3d7b67876db977eb8070 / index.js
2870 bytesRaw
1 | const Graph = require('ipld-graph-builder') |
2 | const Message = require('primea-message') |
3 | const ExoInterface = require('./exoInterface.js') |
4 | const Scheduler = require('./scheduler.js') |
5 | |
6 | module.exports = class Hypervisor { |
7 | /** |
8 | * The Hypervisor manages the container instances by instantiating them and |
9 | * destorying them when possible. It also facilitates localating Containers |
10 | * @param {Graph} dag an instance of [ipfs.dag](https://github.com/ipfs/interface-ipfs-core/tree/master/API/dag#dag-api) |
11 | */ |
12 | constructor (dag, state = {}) { |
13 | this.graph = new Graph(dag) |
14 | this.scheduler = new Scheduler() |
15 | this._state = state |
16 | this._containerTypes = {} |
17 | } |
18 | |
19 | getDestPort (port) { |
20 | if (port.destPort) { |
21 | return port.destPort |
22 | } else { |
23 | return this.graph.get(this._state, `${port.destId}/ports/${port.destName}`) |
24 | } |
25 | } |
26 | |
27 | /** |
28 | */ |
29 | async getInstance (id) { |
30 | let instance = this.scheduler.getInstance(id) |
31 | if (instance) { |
32 | return instance |
33 | } else { |
34 | const lock = this.scheduler.getLock() |
35 | instance = await this._loadInstance(id, lock) |
36 | return instance |
37 | } |
38 | } |
39 | |
40 | async _loadInstance (id, lock) { |
41 | const state = await this.graph.get(this._state, id) |
42 | const container = this._containerTypes[state.type] |
43 | |
44 | // create a new kernel instance |
45 | const exoInterface = new ExoInterface({ |
46 | hypervisor: this, |
47 | state: state, |
48 | container: container, |
49 | id: id |
50 | }) |
51 | |
52 | // save the newly created instance |
53 | this.scheduler.update(exoInterface) |
54 | this.scheduler.releaseLock(lock) |
55 | return exoInterface |
56 | } |
57 | |
58 | async createInstance (type, code, entryPorts = [], id = {nonce: 0, parent: null}) { |
59 | const lock = this.scheduler.getLock() |
60 | id = await this.getHashFromObj(id) |
61 | const state = { |
62 | nonce: [0], |
63 | ports: {}, |
64 | type: type, |
65 | code: code |
66 | } |
67 | |
68 | await this.graph.set(this._state, id, state) |
69 | const exoInterface = await this._loadInstance(id, lock) |
70 | exoInterface.queue(null, new Message({ |
71 | ports: entryPorts |
72 | })) |
73 | |
74 | return exoInterface |
75 | } |
76 | |
77 | /** |
78 | * creates a state root starting from a given container and a given number of |
79 | * ticks |
80 | * @param {Number} ticks the number of ticks at which to create the state root |
81 | * @returns {Promise} |
82 | */ |
83 | async createStateRoot (ticks = Infinity) { |
84 | await this.scheduler.wait(ticks) |
85 | return this.graph.flush(this._state) |
86 | } |
87 | |
88 | /** |
89 | * regirsters a container with the hypervisor |
90 | * @param {String} type - the name of the type |
91 | * @param {Class} Constructor - a Class for instantiating the container |
92 | * @param {*} args - any args that the contructor takes |
93 | */ |
94 | registerContainer (type, Constructor, args) { |
95 | this._containerTypes[type] = { |
96 | Constructor: Constructor, |
97 | args: args |
98 | } |
99 | } |
100 | |
101 | async getHashFromObj (obj) { |
102 | return (await this.graph.flush(obj))['/'] |
103 | } |
104 | } |
105 |
Built with git-ssb-web