From 46b348e46a0a00740be745a1ed9d6289163a3035 Mon Sep 17 00:00:00 2001 From: Julien Duponchelle Date: Tue, 24 Feb 2015 21:53:38 +0100 Subject: [PATCH] VM concurrency --- gns3server/handlers/api/version_handler.py | 11 +++++++++++ gns3server/web/route.py | 19 +++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/gns3server/handlers/api/version_handler.py b/gns3server/handlers/api/version_handler.py index 000e932a..af01fe14 100644 --- a/gns3server/handlers/api/version_handler.py +++ b/gns3server/handlers/api/version_handler.py @@ -20,6 +20,8 @@ from ...schemas.version import VERSION_SCHEMA from ...version import __version__ from aiohttp.web import HTTPConflict +import asyncio + class VersionHandler: @@ -45,3 +47,12 @@ class VersionHandler: if request.json["version"] != __version__: raise HTTPConflict(text="Client version {} differs with server version {}".format(request.json["version"], __version__)) response.json({"version": __version__}) + + @staticmethod + @Route.get( + r"/sleep/{vm_id}", + description="Retrieve the server version number", + output=VERSION_SCHEMA) + def sleep(request, response): + yield from asyncio.sleep(1) + response.json({"version": __version__}) diff --git a/gns3server/web/route.py b/gns3server/web/route.py index 13344bf9..4e411b5a 100644 --- a/gns3server/web/route.py +++ b/gns3server/web/route.py @@ -63,6 +63,8 @@ class Route(object): _routes = [] _documentation = {} + _vms_lock = {} + @classmethod def get(cls, path, *args, **kw): return cls._route('GET', path, *args, **kw) @@ -150,9 +152,22 @@ class Route(object): return response - cls._routes.append((method, cls._path, control_schema)) + @asyncio.coroutine + def vm_concurrency(request): + """ + To avoid strange effect we prevent concurrency + between the same instance of the vm + """ + + if "vm_id" in request.match_info: + cls._vms_lock.setdefault(request.match_info["vm_id"], asyncio.Lock()) + with (yield from cls._vms_lock[request.match_info["vm_id"]]): + response = yield from control_schema(request) + return response + + cls._routes.append((method, cls._path, vm_concurrency)) - return control_schema + return vm_concurrency return register @classmethod