11
11
import os
12
12
import sys
13
13
import time
14
+ import signal
14
15
import logging
15
16
16
17
from typing import List , Optional , Any
19
20
from .core .event import EventManager
20
21
from .common .utils import bytes_
21
22
from .common .flag import FlagParser , flags
22
- from .common .constants import DEFAULT_LOCAL_EXECUTOR , DEFAULT_LOG_FILE , DEFAULT_LOG_FORMAT , DEFAULT_LOG_LEVEL
23
+ from .common .constants import DEFAULT_LOCAL_EXECUTOR , DEFAULT_LOG_FILE , DEFAULT_LOG_FORMAT , DEFAULT_LOG_LEVEL , IS_WINDOWS
23
24
from .common .constants import DEFAULT_OPEN_FILE_LIMIT , DEFAULT_PLUGINS , DEFAULT_VERSION
24
25
from .common .constants import DEFAULT_ENABLE_DASHBOARD , DEFAULT_WORK_KLASS , DEFAULT_PID_FILE
25
26
@@ -190,6 +191,7 @@ def setup(self) -> None:
190
191
)
191
192
self .acceptors .setup ()
192
193
# TODO: May be close listener fd as we don't need it now
194
+ self ._register_signals ()
193
195
194
196
def shutdown (self ) -> None :
195
197
assert self .acceptors
@@ -204,6 +206,11 @@ def shutdown(self) -> None:
204
206
self .listener .shutdown ()
205
207
self ._delete_pid_file ()
206
208
209
+ @property
210
+ def remote_executors_enabled (self ) -> bool :
211
+ return self .flags .threadless and \
212
+ not (self .flags .local_executor == int (DEFAULT_LOCAL_EXECUTOR ))
213
+
207
214
def _write_pid_file (self ) -> None :
208
215
if self .flags .pid_file :
209
216
with open (self .flags .pid_file , 'wb' ) as pid_file :
@@ -214,19 +221,32 @@ def _delete_pid_file(self) -> None:
214
221
and os .path .exists (self .flags .pid_file ):
215
222
os .remove (self .flags .pid_file )
216
223
217
- @property
218
- def remote_executors_enabled (self ) -> bool :
219
- return self .flags .threadless \
220
- and not (self .flags .local_executor == int (DEFAULT_LOCAL_EXECUTOR ))
224
+ def _register_signals (self ) -> None :
225
+ # TODO: Handle SIGINFO, SIGUSR1, SIGUSR2
226
+ signal .signal (signal .SIGINT , self ._handle_exit_signal )
227
+ signal .signal (signal .SIGTERM , self ._handle_exit_signal )
228
+ if not IS_WINDOWS :
229
+ signal .signal (signal .SIGHUP , self ._handle_exit_signal )
230
+ # TODO: SIGQUIT is ideally meant for terminate with core dumps
231
+ signal .signal (signal .SIGQUIT , self ._handle_exit_signal )
232
+
233
+ @staticmethod
234
+ def _handle_exit_signal (signum : int , _frame : Any ) -> None :
235
+ logger .info ('Received signal %d' % signum )
236
+ sys .exit (0 )
237
+
238
+
239
+ def sleep_loop () -> None :
240
+ while True :
241
+ try :
242
+ time .sleep (1 )
243
+ except KeyboardInterrupt :
244
+ break
221
245
222
246
223
247
def main (** opts : Any ) -> None :
224
248
with Proxy (sys .argv [1 :], ** opts ):
225
- while True :
226
- try :
227
- time .sleep (1 )
228
- except KeyboardInterrupt :
229
- break
249
+ sleep_loop ()
230
250
231
251
232
252
def entry_point () -> None :
0 commit comments