Files: b5cb4112bbeaaa34f0d5faa38670426dc58971bf / portManager.js
2513 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 | let parent = await this.hypervisor.graph.get(this.kernel._opts.id, 'parent') |
47 | parent = parent === null ? 'root' : parent |
48 | this._portMap.set(parent, new Port('parent')) |
49 | } |
50 | |
51 | queue (message) { |
52 | this._portMap.get(message.fromPort).queue(message) |
53 | } |
54 | |
55 | create (name, value) { |
56 | this.ports[name] = value |
57 | } |
58 | |
59 | del (name) { |
60 | delete this.ports[name] |
61 | } |
62 | |
63 | move (from, to) { |
64 | this.ports[to] = this.ports[from] |
65 | delete this.ports[from] |
66 | } |
67 | |
68 | async get (name) { |
69 | const port = await this.graph.get(this.state.ports, name) |
70 | const id = await this.hypervisor.generateID(port) |
71 | return this._portMap.get(id) |
72 | } |
73 | |
74 | async getParent () { |
75 | const id = await this.hypervisor.generateID(this.kernel._opts) |
76 | return this._portMap.get(id) |
77 | } |
78 | |
79 | // waits till all ports have reached a threshold tick count |
80 | async wait (threshold) { |
81 | // find the ports that have a smaller tick count then the threshold tick count |
82 | const unkownPorts = [...this._portMap].filter(([id, port]) => { |
83 | return port._ticks < threshold |
84 | }) |
85 | |
86 | const promises = unkownPorts.map(([id, port]) => { |
87 | this.hypervisor.wait(id, threshold).then(ticks => { |
88 | // update the port's tick count |
89 | port.ticks = ticks |
90 | }) |
91 | }) |
92 | await Promise.all(promises) |
93 | } |
94 | |
95 | async getNextMessage (ticks) { |
96 | await this.wait(ticks) |
97 | return [...this._portMap].reduce(messageArbiter)[1].shift() |
98 | } |
99 | } |
100 |
Built with git-ssb-web