git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: e0d0380c051f78c76923c1d39111ee94896e3a8d

Files: e0d0380c051f78c76923c1d39111ee94896e3a8d / portManager.js

2734 bytesRaw
1const Port = require('./port.js')
2const ENTRY = Symbol('entry')
3
4// decides which message to go firts
5function messageArbiter (pairA, pairB) {
6 const a = pairA[1].peek()
7 const b = pairB[1].peek()
8
9 if (!a) {
10 return pairB
11 } else if (!b) {
12 return pairA
13 }
14
15 const aGasPrice = a.resources.gasPrice
16 const bGasPrice = b.resources.gasPrice
17 if (a.ticks !== b.ticks) {
18 return a.ticks < b.ticks ? pairA : pairB
19 } else if (aGasPrice === bGasPrice) {
20 return a.hash() > b.hash() ? pairA : pairB
21 } else {
22 return aGasPrice > bGasPrice ? pairA : pairB
23 }
24}
25
26module.exports = class PortManager {
27 constructor (opts) {
28 Object.assign(this, opts)
29 this._portMap = new Map()
30 }
31
32 async start () {
33 // map ports to thier id's
34 this.ports = await this.hypervisor.graph.get(this.state, 'ports')
35 const promises = Object.keys(this.ports).map(name => {
36 const port = this.ports[name]
37 this._mapPort(name, port)
38 })
39
40 // create the parent port
41 await Promise.all(promises)
42 // skip the root, since it doesn't have a parent
43 if (this.parentPort !== undefined) {
44 const id = await this.hypervisor.generateID(this.parentPort)
45 this._portMap.set(id, new Port(ENTRY))
46 }
47 }
48
49 async _mapPort (name, port) {
50 const id = await this.hypervisor.generateID(port)
51 port = new Port(name)
52 this._portMap.set(id, port)
53 }
54
55 async queue (message) {
56 const id = await this.hypervisor.generateID(message.fromPort)
57 this._portMap.get(id).queue(message)
58 }
59
60 set (name, port) {
61 this.ports[name] = port
62 return this._mapPort(name, port)
63 }
64
65 async get (port) {
66 const id = await this.hypervisor.generateID(port)
67 return this._portMap.get(id)
68 }
69
70 getRef (key) {
71 if (key === ENTRY) {
72 return this.entryPort
73 } else {
74 return this.ports[key]
75 }
76 }
77
78 // waits till all ports have reached a threshold tick count
79 async wait (threshold, fromPort) {
80 // find the ports that have a smaller tick count then the threshold tick count
81 const unkownPorts = [...this._portMap].filter(([id, port]) => {
82 const portRef = this.getRef(port.name)
83 return port.ticks < threshold && fromPort !== portRef
84 })
85
86 const promises = unkownPorts.map(async ([id, port]) => {
87 const portObj = port.name === ENTRY ? this.parentPort : this.ports[port.name]
88 // update the port's tick count
89 port.ticks = await this.hypervisor.wait(portObj, threshold, this.entryPort)
90 })
91 return Promise.all(promises)
92 }
93
94 async getNextMessage () {
95 await this.wait(this.kernel.ticks, this.entryPort)
96 const portMap = [...this._portMap].reduce(messageArbiter)
97 if (portMap) {
98 return portMap[1].shift()
99 }
100 }
101}
102

Built with git-ssb-web