git ssb

0+

wanderer🌟 / js-primea-hypervisor



Tree: 5f6b460515d272f0c4dcfce10ff08f1efd953318

Files: 5f6b460515d272f0c4dcfce10ff08f1efd953318 / portManager.js

2528 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 let ports = Object.keys(this.ports).map(name => {
35 const port = this.ports[name]
36 this._mapPort(name, port)
37 })
38
39 // create the parent port
40 await Promise.all(ports)
41 if (this.parentPort !== undefined) {
42 const id = await this.hypervisor.generateID(this.parentPort)
43 this._portMap.set(id, new Port(ENTRY))
44 }
45 }
46
47 async _mapPort (name, port) {
48 const id = await this.hypervisor.generateID(port)
49 port = new Port(name)
50 this._portMap.set(id, port)
51 }
52
53 queue (message) {
54 this._portMap.get(message.fromPort).queue(message)
55 }
56
57 set (name, port) {
58 this.ports[name] = port
59 return this._mapPort(name, port)
60 }
61
62 async get (port) {
63 const id = await this.hypervisor.generateID(port)
64 return this._portMap.get(id)
65 }
66
67 getRef (key) {
68 return this.ports[key]
69 }
70
71 // waits till all ports have reached a threshold tick count
72 async wait (threshold, fromPort) {
73 // find the ports that have a smaller tick count then the threshold tick count
74 const unkownPorts = [...this._portMap].filter(([id, port]) => {
75 return (port.hasSent || port.name === ENTRY) &&
76 port.ticks < threshold &&
77 fromPort !== port
78 })
79
80 // console.log(unkownPorts, this.entryPort)
81 const promises = unkownPorts.map(async ([id, port]) => {
82 const portObj = port.name === ENTRY ? this.parentPort : this.ports[port.name]
83 // update the port's tick count
84 port.ticks = await this.hypervisor.wait(portObj, threshold, this.entryPort)
85 })
86 return Promise.all(promises)
87 }
88
89 async getNextMessage () {
90 await this.wait(this.kernel.ticks, this.entryPort)
91 const portMap = [...this._portMap].reduce(messageArbiter)
92 if (portMap) {
93 return portMap[1].shift()
94 }
95 }
96}
97

Built with git-ssb-web