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