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:
Matthias Radestock committed 2015-04-03 18:12:03 +01:00
1 parent acbb911823
commit 7166d151aa
2 files changed
+18 -23

No files matched your search

+1 -1
View File
@@ -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
View File
@@ -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?
//