|
@@ -2,6 +2,7 @@ import threading
|
2
|
2
|
from wsgiref.simple_server import make_server
|
3
|
3
|
|
4
|
4
|
import signal
|
|
5
|
+
|
5
|
6
|
from radicale import Application as RadicaleApplication
|
6
|
7
|
from radicale import HTTPServer as RadicaleHTTPServer
|
7
|
8
|
from radicale import HTTPSServer as RadicaleHTTPSServer
|
|
@@ -16,6 +17,8 @@ class DaemonsManager(object):
|
16
|
17
|
def __init__(self, app: TGApp):
|
17
|
18
|
self._app = app
|
18
|
19
|
self._daemons = {}
|
|
20
|
+ signal.signal(signal.SIGTERM, lambda *_: self.stop_all())
|
|
21
|
+ signal.signal(signal.SIGINT, lambda *_: self.stop_all())
|
19
|
22
|
|
20
|
23
|
def run(self, name: str, daemon_class: object, **kwargs) -> None:
|
21
|
24
|
"""
|
|
@@ -32,55 +35,57 @@ class DaemonsManager(object):
|
32
|
35
|
'Daemon with name "{0}" already running'.format(name)
|
33
|
36
|
)
|
34
|
37
|
|
35
|
|
- kwargs['app'] = self._app
|
36
|
|
- shutdown_program = threading.Event()
|
37
|
|
- # SIGTERM and SIGINT (aka KeyboardInterrupt) should just mark this for
|
38
|
|
- # shutdown
|
39
|
|
- signal.signal(signal.SIGTERM, lambda *_: shutdown_program.set())
|
40
|
|
- signal.signal(signal.SIGINT, lambda *_: shutdown_program.set())
|
41
|
|
-
|
42
|
|
- try:
|
43
|
|
- threading.Thread(target=daemon_class.start, kwargs=kwargs).start()
|
44
|
|
- self._daemons[name] = daemon_class
|
45
|
|
- finally:
|
46
|
|
- shutdown_program.set()
|
47
|
|
-
|
|
38
|
+ daemon = daemon_class(name=name, kwargs=kwargs, daemon=True)
|
|
39
|
+ daemon.start()
|
|
40
|
+ self._daemons[name] = daemon
|
48
|
41
|
|
49
|
|
-class Daemon(object):
|
50
|
|
- _name = NotImplemented
|
51
|
|
-
|
52
|
|
- def __init__(self, app: TGApp):
|
53
|
|
- self._app = app
|
54
|
|
-
|
55
|
|
- @classmethod
|
56
|
|
- def start(cls, **kwargs):
|
57
|
|
- return cls(**kwargs)
|
|
42
|
+ def stop(self, name: str) -> None:
|
|
43
|
+ """
|
|
44
|
+ Stop daemon with his name and wait for him.
|
|
45
|
+ Where name is given name when daemon started
|
|
46
|
+ with run method. If daemon name unknow, raise IndexError.
|
|
47
|
+ :param name:
|
|
48
|
+ """
|
|
49
|
+ self._daemons[name].stop()
|
|
50
|
+ self._daemons[name].join()
|
58
|
51
|
|
59
|
|
- @classmethod
|
60
|
|
- def kill(cls):
|
|
52
|
+ def stop_all(self) -> None:
|
|
53
|
+ """
|
|
54
|
+ Stop all started daemons and w<ait for them.
|
|
55
|
+ """
|
|
56
|
+ for daemon_name in self._daemons:
|
|
57
|
+ self._daemons[daemon_name].stop()
|
|
58
|
+ for daemon_name in self._daemons:
|
|
59
|
+ self._daemons[daemon_name].join()
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+class Daemon(threading.Thread):
|
|
63
|
+ """
|
|
64
|
+ Thread who contains daemon. You must implement start and stop methods to
|
|
65
|
+ manage daemon life correctly.
|
|
66
|
+ """
|
|
67
|
+ def run(self):
|
61
|
68
|
raise NotImplementedError()
|
62
|
69
|
|
63
|
|
- @property
|
64
|
|
- def name(self):
|
65
|
|
- return self._name
|
|
70
|
+ def stop(self):
|
|
71
|
+ raise NotImplementedError()
|
66
|
72
|
|
67
|
73
|
|
68
|
74
|
class RadicaleDaemon(Daemon):
|
69
|
|
- _name = 'tracim-radicale-server'
|
70
|
|
-
|
71
|
|
- @classmethod
|
72
|
|
- def kill(cls):
|
73
|
|
- pass # TODO
|
|
75
|
+ def __init__(self, *args, **kwargs):
|
|
76
|
+ super().__init__(*args, **kwargs)
|
|
77
|
+ self._prepare_config()
|
|
78
|
+ self._server = self._get_server()
|
74
|
79
|
|
75
|
|
- def __init__(self, app: TGApp):
|
|
80
|
+ def run(self):
|
76
|
81
|
"""
|
77
|
82
|
To see origin radical server start method, refer to
|
78
|
83
|
radicale.__main__.run
|
79
|
84
|
"""
|
80
|
|
- super().__init__(app)
|
81
|
|
- self._prepare_config()
|
82
|
|
- server = self._get_server()
|
83
|
|
- server.serve_forever()
|
|
85
|
+ self._server.serve_forever()
|
|
86
|
+
|
|
87
|
+ def stop(self):
|
|
88
|
+ self._server.shutdown()
|
84
|
89
|
|
85
|
90
|
def _prepare_config(self):
|
86
|
91
|
from tracim.config.app_cfg import CFG
|