django-botmanager 0.2.22__py3-none-any.whl → 0.2.23__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- botmanager/management/commands/bot_manager.py +45 -12
- {django_botmanager-0.2.22.dist-info → django_botmanager-0.2.23.dist-info}/METADATA +1 -1
- {django_botmanager-0.2.22.dist-info → django_botmanager-0.2.23.dist-info}/RECORD +6 -6
- {django_botmanager-0.2.22.dist-info → django_botmanager-0.2.23.dist-info}/WHEEL +0 -0
- {django_botmanager-0.2.22.dist-info → django_botmanager-0.2.23.dist-info}/licenses/LICENSE +0 -0
- {django_botmanager-0.2.22.dist-info → django_botmanager-0.2.23.dist-info}/top_level.txt +0 -0
|
@@ -3,9 +3,10 @@ import importlib
|
|
|
3
3
|
import json
|
|
4
4
|
import logging
|
|
5
5
|
import os
|
|
6
|
+
import signal
|
|
6
7
|
import sys
|
|
7
8
|
from datetime import datetime, timedelta
|
|
8
|
-
from multiprocessing import Queue, Process
|
|
9
|
+
from multiprocessing import Queue, Process, Event
|
|
9
10
|
from time import sleep, time
|
|
10
11
|
|
|
11
12
|
import psutil
|
|
@@ -30,6 +31,9 @@ except ImportError:
|
|
|
30
31
|
setproctitle = lambda x: x
|
|
31
32
|
|
|
32
33
|
|
|
34
|
+
PROCESS_TO_FINISH_GRACEFULLY_TIMEOUT = 30 # seconds
|
|
35
|
+
|
|
36
|
+
|
|
33
37
|
class BotManagerCommandException(BotManagerBaseCommandException):
|
|
34
38
|
pass
|
|
35
39
|
|
|
@@ -142,7 +146,30 @@ class Command(BotManagerBaseCommand):
|
|
|
142
146
|
current_pid = os.getpid()
|
|
143
147
|
PidsFileController.add_pid(current_pid)
|
|
144
148
|
|
|
149
|
+
shutdown_event = Event()
|
|
150
|
+
|
|
145
151
|
processes = []
|
|
152
|
+
|
|
153
|
+
def signal_handler(signum, frame):
|
|
154
|
+
logging.info('Main process received signal {}'.format(signum))
|
|
155
|
+
logging.info('Start shutting down children processes gracefully...')
|
|
156
|
+
shutdown_event.set()
|
|
157
|
+
|
|
158
|
+
# Wait for processes to finish
|
|
159
|
+
for p in processes:
|
|
160
|
+
p.join(timeout=PROCESS_TO_FINISH_GRACEFULLY_TIMEOUT)
|
|
161
|
+
if p.is_alive():
|
|
162
|
+
logging.info("Process {} didn't terminate gracefully, forcing...".format(p.pid))
|
|
163
|
+
p.terminate()
|
|
164
|
+
|
|
165
|
+
logging.info("All children processes have been terminated. Exiting main process {}.".format(current_pid))
|
|
166
|
+
|
|
167
|
+
sys.exit(0)
|
|
168
|
+
|
|
169
|
+
# Register signal handlers
|
|
170
|
+
signal.signal(signal.SIGTERM, signal_handler)
|
|
171
|
+
signal.signal(signal.SIGINT, signal_handler)
|
|
172
|
+
|
|
146
173
|
queue_dict = {}
|
|
147
174
|
for task_class_string, processes_count in self.config['tasks'].items():
|
|
148
175
|
cls_name = task_class_string.split('.')[-1]
|
|
@@ -158,7 +185,7 @@ class Command(BotManagerBaseCommand):
|
|
|
158
185
|
queue_dict[task_class.name].maxsize = maxsize
|
|
159
186
|
|
|
160
187
|
for i in range(processes_count):
|
|
161
|
-
tm = TaskManager(task_class, queue_dict[task_class.name], i + 1, current_pid)
|
|
188
|
+
tm = TaskManager(task_class, queue_dict[task_class.name], i + 1, current_pid, shutdown_event=shutdown_event)
|
|
162
189
|
p = Process(target=Command.start_service, args=(tm,))
|
|
163
190
|
p.name = tm.process_name
|
|
164
191
|
p.daemon = True
|
|
@@ -166,7 +193,7 @@ class Command(BotManagerBaseCommand):
|
|
|
166
193
|
processes.append(p)
|
|
167
194
|
PidsFileController.add_pid(p.pid)
|
|
168
195
|
|
|
169
|
-
tf = TaskFetcher(queue_dict, current_pid)
|
|
196
|
+
tf = TaskFetcher(queue_dict, current_pid, shutdown_event=shutdown_event)
|
|
170
197
|
p = Process(target=Command.start_service, args=(tf,))
|
|
171
198
|
p.name = tf.process_name
|
|
172
199
|
p.daemon = True
|
|
@@ -175,7 +202,7 @@ class Command(BotManagerBaseCommand):
|
|
|
175
202
|
PidsFileController.add_pid(p.pid)
|
|
176
203
|
|
|
177
204
|
if not options.get('without_sheduller'):
|
|
178
|
-
ts = TaskSheduler(self.config, current_pid)
|
|
205
|
+
ts = TaskSheduler(self.config, current_pid, shutdown_event=shutdown_event)
|
|
179
206
|
p = Process(target=Command.start_service, args=(ts,))
|
|
180
207
|
p.name = ts.process_name
|
|
181
208
|
p.daemon = True
|
|
@@ -234,16 +261,16 @@ class Command(BotManagerBaseCommand):
|
|
|
234
261
|
class TaskSheduler(object):
|
|
235
262
|
SET_PERIOD_SECONDS = 5
|
|
236
263
|
|
|
237
|
-
def __init__(self, config, parent_pid):
|
|
264
|
+
def __init__(self, config, parent_pid, shutdown_event=None):
|
|
238
265
|
self.process_name = "BotManager.TaskSheduler"
|
|
239
266
|
self.config = config
|
|
240
267
|
self.parent_pid = parent_pid
|
|
241
268
|
self.shedule_cache = {}
|
|
269
|
+
self.shutdown_event = shutdown_event
|
|
242
270
|
|
|
243
271
|
def run(self):
|
|
244
272
|
setproctitle(self.process_name)
|
|
245
|
-
while
|
|
246
|
-
|
|
273
|
+
while not self.shutdown_event.is_set():
|
|
247
274
|
if os.getppid() != self.parent_pid:
|
|
248
275
|
logging.info(u"Parent process is die. Exit..")
|
|
249
276
|
break
|
|
@@ -259,6 +286,7 @@ class TaskSheduler(object):
|
|
|
259
286
|
logging.exception(e)
|
|
260
287
|
|
|
261
288
|
sleep(self.SET_PERIOD_SECONDS)
|
|
289
|
+
logging.info(u"TaskSheduler process shutdown gracefully.")
|
|
262
290
|
|
|
263
291
|
def _time_to_set_tasks_for(self, task_class):
|
|
264
292
|
last_shedule_time = self.shedule_cache.get(task_class.name)
|
|
@@ -268,11 +296,12 @@ class TaskSheduler(object):
|
|
|
268
296
|
|
|
269
297
|
class TaskFetcher(object):
|
|
270
298
|
|
|
271
|
-
def __init__(self, queue_dict, parent_pid):
|
|
299
|
+
def __init__(self, queue_dict, parent_pid, shutdown_event=None):
|
|
272
300
|
self.process_name = "BotManager.TaskFetcher"
|
|
273
301
|
self.queue_dict = queue_dict
|
|
274
302
|
self.parent_pid = parent_pid
|
|
275
303
|
self.config = settings.MAIN_CONFIG
|
|
304
|
+
self.shutdown_event = shutdown_event
|
|
276
305
|
|
|
277
306
|
def run(self):
|
|
278
307
|
"""
|
|
@@ -289,7 +318,7 @@ class TaskFetcher(object):
|
|
|
289
318
|
"""
|
|
290
319
|
setproctitle(self.process_name)
|
|
291
320
|
Task.objects.filter(in_process=True).update(in_process=False)
|
|
292
|
-
while
|
|
321
|
+
while not self.shutdown_event.is_set():
|
|
293
322
|
try:
|
|
294
323
|
|
|
295
324
|
if os.getppid() != self.parent_pid:
|
|
@@ -341,6 +370,8 @@ class TaskFetcher(object):
|
|
|
341
370
|
|
|
342
371
|
sleep(self.config['fetch_period'])
|
|
343
372
|
|
|
373
|
+
logging.info(u"TaskFetcher shutdown gracefully.")
|
|
374
|
+
|
|
344
375
|
def _get_qsize(self, task):
|
|
345
376
|
try:
|
|
346
377
|
return self.queue_dict[task.name].qsize()
|
|
@@ -351,12 +382,13 @@ class TaskFetcher(object):
|
|
|
351
382
|
|
|
352
383
|
|
|
353
384
|
class TaskManager(object):
|
|
354
|
-
def __init__(self, task_class, queue, process_num, parent_pid):
|
|
385
|
+
def __init__(self, task_class, queue, process_num, parent_pid, shutdown_event=None):
|
|
355
386
|
self.task_class = task_class
|
|
356
387
|
self.queue = queue
|
|
357
388
|
self.process_num = process_num
|
|
358
389
|
self.process_name = u"BotManager.{0}.{1}".format(self.task_class.name, self.process_num)
|
|
359
390
|
self.parent_pid = parent_pid
|
|
391
|
+
self.shutdown_event = shutdown_event
|
|
360
392
|
|
|
361
393
|
def __str__(self):
|
|
362
394
|
return self.process_name
|
|
@@ -367,7 +399,7 @@ class TaskManager(object):
|
|
|
367
399
|
|
|
368
400
|
def run(self):
|
|
369
401
|
setproctitle(self.process_name)
|
|
370
|
-
while
|
|
402
|
+
while not self.shutdown_event.is_set():
|
|
371
403
|
try:
|
|
372
404
|
|
|
373
405
|
if os.getppid() != self.parent_pid:
|
|
@@ -390,6 +422,8 @@ class TaskManager(object):
|
|
|
390
422
|
u"Error in queue preparing: %s".format(e)
|
|
391
423
|
)
|
|
392
424
|
|
|
425
|
+
logging.info(u"TaskManager process {} shutdown gracefully.".format(self.process_name))
|
|
426
|
+
|
|
393
427
|
|
|
394
428
|
class PidsFileController(object):
|
|
395
429
|
def __init__(self):
|
|
@@ -458,4 +492,3 @@ class PidsFileController(object):
|
|
|
458
492
|
|
|
459
493
|
if os.path.exists(pids_file_name):
|
|
460
494
|
os.remove(pids_file_name)
|
|
461
|
-
|
|
@@ -7,7 +7,7 @@ botmanager/settings.py,sha256=saOAublzj8ikIwZ7eJR_P90nKolAv29Kp36QDUYEbbw,3266
|
|
|
7
7
|
botmanager/utils.py,sha256=4epNJDf5C7MrNQlZ8t2EAKGsFGRc2uXqoY49__YHGjg,1105
|
|
8
8
|
botmanager/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
9
|
botmanager/management/commands/__init__.py,sha256=uLLxNF6CEdNFFvWTcPHlaYxKQLscMRHs9sRegH19L2g,542
|
|
10
|
-
botmanager/management/commands/bot_manager.py,sha256=
|
|
10
|
+
botmanager/management/commands/bot_manager.py,sha256=WUybgNhLKOkq40LhMZSjMkWDGI8bMPTS6qBmsya6YNo,19749
|
|
11
11
|
botmanager/migrations/0001_initial.py,sha256=AfYbVMcP171RefENIDUpPkVYQK3xoSxxc_XAr5DIoQs,3357
|
|
12
12
|
botmanager/migrations/0002_auto_20161208_1406.py,sha256=jxfewdTeJ8RpLl-lzxp1zYtJijVPYR54pPXysJeb62U,742
|
|
13
13
|
botmanager/migrations/0003_auto_20161208_1529.py,sha256=FMu3GdUsKqR8oPUPxqsqPfRBjVn-9p_wukgHjsFf5hk,1935
|
|
@@ -21,8 +21,8 @@ botmanager/migrations/0010_auto_20170531_1321.py,sha256=VnfOWMBI_fuBGmH1NOuXzA5k
|
|
|
21
21
|
botmanager/migrations/0011_alter_task_create_dt_alter_task_id.py,sha256=-bR0dQFj_ncNKJLQSVF_aDLIYNkNzkbFcsyWF6vMB2w,706
|
|
22
22
|
botmanager/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
23
|
botmanager/templates/botmanager/task/change_form.html,sha256=kwcZ72z_YgNJgWOKNE_jS1WXk7YDvo50r0kdLBXLhmU,277
|
|
24
|
-
django_botmanager-0.2.
|
|
25
|
-
django_botmanager-0.2.
|
|
26
|
-
django_botmanager-0.2.
|
|
27
|
-
django_botmanager-0.2.
|
|
28
|
-
django_botmanager-0.2.
|
|
24
|
+
django_botmanager-0.2.23.dist-info/licenses/LICENSE,sha256=drrREcwMWVwKpmlpyKh6ytsBFonOm2GbADAJD3WzjKY,1479
|
|
25
|
+
django_botmanager-0.2.23.dist-info/METADATA,sha256=WBTwZp7r9xc17EZTBuYdYnFyPsCtrnKzwzIVtk7It3E,439
|
|
26
|
+
django_botmanager-0.2.23.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
27
|
+
django_botmanager-0.2.23.dist-info/top_level.txt,sha256=gq7opmRFT7PQifLHi-_hCCtsMjAAiH87radGZ13utgM,11
|
|
28
|
+
django_botmanager-0.2.23.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|