The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/5181

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===
Currently the EventListener.Disconnect() method just removes the listener from
the list, but does not close the underlying websocket connection (since there
might be other listeners). However if the list of event listeners has become
empty, the current logic won't close the connection since it's blocked on
conn.ReadMessage().

This change separates the job of fetching events via conn.ReadMessage() from the
job of monitoring if all listeners are gone.

This is an attempt to fix #5179: I was not able to reproduce the issue, but an event listeners leakage is the only thing that comes to my mind, and hopefully the scenario described above is indeed what's happening for real.

Signed-off-by: Free Ekanayaka <free.ekanay...@canonical.com>
From 2024096d4b906ab3f044e40a6794eb6a3ba0f5e1 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanay...@canonical.com>
Date: Wed, 17 Oct 2018 10:34:36 +0200
Subject: [PATCH] Prevent event listeners from lying around even after
 Disconnect()

Currently the EventListener.Disconnect() method just removes the listener from
the list, but does not close the underlying websocket connection (since there
might be other listeners). However if the list of event listeners has become
empty, the current logic won't close the connection since it's blocked on
conn.ReadMessage().

This change separates the job of fetching events via conn.ReadMessage() from the
job of monitoring if all listeners are gone.

Signed-off-by: Free Ekanayaka <free.ekanay...@canonical.com>
---
 client/lxd_events.go | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/client/lxd_events.go b/client/lxd_events.go
index 9df4f31f4d..15fc35cb6f 100644
--- a/client/lxd_events.go
+++ b/client/lxd_events.go
@@ -3,6 +3,7 @@ package lxd
 import (
        "encoding/json"
        "fmt"
+       "time"
 
        "github.com/lxc/lxd/shared"
 )
@@ -39,9 +40,17 @@ func (r *ProtocolLXD) GetEvents() (*EventListener, error) {
        // Add the listener
        r.eventListeners = append(r.eventListeners, &listener)
 
-       // And spawn the listener
+       // Spawn a watcher that will close the websocket connection after all
+       // listeners are gone.
+       stopCh := make(chan struct{}, 0)
        go func() {
                for {
+                       select {
+                       case <-time.After(time.Minute):
+                       case <-stopCh:
+                               break
+                       }
+
                        r.eventListenersLock.Lock()
                        if len(r.eventListeners) == 0 {
                                // We don't need the connection anymore, 
disconnect
@@ -52,7 +61,12 @@ func (r *ProtocolLXD) GetEvents() (*EventListener, error) {
                                break
                        }
                        r.eventListenersLock.Unlock()
+               }
+       }()
 
+       // Spawn the listener
+       go func() {
+               for {
                        _, data, err := conn.ReadMessage()
                        if err != nil {
                                // Prevent anything else from interacting with 
the listeners
@@ -68,6 +82,10 @@ func (r *ProtocolLXD) GetEvents() (*EventListener, error) {
 
                                // And remove them all from the list
                                r.eventListeners = []*EventListener{}
+
+                               conn.Close()
+                               close(stopCh)
+
                                return
                        }
 
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to