mirror of
https://github.com/django-q2/django-q2.git
synced 2026-10-03 18:08:13 +08:00
Moves Status to it's own file
This way only qmonitor and qinfo need Curses and you can still run the cluster without it.
This commit is contained in:
@@ -7,7 +7,7 @@ sys.path.insert(0, myPath)
|
|||||||
from .tasks import async, schedule, result, result_group, fetch, fetch_group, count_group, delete_group, queue_size
|
from .tasks import async, schedule, result, result_group, fetch, fetch_group, count_group, delete_group, queue_size
|
||||||
from .models import Task, Schedule, Success, Failure
|
from .models import Task, Schedule, Success, Failure
|
||||||
from .cluster import Cluster
|
from .cluster import Cluster
|
||||||
from .monitor import Stat
|
from .status import Stat
|
||||||
|
|
||||||
VERSION = (0, 5, 3)
|
VERSION = (0, 5, 3)
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -32,7 +32,7 @@ import tasks
|
|||||||
|
|
||||||
from django_q.conf import Conf, redis_client, logger, psutil, get_ppid
|
from django_q.conf import Conf, redis_client, logger, psutil, get_ppid
|
||||||
from django_q.models import Task, Success, Schedule
|
from django_q.models import Task, Success, Schedule
|
||||||
from django_q.monitor import Status, Stat, ping_redis
|
from django_q.status import Stat, Status, ping_redis
|
||||||
|
|
||||||
|
|
||||||
class Cluster(object):
|
class Cluster(object):
|
||||||
|
|||||||
+2
-118
@@ -1,5 +1,4 @@
|
|||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import socket
|
|
||||||
|
|
||||||
# external
|
# external
|
||||||
from blessed import Terminal
|
from blessed import Terminal
|
||||||
@@ -11,8 +10,8 @@ from django.utils import timezone
|
|||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
# local
|
# local
|
||||||
import signing
|
from django_q.conf import Conf, redis_client
|
||||||
from django_q.conf import Conf, redis_client, logger
|
from django_q.status import Stat, ping_redis
|
||||||
from django_q import models
|
from django_q import models
|
||||||
|
|
||||||
|
|
||||||
@@ -85,113 +84,6 @@ def monitor(run_once=False, r=redis_client):
|
|||||||
val = term.inkey(timeout=1)
|
val = term.inkey(timeout=1)
|
||||||
|
|
||||||
|
|
||||||
class Status(object):
|
|
||||||
"""Cluster status base class."""
|
|
||||||
|
|
||||||
def __init__(self, pid):
|
|
||||||
self.workers = []
|
|
||||||
self.tob = None
|
|
||||||
self.reincarnations = 0
|
|
||||||
self.cluster_id = pid
|
|
||||||
self.sentinel = 0
|
|
||||||
self.status = Conf.STOPPED
|
|
||||||
self.done_q_size = 0
|
|
||||||
self.host = socket.gethostname()
|
|
||||||
self.monitor = 0
|
|
||||||
self.task_q_size = 0
|
|
||||||
self.pusher = 0
|
|
||||||
self.timestamp = timezone.now()
|
|
||||||
|
|
||||||
|
|
||||||
class Stat(Status):
|
|
||||||
"""Status object for Cluster monitoring."""
|
|
||||||
|
|
||||||
def __init__(self, sentinel):
|
|
||||||
super(Stat, self).__init__(sentinel.parent_pid or sentinel.pid)
|
|
||||||
self.r = sentinel.r
|
|
||||||
self.tob = sentinel.tob
|
|
||||||
self.reincarnations = sentinel.reincarnations
|
|
||||||
self.sentinel = sentinel.pid
|
|
||||||
self.status = sentinel.status()
|
|
||||||
self.done_q_size = 0
|
|
||||||
self.task_q_size = 0
|
|
||||||
if Conf.QSIZE:
|
|
||||||
self.done_q_size = sentinel.result_queue.qsize()
|
|
||||||
self.task_q_size = sentinel.task_queue.qsize()
|
|
||||||
if sentinel.monitor:
|
|
||||||
self.monitor = sentinel.monitor.pid
|
|
||||||
if sentinel.pusher:
|
|
||||||
self.pusher = sentinel.pusher.pid
|
|
||||||
self.workers = [w.pid for w in sentinel.pool]
|
|
||||||
|
|
||||||
def uptime(self):
|
|
||||||
return (timezone.now() - self.tob).total_seconds()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def key(self):
|
|
||||||
"""
|
|
||||||
:return: redis key for this cluster statistic
|
|
||||||
"""
|
|
||||||
return self.get_key(self.cluster_id)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_key(cluster_id):
|
|
||||||
"""
|
|
||||||
:param cluster_id: cluster ID
|
|
||||||
:return: redis key for the cluster statistic
|
|
||||||
"""
|
|
||||||
return '{}:{}'.format(Conf.Q_STAT, cluster_id)
|
|
||||||
|
|
||||||
def save(self):
|
|
||||||
try:
|
|
||||||
self.r.set(self.key, signing.SignedPackage.dumps(self, True), 3)
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(e)
|
|
||||||
|
|
||||||
def empty_queues(self):
|
|
||||||
return self.done_q_size + self.task_q_size == 0
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get(cluster_id, r=redis_client):
|
|
||||||
"""
|
|
||||||
gets the current status for the cluster
|
|
||||||
:param cluster_id: id of the cluster
|
|
||||||
:return: Stat or Status
|
|
||||||
"""
|
|
||||||
key = Stat.get_key(cluster_id)
|
|
||||||
if r.exists(key):
|
|
||||||
pack = r.get(key)
|
|
||||||
try:
|
|
||||||
return signing.SignedPackage.loads(pack)
|
|
||||||
except signing.BadSignature:
|
|
||||||
return None
|
|
||||||
return Status(cluster_id)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_all(r=redis_client):
|
|
||||||
"""
|
|
||||||
Get the status for all currently running clusters with the same prefix
|
|
||||||
and secret key.
|
|
||||||
:return: list of type Stat
|
|
||||||
"""
|
|
||||||
stats = []
|
|
||||||
keys = r.keys(pattern='{}:*'.format(Conf.Q_STAT))
|
|
||||||
if keys:
|
|
||||||
packs = r.mget(keys)
|
|
||||||
for pack in packs:
|
|
||||||
try:
|
|
||||||
stats.append(signing.SignedPackage.loads(pack))
|
|
||||||
except signing.BadSignature:
|
|
||||||
continue
|
|
||||||
return stats
|
|
||||||
|
|
||||||
def __getstate__(self):
|
|
||||||
# Don't pickle the redis connection
|
|
||||||
state = dict(self.__dict__)
|
|
||||||
del state['r']
|
|
||||||
return state
|
|
||||||
|
|
||||||
|
|
||||||
def info(r=redis_client):
|
def info(r=redis_client):
|
||||||
term = Terminal()
|
term = Terminal()
|
||||||
ping_redis(r)
|
ping_redis(r)
|
||||||
@@ -272,11 +164,3 @@ def info(r=redis_client):
|
|||||||
term.white('{0:.4f}'.format(exec_time))
|
term.white('{0:.4f}'.format(exec_time))
|
||||||
)
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def ping_redis(r):
|
|
||||||
try:
|
|
||||||
r.ping()
|
|
||||||
except Exception as e:
|
|
||||||
logger.error('Can not connect to Redis server.')
|
|
||||||
raise e
|
|
||||||
|
|||||||
@@ -0,0 +1,119 @@
|
|||||||
|
import socket
|
||||||
|
from django.utils import timezone
|
||||||
|
from django_q.conf import Conf, logger, redis_client
|
||||||
|
import signing
|
||||||
|
|
||||||
|
|
||||||
|
class Status(object):
|
||||||
|
"""Cluster status base class."""
|
||||||
|
|
||||||
|
def __init__(self, pid):
|
||||||
|
self.workers = []
|
||||||
|
self.tob = None
|
||||||
|
self.reincarnations = 0
|
||||||
|
self.cluster_id = pid
|
||||||
|
self.sentinel = 0
|
||||||
|
self.status = Conf.STOPPED
|
||||||
|
self.done_q_size = 0
|
||||||
|
self.host = socket.gethostname()
|
||||||
|
self.monitor = 0
|
||||||
|
self.task_q_size = 0
|
||||||
|
self.pusher = 0
|
||||||
|
self.timestamp = timezone.now()
|
||||||
|
|
||||||
|
|
||||||
|
class Stat(Status):
|
||||||
|
"""Status object for Cluster monitoring."""
|
||||||
|
|
||||||
|
def __init__(self, sentinel):
|
||||||
|
super(Stat, self).__init__(sentinel.parent_pid or sentinel.pid)
|
||||||
|
self.r = sentinel.r
|
||||||
|
self.tob = sentinel.tob
|
||||||
|
self.reincarnations = sentinel.reincarnations
|
||||||
|
self.sentinel = sentinel.pid
|
||||||
|
self.status = sentinel.status()
|
||||||
|
self.done_q_size = 0
|
||||||
|
self.task_q_size = 0
|
||||||
|
if Conf.QSIZE:
|
||||||
|
self.done_q_size = sentinel.result_queue.qsize()
|
||||||
|
self.task_q_size = sentinel.task_queue.qsize()
|
||||||
|
if sentinel.monitor:
|
||||||
|
self.monitor = sentinel.monitor.pid
|
||||||
|
if sentinel.pusher:
|
||||||
|
self.pusher = sentinel.pusher.pid
|
||||||
|
self.workers = [w.pid for w in sentinel.pool]
|
||||||
|
|
||||||
|
def uptime(self):
|
||||||
|
return (timezone.now() - self.tob).total_seconds()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def key(self):
|
||||||
|
"""
|
||||||
|
:return: redis key for this cluster statistic
|
||||||
|
"""
|
||||||
|
return self.get_key(self.cluster_id)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_key(cluster_id):
|
||||||
|
"""
|
||||||
|
:param cluster_id: cluster ID
|
||||||
|
:return: redis key for the cluster statistic
|
||||||
|
"""
|
||||||
|
return '{}:{}'.format(Conf.Q_STAT, cluster_id)
|
||||||
|
|
||||||
|
def save(self):
|
||||||
|
try:
|
||||||
|
self.r.set(self.key, signing.SignedPackage.dumps(self, True), 3)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(e)
|
||||||
|
|
||||||
|
def empty_queues(self):
|
||||||
|
return self.done_q_size + self.task_q_size == 0
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get(cluster_id, r=redis_client):
|
||||||
|
"""
|
||||||
|
gets the current status for the cluster
|
||||||
|
:param cluster_id: id of the cluster
|
||||||
|
:return: Stat or Status
|
||||||
|
"""
|
||||||
|
key = Stat.get_key(cluster_id)
|
||||||
|
if r.exists(key):
|
||||||
|
pack = r.get(key)
|
||||||
|
try:
|
||||||
|
return signing.SignedPackage.loads(pack)
|
||||||
|
except signing.BadSignature:
|
||||||
|
return None
|
||||||
|
return Status(cluster_id)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_all(r=redis_client):
|
||||||
|
"""
|
||||||
|
Get the status for all currently running clusters with the same prefix
|
||||||
|
and secret key.
|
||||||
|
:return: list of type Stat
|
||||||
|
"""
|
||||||
|
stats = []
|
||||||
|
keys = r.keys(pattern='{}:*'.format(Conf.Q_STAT))
|
||||||
|
if keys:
|
||||||
|
packs = r.mget(keys)
|
||||||
|
for pack in packs:
|
||||||
|
try:
|
||||||
|
stats.append(signing.SignedPackage.loads(pack))
|
||||||
|
except signing.BadSignature:
|
||||||
|
continue
|
||||||
|
return stats
|
||||||
|
|
||||||
|
def __getstate__(self):
|
||||||
|
# Don't pickle the redis connection
|
||||||
|
state = dict(self.__dict__)
|
||||||
|
del state['r']
|
||||||
|
return state
|
||||||
|
|
||||||
|
|
||||||
|
def ping_redis(r):
|
||||||
|
try:
|
||||||
|
r.ping()
|
||||||
|
except Exception as e:
|
||||||
|
logger.error('Can not connect to Redis server.')
|
||||||
|
raise e
|
||||||
@@ -14,7 +14,7 @@ from django_q.humanhash import DEFAULT_WORDLIST
|
|||||||
from django_q.tasks import fetch, fetch_group, async, result, result_group, count_group, delete_group, queue_size
|
from django_q.tasks import fetch, fetch_group, async, result, result_group, count_group, delete_group, queue_size
|
||||||
from django_q.models import Task, Success
|
from django_q.models import Task, Success
|
||||||
from django_q.conf import Conf, redis_client
|
from django_q.conf import Conf, redis_client
|
||||||
from django_q.monitor import Stat
|
from django_q.status import Stat
|
||||||
from .tasks import multiply
|
from .tasks import multiply
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ import redis
|
|||||||
|
|
||||||
from django_q import async
|
from django_q import async
|
||||||
from django_q.cluster import Cluster
|
from django_q.cluster import Cluster
|
||||||
from django_q.monitor import monitor, Stat, ping_redis, info
|
from django_q.monitor import monitor, info
|
||||||
|
from django_q.status import Stat, ping_redis
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
|
|||||||
Reference in New Issue
Block a user