Files: 26423b152859d2a3cccf24570ef55cf2770aee41 / portManager.js
2279 bytesRaw
1 | const Port = require('./port.js') |
2 | const common = require('./common.js') |
3 | |
4 | module.exports = class PortManager { |
5 | constructor (ports, kernel) { |
6 | this.kernel = kernel |
7 | this.ports = ports |
8 | this._portMap = new Map() |
9 | this._hasMappedPorts = false |
10 | this._tempQueue = [] |
11 | this._mapPorts(this.ports).then(ports => { |
12 | this._portMap = ports |
13 | this.queue = this._queue |
14 | for (const message of this._tempQueue) { |
15 | this.queue(message) |
16 | } |
17 | }) |
18 | } |
19 | |
20 | queue (message) { |
21 | this._tempQueue.push(message) |
22 | } |
23 | |
24 | _queue (message) { |
25 | this._portMap.get(message.from).push(message) |
26 | } |
27 | |
28 | async _mapPorts (ports) { |
29 | ports = Object.key(ports).map(name => { |
30 | const port = ports[name] |
31 | this.kernel.id(port).then(id => { |
32 | return [id, new Port(name)] |
33 | }) |
34 | }) |
35 | ports = await Promise.all(ports) |
36 | return new Map(ports) |
37 | } |
38 | |
39 | create (name, value) { |
40 | this.ports[name] = value |
41 | } |
42 | |
43 | del (name) { |
44 | delete this.ports[name] |
45 | } |
46 | |
47 | move (from, to) { |
48 | this.ports[to] = this.ports[from] |
49 | delete this.ports[from] |
50 | } |
51 | |
52 | async get (name) { |
53 | const port = await name === common.PARENT ? this.graph.get(this.state.ports, name) : this.parentId |
54 | const id = await this.kernel.id(port) |
55 | return this._portMap.get(id) |
56 | } |
57 | |
58 | // waits till all ports have reached a threshold tick count |
59 | async wait (ticks) { |
60 | const unkownPorts = [...this._ports].filter((id, port) => { |
61 | const message = port.peek() |
62 | return !message || message.ticks < ticks |
63 | }) |
64 | |
65 | const promises = [] |
66 | for (const id in unkownPorts) { |
67 | promises.push(this.hypervisor.waitOnVM(id, ticks)) |
68 | } |
69 | await Promise.all(promises) |
70 | } |
71 | |
72 | async getNextMessage (ticks) { |
73 | await this.wait(ticks) |
74 | return [...this._ports].reduce(messageArbiter).shift() |
75 | } |
76 | } |
77 | |
78 | // decides which message to go firts |
79 | function messageArbiter (portA, portB) { |
80 | const a = portA.peek() |
81 | const b = portB.peek() |
82 | |
83 | if (!a) { |
84 | return b |
85 | } else if (!b) { |
86 | return a |
87 | } |
88 | |
89 | const aGasPrice = a.resources.gasPrice |
90 | const bGasPrice = b.resources.gasPrice |
91 | if (a.ticks !== b.ticks) { |
92 | return a.ticks < b.ticks ? a : b |
93 | } else if (aGasPrice === bGasPrice) { |
94 | return a.hash() > b.hash() ? a : b |
95 | } else { |
96 | return aGasPrice > bGasPrice ? a : b |
97 | } |
98 | } |
99 |
Built with git-ssb-web