Merge pull request #412 from GNS3/stats_stream

Send machine stats via the notification stream
This commit is contained in:
Jeremy Grossmann 2016-01-26 08:52:16 -08:00
commit 35e045a22e
2 changed files with 23 additions and 5 deletions

View File

@ -19,6 +19,7 @@ import aiohttp
import asyncio
import json
import os
import psutil
from ...web.route import Route
from ...schemas.project import PROJECT_OBJECT_SCHEMA, PROJECT_CREATE_SCHEMA, PROJECT_UPDATE_SCHEMA, PROJECT_FILE_LIST_SCHEMA, PROJECT_LIST_SCHEMA
@ -205,7 +206,7 @@ class ProjectHandler:
queue = project.get_listen_queue()
ProjectHandler._notifications_listening.setdefault(project.id, 0)
ProjectHandler._notifications_listening[project.id] += 1
response.write("{\"action\": \"ping\"}\n".encode("utf-8"))
response.write("{}\n".format(json.dumps(ProjectHandler._getPingMessage())).encode("utf-8"))
while True:
try:
(action, msg) = yield from asyncio.wait_for(queue.get(), 5)
@ -218,11 +219,26 @@ class ProjectHandler:
except asyncio.futures.CancelledError as e:
break
except asyncio.futures.TimeoutError:
response.write("{\"action\": \"ping\"}\n".encode("utf-8"))
response.write("{}\n".format(json.dumps(ProjectHandler._getPingMessage())).encode("utf-8"))
project.stop_listen_queue(queue)
if project.id in ProjectHandler._notifications_listening:
ProjectHandler._notifications_listening[project.id] -= 1
@classmethod
def _getPingMessage(cls):
"""
The ping message is regulary send to the client to
keep the connection open. We send with it some informations
about server load.
:returns: hash
"""
stats = {}
# Non blocking call in order to get cpu usage. First call will return 0
stats["cpu_usage_percent"] = psutil.cpu_percent(interval=None)
stats["memory_usage_percent"] = psutil.virtual_memory().percent
return {"action": "ping", "event": stats}
@classmethod
@Route.get(
r"/projects/{project_id}/files",

View File

@ -207,9 +207,9 @@ def test_notification(server, project, loop):
@asyncio.coroutine
def go(future):
response = yield from aiohttp.request("GET", server.get_url("/projects/{project_id}/notifications".format(project_id=project.id), 1))
response.body = yield from response.content.read(19)
response.body = yield from response.content.read(200)
project.emit("vm.created", {"a": "b"})
response.body += yield from response.content.read(47)
response.body += yield from response.content.read(50)
response.close()
future.set_result(response)
@ -217,7 +217,9 @@ def test_notification(server, project, loop):
asyncio.async(go(future))
response = loop.run_until_complete(future)
assert response.status == 200
assert response.body == b'{"action": "ping"}\n{"action": "vm.created", "event": {"a": "b"}}\n'
assert b'"action": "ping"' in response.body
assert b'"cpu_usage_percent"' in response.body
assert b'{"action": "vm.created", "event": {"a": "b"}}\n' in response.body
def test_notification_invalid_id(server):