From f86cec345870f9906a05add76939d8c727f337a7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Lebleu?= <jerome.lebleu@mailoo.org>
Date: Sun, 25 May 2014 01:30:01 +0200
Subject: [PATCH] [fix] Close WebSocket on action ended to prevent unclosed and
 lost socket

---
 moulinette/interfaces/api.py | 28 ++++++++++++++++++++++++----
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/moulinette/interfaces/api.py b/moulinette/interfaces/api.py
index 916d66f5..b2b8d644 100644
--- a/moulinette/interfaces/api.py
+++ b/moulinette/interfaces/api.py
@@ -279,11 +279,23 @@ class _ActionsMapPlugin(object):
             return HTTPErrorResponse(m18n.g('websocket_request_excepted'))
 
         while True:
-            style, message = queue.get()
+            item = queue.get()
             try:
-                wsock.send(json_encode({ style: message }))
-            except WebSocketError:
-                break
+                # Retrieve the message
+                style, message = item
+            except TypeError:
+                if item == StopIteration:
+                    # Delete the current queue and break
+                    del self.queues[s_id]
+                    break
+                logging.warning("invalid item in the messages queue: %r" % item)
+            else:
+                try:
+                    # Send the message
+                    wsock.send(json_encode({ style: message }))
+                except WebSocketError:
+                    break
+            sleep(0)
 
     def process(self, _route, arguments={}):
         """Process the relevant action for the route
@@ -303,6 +315,14 @@ class _ActionsMapPlugin(object):
             raise HTTPErrorResponse(e.strerror)
         else:
             return ret
+        finally:
+            # Close opened WebSocket by putting StopIteration in the queue
+            try:
+                queue = self.queues[request.get_cookie('session.id')]
+            except KeyError:
+                pass
+            else:
+                queue.put(StopIteration)
 
 
     ## Signals handlers