From cb1a81fe4cda01f974f9f76fe6a50d2c31ba3698 Mon Sep 17 00:00:00 2001 From: Juan Font Alonso Date: Tue, 8 Jun 2021 19:19:40 +0200 Subject: [PATCH 1/2] Close the update channel when the client actually closes the connection. Fixes #32. --- api.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/api.go b/api.go index 39d57392..1c87ed80 100644 --- a/api.go +++ b/api.go @@ -241,7 +241,6 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { update := make(chan []byte, 1) cancelKeepAlive := make(chan []byte, 1) defer close(pollData) - defer close(update) defer close(cancelKeepAlive) h.pollMu.Lock() h.clientsPolling[m.ID] = update @@ -283,8 +282,9 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { peers, _ := h.getPeers(m) h.pollMu.Lock() for _, p := range *peers { - log.Printf("[%s] Notifying peer %s (%s)", m.Name, p.Name, p.Addresses[0]) - if pUp, ok := h.clientsPolling[uint64(p.ID)]; ok { + pUp, ok := h.clientsPolling[uint64(p.ID)] + if ok { + log.Printf("[%s] Notifying peer %s (%s)", m.Name, p.Name, p.Addresses[0]) pUp <- []byte{} } else { log.Printf("[%s] Peer %s does not appear to be polling", m.Name, p.Name) @@ -311,22 +311,23 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { log.Printf("[%s] Received a request for update", m.Name) data, err := h.getMapResponse(mKey, req, m) if err != nil { - log.Printf("[%s] 🤮 Cannot get the poll response: %s", m.Name, err) + log.Printf("[%s] Could not get the map update: %s", m.Name, err) } _, err = w.Write(*data) if err != nil { - log.Printf("[%s] 🤮 Cannot write the poll response: %s", m.Name, err) + log.Printf("[%s] Could not write the map response: %s", m.Name, err) } return true case <-c.Request.Context().Done(): - log.Printf("[%s] 😥 The client has closed the connection", m.Name) + h.pollMu.Lock() + log.Printf("[%s] The client has closed the connection", m.Name) now := time.Now().UTC() m.LastSeen = &now db.Save(&m) - h.pollMu.Lock() cancelKeepAlive <- []byte{} delete(h.clientsPolling, m.ID) + close(update) h.pollMu.Unlock() return false From 5db7716be229ac5ff47a24fc0ff03e39589eed3f Mon Sep 17 00:00:00 2001 From: Juan Font Alonso Date: Wed, 9 Jun 2021 20:55:25 +0200 Subject: [PATCH 2/2] Reduce the mutex size when the client closes the connection --- api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api.go b/api.go index 1c87ed80..344878ce 100644 --- a/api.go +++ b/api.go @@ -320,11 +320,11 @@ func (h *Headscale) PollNetMapHandler(c *gin.Context) { return true case <-c.Request.Context().Done(): - h.pollMu.Lock() log.Printf("[%s] The client has closed the connection", m.Name) now := time.Now().UTC() m.LastSeen = &now db.Save(&m) + h.pollMu.Lock() cancelKeepAlive <- []byte{} delete(h.clientsPolling, m.ID) close(update)