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