1
0
mirror of https://github.com/GNS3/gns3-server synced 2024-12-01 04:38:12 +00:00

Implement a minimum interval between psutil calls. Fixes #2262

This commit is contained in:
Bernhard Ehlers 2018-02-13 11:31:04 +01:00
parent 17422bc461
commit 3a09bd43dc
3 changed files with 56 additions and 19 deletions

View File

@ -19,12 +19,12 @@ import aiohttp
import asyncio import asyncio
import json import json
import os import os
import psutil
import tempfile import tempfile
from gns3server.web.route import Route from gns3server.web.route import Route
from gns3server.compute.project_manager import ProjectManager from gns3server.compute.project_manager import ProjectManager
from gns3server.compute import MODULES from gns3server.compute import MODULES
from gns3server.utils.ping_stats import PingStats
from gns3server.schemas.project import ( from gns3server.schemas.project import (
PROJECT_OBJECT_SCHEMA, PROJECT_OBJECT_SCHEMA,
@ -186,11 +186,7 @@ class ProjectHandler:
:returns: hash :returns: hash
""" """
stats = {} return {"action": "ping", "event": PingStats.get()}
# 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}
@Route.get( @Route.get(
r"/projects/{project_id}/files", r"/projects/{project_id}/files",

View File

@ -17,7 +17,8 @@
import asyncio import asyncio
import json import json
import psutil
from gns3server.utils.ping_stats import PingStats
class NotificationQueue(asyncio.Queue): class NotificationQueue(asyncio.Queue):
@ -38,24 +39,14 @@ class NotificationQueue(asyncio.Queue):
# At first get we return a ping so the client immediately receives data # At first get we return a ping so the client immediately receives data
if self._first: if self._first:
self._first = False self._first = False
return ("ping", self._getPing(), {}) return ("ping", PingStats.get(), {})
try: try:
(action, msg, kwargs) = yield from asyncio.wait_for(super().get(), timeout) (action, msg, kwargs) = yield from asyncio.wait_for(super().get(), timeout)
except asyncio.futures.TimeoutError: except asyncio.futures.TimeoutError:
return ("ping", self._getPing(), {}) return ("ping", PingStats.get(), {})
return (action, msg, kwargs) return (action, msg, kwargs)
def _getPing(self):
"""
Return the content of the ping notification
"""
msg = {}
# Non blocking call in order to get cpu usage. First call will return 0
msg["cpu_usage_percent"] = psutil.cpu_percent(interval=None)
msg["memory_usage_percent"] = psutil.virtual_memory().percent
return msg
@asyncio.coroutine @asyncio.coroutine
def get_json(self, timeout): def get_json(self, timeout):
""" """

View File

@ -0,0 +1,50 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2018 GNS3 Technologies Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import psutil
import time
class PingStats:
"""
Ping messages are regularly sent to the client to keep the connection open.
We send with it some information about server load.
"""
_last_measurement = 0.0 # time of last measurement
_last_cpu_percent = 0.0 # last cpu_percent
_last_mem_percent = 0.0 # last virtual_memory().percent
@classmethod
def get(cls):
"""
Get ping statistics
:returns: hash
"""
stats = {}
cur_time = time.time()
# minimum interval for getting CPU and memory statistics
if cur_time < cls._last_measurement or \
cur_time > cls._last_measurement + 1.9:
cls._last_measurement = cur_time
# Non blocking call to get cpu usage. First call will return 0
cls._last_cpu_percent = psutil.cpu_percent(interval=None)
cls._last_mem_percent = psutil.virtual_memory().percent
stats["cpu_usage_percent"] = cls._last_cpu_percent
stats["memory_usage_percent"] = cls._last_mem_percent
return stats