|
@@ -1,9 +1,8 @@
|
1
|
1
|
import threading
|
|
2
|
+import collections
|
2
|
3
|
from configparser import DuplicateSectionError
|
3
|
|
-from wsgiref.simple_server import make_server
|
4
|
|
-import signal
|
5
|
4
|
|
6
|
|
-import collections
|
|
5
|
+from wsgiref.simple_server import make_server
|
7
|
6
|
|
8
|
7
|
from radicale import Application as RadicaleApplication
|
9
|
8
|
from radicale import HTTPServer as BaseRadicaleHTTPServer
|
|
@@ -13,16 +12,18 @@ from radicale import config as radicale_config
|
13
|
12
|
from rq import Connection as RQConnection
|
14
|
13
|
from rq import Worker as BaseRQWorker
|
15
|
14
|
from redis import Redis
|
|
15
|
+from rq.dummy import do_nothing
|
|
16
|
+from rq.worker import StopRequested
|
16
|
17
|
|
17
|
18
|
from tracim.lib.base import logger
|
18
|
19
|
from tracim.lib.exceptions import AlreadyRunningDaemon
|
19
|
|
-from tracim.lib.utils import add_signal_handler
|
|
20
|
+
|
|
21
|
+from tracim.lib.utils import get_rq_queue
|
20
|
22
|
|
21
|
23
|
|
22
|
24
|
class DaemonsManager(object):
|
23
|
25
|
def __init__(self):
|
24
|
26
|
self._running_daemons = {}
|
25
|
|
- add_signal_handler(signal.SIGTERM, self.stop_all)
|
26
|
27
|
|
27
|
28
|
def run(self, name: str, daemon_class: object, **kwargs) -> None:
|
28
|
29
|
"""
|
|
@@ -61,7 +62,7 @@ class DaemonsManager(object):
|
61
|
62
|
logger.info(self, 'Stopping daemon with name "{0}": OK'
|
62
|
63
|
.format(name))
|
63
|
64
|
|
64
|
|
- def stop_all(self, *args, **kwargs) -> None:
|
|
65
|
+ def stop_all(self) -> None:
|
65
|
66
|
"""
|
66
|
67
|
Stop all started daemons and wait for them.
|
67
|
68
|
"""
|
|
@@ -71,6 +72,10 @@ class DaemonsManager(object):
|
71
|
72
|
daemon.stop()
|
72
|
73
|
|
73
|
74
|
for name, daemon in self._running_daemons.items():
|
|
75
|
+ logger.info(
|
|
76
|
+ self,
|
|
77
|
+ 'Stopping daemon "{0}" waiting confirmation'.format(name),
|
|
78
|
+ )
|
74
|
79
|
daemon.join()
|
75
|
80
|
logger.info(self, 'Stopping daemon "{0}" OK'.format(name))
|
76
|
81
|
|
|
@@ -158,7 +163,12 @@ class MailSenderDaemon(Daemon):
|
158
|
163
|
pass
|
159
|
164
|
|
160
|
165
|
def stop(self) -> None:
|
161
|
|
- self.worker.request_stop('TRACIM STOP', None)
|
|
166
|
+ # When _stop_requested at False, tracim.lib.daemons.RQWorker
|
|
167
|
+ # will raise StopRequested exception in worker thread after receive a
|
|
168
|
+ # job.
|
|
169
|
+ self.worker._stop_requested = True
|
|
170
|
+ queue = get_rq_queue('mail_sender')
|
|
171
|
+ queue.enqueue(do_nothing)
|
162
|
172
|
|
163
|
173
|
def run(self) -> None:
|
164
|
174
|
from tracim.config.app_cfg import CFG
|
|
@@ -175,13 +185,19 @@ class MailSenderDaemon(Daemon):
|
175
|
185
|
|
176
|
186
|
class RQWorker(BaseRQWorker):
|
177
|
187
|
def _install_signal_handlers(self):
|
178
|
|
- # TODO BS 20170126: RQ WWorker is designed to work in main thread
|
|
188
|
+ # RQ Worker is designed to work in main thread
|
179
|
189
|
# So we have to disable these signals (we implement server stop in
|
180
|
|
- # MailSenderDaemon.stop method). When bug
|
181
|
|
- # https://github.com/tracim/tracim/issues/166 will be fixed, ensure
|
182
|
|
- # This worker terminate correctly.
|
|
190
|
+ # MailSenderDaemon.stop method).
|
183
|
191
|
pass
|
184
|
192
|
|
|
193
|
+ def dequeue_job_and_maintain_ttl(self, timeout):
|
|
194
|
+ # RQ Worker is designed to work in main thread, so we add behaviour
|
|
195
|
+ # here: if _stop_requested has been set to True, raise the standard way
|
|
196
|
+ # StopRequested exception to stop worker.
|
|
197
|
+ if self._stop_requested:
|
|
198
|
+ raise StopRequested()
|
|
199
|
+ return super().dequeue_job_and_maintain_ttl(timeout)
|
|
200
|
+
|
185
|
201
|
|
186
|
202
|
class RadicaleHTTPSServer(TracimSocketServerMixin, BaseRadicaleHTTPSServer):
|
187
|
203
|
pass
|