Option for auto close project when no client listen

And fix websocket not correctly detected has closed.

Ref https://github.com/GNS3/gns3-gui/issues/1331
This commit is contained in:
Julien Duponchelle 2016-08-16 17:35:43 +02:00
parent 9e81994adc
commit 9694850465
No known key found for this signature in database
GPG Key ID: CE8B29639E07F5E8
4 changed files with 26 additions and 0 deletions

View File

@ -44,6 +44,13 @@ class Notification:
yield queue
self._listeners[project.id].remove(queue)
def project_has_listeners(self, project):
"""
:param project_id: Project object
:returns: True if client listen this project
"""
return project.id in self._listeners and len(self._listeners[project.id]) > 0
def dispatch(self, action, event, compute_id):
"""
Notification received from compute node. Send it directly

View File

@ -32,11 +32,16 @@ class NotificationHandler:
ws = WebSocketResponse()
yield from ws.prepare(request)
# Process ping / pong and close message
asyncio.async(ws.receive())
with notifications.queue() as queue:
while True:
try:
notification = yield from queue.get_json(5)
except asyncio.futures.CancelledError:
break
if ws.closed:
break
ws.send_str(notification)
return ws

View File

@ -213,6 +213,9 @@ class ProjectHandler:
except asyncio.futures.CancelledError as e:
break
if project.auto_close and not controller.notification.project_has_listeners(project):
yield from project.close()
@Route.get(
r"/projects/{project_id}/notifications/ws",
description="Receive notifications about projects from a Websocket",
@ -231,13 +234,22 @@ class ProjectHandler:
ws = aiohttp.web.WebSocketResponse()
yield from ws.prepare(request)
# Process ping / pong and close message
asyncio.async(ws.receive())
with controller.notification.queue(project) as queue:
while True:
try:
notification = yield from queue.get_json(5)
except asyncio.futures.CancelledError as e:
break
if ws.closed:
break
ws.send_str(notification)
if project.auto_close and not controller.notification.project_has_listeners(project):
yield from project.close()
return ws
@Route.get(

View File

@ -146,6 +146,7 @@ def test_notification(http_controller, project, controller, loop):
assert b'"action": "ping"' in response.body
assert b'"cpu_usage_percent"' in response.body
assert b'{"action": "node.created", "event": {"a": "b"}}\n' in response.body
assert project.status == "opened"
def test_notification_invalid_id(http_controller):
@ -167,6 +168,7 @@ def test_notification_ws(http_controller, controller, project, async_run):
async_run(http_controller.close())
ws.close()
assert project.status == "opened"
def test_export(http_controller, tmpdir, loop, project):