use idle time in switch decisions to force it to try all links

This commit is contained in:
Arceliar 2019-03-09 19:27:52 -06:00
parent c7b4bfcef5
commit 3c696c3e55

View File

@ -646,7 +646,7 @@ func (t *switchTable) bestPortForCoords(coords []byte) switchPort {
// Handle an incoming packet // Handle an incoming packet
// Either send it to ourself, or to the first idle peer that's free // Either send it to ourself, or to the first idle peer that's free
// Returns true if the packet has been handled somehow, false if it should be queued // Returns true if the packet has been handled somehow, false if it should be queued
func (t *switchTable) handleIn(packet []byte, idle map[switchPort]struct{}) bool { func (t *switchTable) handleIn(packet []byte, idle map[switchPort]time.Time) bool {
coords := switch_getPacketCoords(packet) coords := switch_getPacketCoords(packet)
closer := t.getCloser(coords) closer := t.getCloser(coords)
if len(closer) == 0 { if len(closer) == 0 {
@ -654,15 +654,13 @@ func (t *switchTable) handleIn(packet []byte, idle map[switchPort]struct{}) bool
t.toRouter <- packet t.toRouter <- packet
return true return true
} }
table := t.getTable()
var best *peer var best *peer
var bestDist int var bestDist int
var bestCoordLen int var bestTime time.Time
ports := t.core.peers.getPorts() ports := t.core.peers.getPorts()
for port, dist := range closer { for port, dist := range closer {
to := ports[port] to := ports[port]
_, isIdle := idle[port] thisTime, isIdle := idle[port]
coordLen := len(table.elems[port].locator.coords)
var update bool var update bool
switch { switch {
case to == nil: case to == nil:
@ -675,21 +673,15 @@ func (t *switchTable) handleIn(packet []byte, idle map[switchPort]struct{}) bool
update = true update = true
case dist > bestDist: case dist > bestDist:
//nothing //nothing
case coordLen < bestCoordLen: case thisTime.Before(bestTime):
update = true update = true
/*
case coordLen > bestCoordLen:
//nothing
case port < best.port:
update = true
*/
default: default:
//nothing //nothing
} }
if update { if update {
best = to best = to
bestDist = dist bestDist = dist
bestCoordLen = coordLen bestTime = thisTime
} }
} }
if best != nil { if best != nil {
@ -836,7 +828,7 @@ func (t *switchTable) doWorker() {
}() }()
t.queues.switchTable = t t.queues.switchTable = t
t.queues.bufs = make(map[string]switch_buffer) // Packets per PacketStreamID (string) t.queues.bufs = make(map[string]switch_buffer) // Packets per PacketStreamID (string)
idle := make(map[switchPort]struct{}) // this is to deduplicate things idle := make(map[switchPort]time.Time) // this is to deduplicate things
for { for {
//t.core.log.Debugf("Switch state: idle = %d, buffers = %d", len(idle), len(t.queues.bufs)) //t.core.log.Debugf("Switch state: idle = %d, buffers = %d", len(idle), len(t.queues.bufs))
select { select {
@ -869,7 +861,7 @@ func (t *switchTable) doWorker() {
// Try to find something to send to this peer // Try to find something to send to this peer
if !t.handleIdle(port) { if !t.handleIdle(port) {
// Didn't find anything ready to send yet, so stay idle // Didn't find anything ready to send yet, so stay idle
idle[port] = struct{}{} idle[port] = time.Now()
} }
case f := <-t.admin: case f := <-t.admin:
f() f()