|
@@ -1,6 +1,8 @@
|
1
|
1
|
import threading
|
2
|
2
|
from wsgiref.simple_server import make_server
|
3
|
3
|
import signal
|
|
4
|
+
|
|
5
|
+import collections
|
4
|
6
|
import transaction
|
5
|
7
|
|
6
|
8
|
from radicale import Application as RadicaleApplication
|
|
@@ -59,7 +61,7 @@ class DaemonsManager(object):
|
59
|
61
|
|
60
|
62
|
def stop_all(self, *args, **kwargs) -> None:
|
61
|
63
|
"""
|
62
|
|
- Stop all started daemons and w<ait for them.
|
|
64
|
+ Stop all started daemons and wait for them.
|
63
|
65
|
"""
|
64
|
66
|
logger.info(self, 'Stopping all daemons')
|
65
|
67
|
for name, daemon in self._running_daemons.items():
|
|
@@ -72,12 +74,27 @@ class DaemonsManager(object):
|
72
|
74
|
|
73
|
75
|
self._running_daemons = {}
|
74
|
76
|
|
|
77
|
+ def execute_in_thread(self, thread_name, callback):
|
|
78
|
+ self._running_daemons[thread_name].append_thread_callback(callback)
|
|
79
|
+
|
75
|
80
|
|
76
|
81
|
class TracimSocketServerMixin(object):
|
77
|
82
|
"""
|
78
|
83
|
Mixin to use with socketserver.BaseServer who add _after_serve_actions
|
79
|
84
|
method executed after end of server execution.
|
80
|
85
|
"""
|
|
86
|
+ def __init__(self, *args, **kwargs):
|
|
87
|
+ super().__init__(*args, **kwargs)
|
|
88
|
+ self._daemon_execute_callbacks = []
|
|
89
|
+
|
|
90
|
+ def append_thread_callback(self, callback: collections.Callable) -> None:
|
|
91
|
+ """
|
|
92
|
+ Add callback to self._daemon_execute_callbacks. See service_actions
|
|
93
|
+ function to their usages.
|
|
94
|
+ :param callback: callback to execute in daemon
|
|
95
|
+ """
|
|
96
|
+ self._daemon_execute_callbacks.append(callback)
|
|
97
|
+
|
81
|
98
|
def serve_forever(self, *args, **kwargs):
|
82
|
99
|
super().serve_forever(*args, **kwargs)
|
83
|
100
|
# After serving (in case of stop) do following:
|
|
@@ -88,7 +105,15 @@ class TracimSocketServerMixin(object):
|
88
|
105
|
Override (and call super if needed) to execute actions when server
|
89
|
106
|
finish it's job.
|
90
|
107
|
"""
|
91
|
|
- transaction.commit()
|
|
108
|
+ pass
|
|
109
|
+
|
|
110
|
+ def service_actions(self):
|
|
111
|
+ if len(self._daemon_execute_callbacks):
|
|
112
|
+ try:
|
|
113
|
+ while True:
|
|
114
|
+ self._daemon_execute_callbacks.pop()()
|
|
115
|
+ except IndexError:
|
|
116
|
+ pass # Finished to iter
|
92
|
117
|
|
93
|
118
|
|
94
|
119
|
class Daemon(threading.Thread):
|
|
@@ -96,10 +121,26 @@ class Daemon(threading.Thread):
|
96
|
121
|
Thread who contains daemon. You must implement start and stop methods to
|
97
|
122
|
manage daemon life correctly.
|
98
|
123
|
"""
|
99
|
|
- def run(self):
|
|
124
|
+ def run(self) -> None:
|
|
125
|
+ """
|
|
126
|
+ Place here code who have to be executed in Daemon.
|
|
127
|
+ """
|
100
|
128
|
raise NotImplementedError()
|
101
|
129
|
|
102
|
|
- def stop(self):
|
|
130
|
+ def stop(self) -> None:
|
|
131
|
+ """
|
|
132
|
+ Place here code who stop your daemon
|
|
133
|
+ """
|
|
134
|
+ raise NotImplementedError()
|
|
135
|
+
|
|
136
|
+ def append_thread_callback(self, callback: collections.Callable) -> None:
|
|
137
|
+ """
|
|
138
|
+ Place here the logic who permit to execute a callback in your daemon.
|
|
139
|
+ To get an exemple of that, take a look at
|
|
140
|
+ socketserver.BaseServer#service_actions and how we use it in
|
|
141
|
+ tracim.lib.daemons.TracimSocketServerMixin#service_actions .
|
|
142
|
+ :param callback: callback to execute in your thread.
|
|
143
|
+ """
|
103
|
144
|
raise NotImplementedError()
|
104
|
145
|
|
105
|
146
|
|
|
@@ -157,3 +198,11 @@ class RadicaleDaemon(Daemon):
|
157
|
198
|
RadicaleHTTPSServer if cfg.RADICALE_SERVER_SSL else RadicaleHTTPServer,
|
158
|
199
|
RadicaleRequestHandler
|
159
|
200
|
)
|
|
201
|
+
|
|
202
|
+ def append_thread_callback(self, callback: collections.Callable) -> None:
|
|
203
|
+ """
|
|
204
|
+ Give the callback to running server through
|
|
205
|
+ tracim.lib.daemons.TracimSocketServerMixin#append_thread_callback
|
|
206
|
+ :param callback: callback to execute in daemon
|
|
207
|
+ """
|
|
208
|
+ self._server.append_thread_callback(callback)
|