make route calculcation more efficient and properly async
Instead of following the usual actor pattern, we use a 1-place channel with a non-blocking send. Essentially, if there is already a pending recalculation request queued up, there is no point enqueuing another one.
This commit is contained in:
1 parent
acbb911823
commit
7166d151aa
2 files changed
+18
-23
No files matched your search
@@ -21,7 +21,7 @@ type mockChannelConnection struct {
|
||||
func NewTestRouter(name PeerName) *Router {
|
||||
router := NewRouter(nil, name, "", nil, 10, 1024, nil)
|
||||
router.ConnectionMaker.actionChan = make(chan ConnectionMakerAction, ChannelSize)
|
||||
router.Routes.actionChan = make(chan RoutesAction, ChannelSize)
|
||||
router.Routes.recalculate = make(chan *struct{}, 1)
|
||||
return router
|
||||
}
|
||||
|
||||
|
||||
+17
-22
@@ -8,11 +8,11 @@ import (
|
||||
|
||||
type Routes struct {
|
||||
sync.RWMutex
|
||||
ourself *Peer
|
||||
peers *Peers
|
||||
unicast map[PeerName]PeerName
|
||||
broadcast map[PeerName][]PeerName
|
||||
actionChan chan<- RoutesAction
|
||||
ourself *Peer
|
||||
peers *Peers
|
||||
unicast map[PeerName]PeerName
|
||||
broadcast map[PeerName][]PeerName
|
||||
recalculate chan<- *struct{}
|
||||
}
|
||||
|
||||
func NewRoutes(ourself *Peer, peers *Peers) *Routes {
|
||||
@@ -27,9 +27,9 @@ func NewRoutes(ourself *Peer, peers *Peers) *Routes {
|
||||
}
|
||||
|
||||
func (routes *Routes) Start() {
|
||||
actionChan := make(chan RoutesAction, ChannelSize)
|
||||
routes.actionChan = actionChan
|
||||
go routes.actorLoop(actionChan)
|
||||
recalculate := make(chan *struct{}, 1)
|
||||
routes.recalculate = recalculate
|
||||
go routes.run(recalculate)
|
||||
}
|
||||
|
||||
func (routes *Routes) Unicast(name PeerName) (PeerName, bool) {
|
||||
@@ -64,13 +64,16 @@ func (routes *Routes) String() string {
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// ACTOR client API
|
||||
|
||||
type RoutesAction func()
|
||||
|
||||
// Async.
|
||||
func (routes *Routes) Recalculate() {
|
||||
routes.actionChan <- func() {
|
||||
select {
|
||||
case routes.recalculate <- nil:
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
func (routes *Routes) run(recalculate <-chan *struct{}) {
|
||||
for {
|
||||
<-recalculate
|
||||
unicast := routes.calculateUnicast()
|
||||
broadcast := routes.calculateBroadcast()
|
||||
routes.Lock()
|
||||
@@ -80,14 +83,6 @@ func (routes *Routes) Recalculate() {
|
||||
}
|
||||
}
|
||||
|
||||
// ACTOR server
|
||||
|
||||
func (routes *Routes) actorLoop(actionChan <-chan RoutesAction) {
|
||||
for {
|
||||
(<-actionChan)()
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate all the routes for the question: if *we* want to send a
|
||||
// packet to Peer X, what is the next hop?
|
||||
//
|
||||
|
||||
Reference in new issue
Block a user