Skip to content

Commit

Permalink
Send machine stats via the notification stream
Browse files Browse the repository at this point in the history
Fix #252
  • Loading branch information
julien-duponchelle committed Jan 26, 2016
1 parent 119a2a3 commit 58b9986
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 5 deletions.
20 changes: 18 additions & 2 deletions gns3server/handlers/api/project_handler.py
Expand Up @@ -19,6 +19,7 @@
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
Expand Down Expand Up @@ -205,7 +206,7 @@ def notification(request, response):
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)
Expand All @@ -218,11 +219,26 @@ def notification(request, response):
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",
Expand Down
8 changes: 5 additions & 3 deletions tests/handlers/api/test_project.py
Expand Up @@ -207,17 +207,19 @@ 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)

future = asyncio.Future()
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):
Expand Down

0 comments on commit 58b9986

Please sign in to comment.