Commit 9b7a855ce9b773c9162179ef6cdb3c70739711f0
wrote docs
wanderer committed on 5/23/2017, 12:29:00 AMParent: a728a4416ce9e9ab6ba38dc79dde2c7a294feb7e
Files changed
exoInterface.js | changed |
index.js | changed |
port.js | changed |
portManager.js | changed |
exoInterface.js | ||
---|---|---|
@@ -82,8 +82,9 @@ | ||
82 | 82 | /** |
83 | 83 | * run the kernels code with a given enviroment |
84 | 84 | * The Kernel Stores all of its state in the Environment. The Interface is used |
85 | 85 | * to by the VM to retrive infromation from the Environment. |
86 | + * @returns {Promise} | |
86 | 87 | */ |
87 | 88 | async run (message) { |
88 | 89 | const oldState = clone(this.state, false, 3) |
89 | 90 | let result |
@@ -105,9 +106,10 @@ | ||
105 | 106 | } |
106 | 107 | |
107 | 108 | /** |
108 | 109 | * returns a promise that resolves once the kernel hits the threshould tick count |
109 | - * | |
110 | + * @param {Number} threshould - the number of ticks to wait | |
111 | + * @returns {Promise} | |
110 | 112 | */ |
111 | 113 | wait (threshold, fromPort) { |
112 | 114 | if (threshold <= this.ticks) { |
113 | 115 | return this.ticks |
@@ -123,8 +125,12 @@ | ||
123 | 125 | }) |
124 | 126 | } |
125 | 127 | } |
126 | 128 | |
129 | + /** | |
130 | + * updates the number of ticks that the container has run | |
131 | + * @param {Number} count - the number of ticks to add | |
132 | + */ | |
127 | 133 | incrementTicks (count) { |
128 | 134 | this.ticks += count |
129 | 135 | for (const [fromPort, waiter] of this._waitingMap) { |
130 | 136 | if (waiter.threshold < this.ticks) { |
@@ -133,8 +139,13 @@ | ||
133 | 139 | } |
134 | 140 | } |
135 | 141 | } |
136 | 142 | |
143 | + /** | |
144 | + * sends a message to a given port | |
145 | + * @param {Object} portRef - the port | |
146 | + * @param {Message} message - the message | |
147 | + */ | |
137 | 148 | async send (portRef, message) { |
138 | 149 | if (!this.ports.isValidPort(portRef)) { |
139 | 150 | throw new Error('invalid port referance') |
140 | 151 | } |
@@ -146,14 +157,20 @@ | ||
146 | 157 | const container = await this.getInstance(portRef) |
147 | 158 | container.queue(message) |
148 | 159 | |
149 | 160 | const waiter = this._waitingMap.get(portRef) |
161 | + // if the was a wait on this port the resolve it | |
150 | 162 | if (waiter) { |
151 | 163 | waiter.resolve(this.ticks) |
152 | 164 | this._waitingMap.delete(portRef) |
153 | 165 | } |
154 | 166 | } |
155 | 167 | |
168 | + /** | |
169 | + * gets a container instance given a port | |
170 | + * @param {Object} portRef - the port | |
171 | + * @returns {Object} | |
172 | + */ | |
156 | 173 | getInstance (portRef) { |
157 | 174 | return this.hypervisor.getInstanceByPort(portRef, this.entryPort) |
158 | 175 | } |
159 | 176 | } |
index.js | ||
---|---|---|
@@ -98,8 +98,9 @@ | ||
98 | 98 | * creates a state root starting from a given container and a given number of |
99 | 99 | * ticks |
100 | 100 | * @param {Container} container an container instance |
101 | 101 | * @param {Number} ticks the number of ticks at which to create the state root |
102 | + * @returns {Promise} | |
102 | 103 | */ |
103 | 104 | async createStateRoot (container, ticks) { |
104 | 105 | await container.wait(ticks) |
105 | 106 | return this.graph.flush(container.state) |
port.js | ||
---|---|---|
@@ -1,24 +1,44 @@ | ||
1 | 1 | module.exports = class Port { |
2 | - constructor (name) { | |
3 | - this.name = name | |
2 | + /** | |
3 | + * a simple repsentation of a port | |
4 | + * @property {Interger} ticks - the last know number of ticks the | |
5 | + * corrisponding container is at | |
6 | + */ | |
7 | + constructor () { | |
4 | 8 | this._queue = [] |
5 | 9 | this.ticks = 0 |
6 | 10 | } |
7 | 11 | |
12 | + /** | |
13 | + * queues a message on the port | |
14 | + * @param {Message} | |
15 | + */ | |
8 | 16 | queue (message) { |
9 | 17 | this.ticks = message._fromPortTicks |
10 | 18 | this._queue.push(message) |
11 | 19 | } |
12 | 20 | |
21 | + /** | |
22 | + * returns the message at the front of the queue | |
23 | + * @returns {Message} | |
24 | + */ | |
13 | 25 | peek () { |
14 | 26 | return this._queue[0] |
15 | 27 | } |
16 | 28 | |
17 | - shift () { | |
29 | + /** | |
30 | + * dequeue a message | |
31 | + * @returns {Message} | |
32 | + */ | |
33 | + dequeue () { | |
18 | 34 | return this._queue.shift() |
19 | 35 | } |
20 | 36 | |
37 | + /** | |
38 | + * returns the size of the queue | |
39 | + * @returns {Integer} | |
40 | + */ | |
21 | 41 | get size () { |
22 | 42 | return this._queue.length |
23 | 43 | } |
24 | 44 | } |
portManager.js | ||
---|---|---|
@@ -27,13 +27,28 @@ | ||
27 | 27 | } |
28 | 28 | } |
29 | 29 | |
30 | 30 | module.exports = class PortManager { |
31 | + /** | |
32 | + * The port manager manages the the ports. This inculdes creation, deletion | |
33 | + * fetching and waiting on ports | |
34 | + * @param {Object} opts | |
35 | + * @param {Object} opts.state | |
36 | + * @param {Object} opts.entryPort | |
37 | + * @param {Object} opts.parentPort | |
38 | + * @param {Object} opts.hypervisor | |
39 | + * @param {Object} opts.exoInterface | |
40 | + */ | |
31 | 41 | constructor (opts) { |
32 | 42 | Object.assign(this, opts) |
33 | 43 | this._portMap = new Map() |
34 | 44 | } |
35 | 45 | |
46 | + /** | |
47 | + * starts the port manager. This fetchs the ports from the state and maps | |
48 | + * them to thier names | |
49 | + * @returns {Promise} | |
50 | + */ | |
36 | 51 | async start () { |
37 | 52 | // skip the root, since it doesn't have a parent |
38 | 53 | if (this.parentPort !== undefined) { |
39 | 54 | this._bindRef(this.parentPort, ENTRY) |
@@ -47,36 +62,64 @@ | ||
47 | 62 | }) |
48 | 63 | } |
49 | 64 | |
50 | 65 | _bindRef (portRef, name) { |
51 | - const port = new Port(name) | |
66 | + const port = new Port() | |
52 | 67 | this._portMap.set(portRef, port) |
53 | 68 | } |
54 | 69 | |
70 | + /** | |
71 | + * binds a port to a name | |
72 | + * @param {Object} port - the port to bind | |
73 | + * @param {String} name - the name of the port | |
74 | + */ | |
55 | 75 | bind (port, name) { |
56 | 76 | // save the port instance |
57 | 77 | this.ports[name] = port |
58 | 78 | this._bindRef(port, name) |
59 | 79 | } |
60 | 80 | |
81 | + /** | |
82 | + * queues a message on a port | |
83 | + * @param {Message} message | |
84 | + */ | |
61 | 85 | queue (message) { |
62 | 86 | this._portMap.get(message.fromPort).queue(message) |
63 | 87 | } |
64 | 88 | |
65 | - get (key) { | |
66 | - return this.ports[key] | |
89 | + /** | |
90 | + * gets a port given it's name | |
91 | + * @param {String} name | |
92 | + * @return {Object} | |
93 | + */ | |
94 | + get (name) { | |
95 | + return this.ports[name] | |
67 | 96 | } |
68 | 97 | |
69 | - delete (key) { | |
70 | - const port = this.ports[key] | |
71 | - delete this.ports[key] | |
98 | + /** | |
99 | + * deletes a port given its name | |
100 | + * @param {String} name | |
101 | + */ | |
102 | + delete (name) { | |
103 | + const port = this.ports[name] | |
104 | + delete this.ports[name] | |
72 | 105 | this._portMap.delete(port) |
73 | 106 | } |
74 | 107 | |
108 | + /** | |
109 | + * check if a port object is still valid | |
110 | + * @param {Object} port | |
111 | + * @return {Boolean} | |
112 | + */ | |
75 | 113 | isValidPort (port) { |
76 | 114 | return this._portMap.has(port) |
77 | 115 | } |
78 | 116 | |
117 | + /** | |
118 | + * creates a new Port given the container type | |
119 | + * @param {String} type | |
120 | + * @returns {Object} the newly created port | |
121 | + */ | |
79 | 122 | create (type) { |
80 | 123 | const Container = this.hypervisor._containerTypes[type] |
81 | 124 | const parentId = this.entryPort ? this.entryPort.id : null |
82 | 125 | let nonce = this.state['/'].nonce |
@@ -101,12 +144,18 @@ | ||
101 | 144 | this.state['/'].nonce = nonce.toArray() |
102 | 145 | return portRef |
103 | 146 | } |
104 | 147 | |
105 | - // waits till all ports have reached a threshold tick count | |
106 | - wait (threshold, fromPort = this.entryPort, ports = this._portMap) { | |
148 | + /** | |
149 | + * waits till all ports have reached a threshold tick count | |
150 | + * @param {Integer} threshold - the number of ticks to wait | |
151 | + * @param {Object} fromPort - the port requesting the wait | |
152 | + * @param {Array} ports - the ports to wait on | |
153 | + * @returns {Promise} | |
154 | + */ | |
155 | + wait (threshold, fromPort = this.entryPort, ports = [...this._portMap]) { | |
107 | 156 | // find the ports that have a smaller tick count then the threshold tick count |
108 | - const unkownPorts = [...ports].filter(([portRef, port]) => { | |
157 | + const unkownPorts = ports.filter(([portRef, port]) => { | |
109 | 158 | return port.ticks < threshold && fromPort !== portRef |
110 | 159 | }) |
111 | 160 | |
112 | 161 | const promises = unkownPorts.map(async([portRef, port]) => { |
@@ -116,19 +165,24 @@ | ||
116 | 165 | |
117 | 166 | return Promise.all(promises) |
118 | 167 | } |
119 | 168 | |
120 | - async getNextMessage () { | |
169 | + /** | |
170 | + * gets the next canonical message given the an array of ports to choose from | |
171 | + * @param {Array} ports | |
172 | + * @returns {Promise} | |
173 | + */ | |
174 | + async getNextMessage (ports = [...this._portMap]) { | |
121 | 175 | if (this._portMap.size) { |
122 | 176 | // find the oldest message |
123 | - const ticks = [...this._portMap].map(([name, port]) => { | |
177 | + const ticks = ports.map(([name, port]) => { | |
124 | 178 | return port.size ? port.ticks : this.exoInterface.ticks |
125 | 179 | }).reduce((ticksA, ticksB) => { |
126 | 180 | return ticksA < ticksB ? ticksA : ticksB |
127 | 181 | }) |
128 | 182 | |
129 | 183 | await this.wait(ticks) |
130 | - const portMap = [...this._portMap].reduce(messageArbiter) | |
131 | - return portMap[1].shift() | |
184 | + const portMap = ports.reduce(messageArbiter) | |
185 | + return portMap[1].dequeue() | |
132 | 186 | } |
133 | 187 | } |
134 | 188 | } |
Built with git-ssb-web