From 8abc7575cd7083060d19fb007dbf7117b2319738 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Tue, 5 Oct 2021 16:17:18 +0000 Subject: [PATCH] Tear out all the complicated update logic There is some weird behaviour that seem to storm the update channel. And our solution with a central map of update channels isnt particularly elegant. For now, replace all the complicated stuff with a simple channel that checks roughly every 10s if the node is up to date. Only generate and update if there has been changes. --- poll.go | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/poll.go b/poll.go index a33d341b..df3112c4 100644 --- a/poll.go +++ b/poll.go @@ -140,10 +140,9 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { Str("id", c.Param("id")). Str("machine", m.Name). Msg("Loading or creating update channel") - updateChan := h.getOrOpenUpdateChannel(m) + updateChan := make(chan struct{}) pollDataChan := make(chan []byte) - // defer close(pollData) keepAliveChan := make(chan []byte) @@ -160,7 +159,7 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { // It sounds like we should update the nodes when we have received a endpoint update // even tho the comments in the tailscale code dont explicitly say so. updateRequestsFromNode.WithLabelValues("endpoint-update").Inc() - go h.notifyChangesToPeers(m) + go func() { updateChan <- struct{}{} }() return } else if req.OmitPeers && req.Stream { log.Warn(). @@ -186,7 +185,7 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { Str("machine", m.Name). Msg("Notifying peers") updateRequestsFromNode.WithLabelValues("full-update").Inc() - go h.notifyChangesToPeers(m) + go func() { updateChan <- struct{}{} }() h.PollNetMapStream(c, m, req, mKey, pollDataChan, keepAliveChan, updateChan, cancelKeepAlive) log.Trace(). @@ -206,10 +205,10 @@ func (h *Headscale) PollNetMapStream( mKey wgkey.Key, pollDataChan chan []byte, keepAliveChan chan []byte, - updateChan <-chan struct{}, + updateChan chan struct{}, cancelKeepAlive chan struct{}, ) { - go h.scheduledPollWorker(cancelKeepAlive, keepAliveChan, mKey, req, m) + go h.scheduledPollWorker(cancelKeepAlive, updateChan, keepAliveChan, mKey, req, m) c.Stream(func(w io.Writer) bool { log.Trace(). @@ -423,7 +422,8 @@ func (h *Headscale) PollNetMapStream( Str("machine", m.Name). Str("channel", "Done"). Msg("Closing update channel") - h.closeUpdateChannel(m) + //h.closeUpdateChannel(m) + close(updateChan) log.Trace(). Str("handler", "PollNetMapStream"). @@ -446,13 +446,14 @@ func (h *Headscale) PollNetMapStream( func (h *Headscale) scheduledPollWorker( cancelChan <-chan struct{}, + updateChan chan<- struct{}, keepAliveChan chan<- []byte, mKey wgkey.Key, req tailcfg.MapRequest, m *Machine, ) { keepAliveTicker := time.NewTicker(60 * time.Second) - updateCheckerTicker := time.NewTicker(30 * time.Second) + updateCheckerTicker := time.NewTicker(10 * time.Second) for { select { @@ -476,16 +477,12 @@ func (h *Headscale) scheduledPollWorker( keepAliveChan <- data case <-updateCheckerTicker.C: - // Send an update request regardless of outdated or not, if data is sent - // to the node is determined in the updateChan consumer block - err := h.sendRequestOnUpdateChannel(m) - if err != nil { - log.Error(). - Str("func", "keepAlive"). - Str("machine", m.Name). - Err(err). - Msgf("Failed to send update request to %s", m.Name) - } + log.Debug(). + Str("func", "scheduledPollWorker"). + Str("machine", m.Name). + Msg("Sending update request") + updateRequestsFromNode.WithLabelValues("scheduled-update").Inc() + updateChan <- struct{}{} } } }