Updater: Issue INFO log upon received signal (#951)

Fixes #946
This commit is contained in:
Mischa Krüger 2018-01-09 16:54:07 +01:00 committed by Noam Meltzer
parent 2ca7ff82ef
commit eb67c039f1
5 changed files with 35 additions and 5 deletions

View file

@ -45,6 +45,7 @@ The following wonderful people contributed directly or indirectly to this projec
- `Li-aung Yip <https://github.com/LiaungYip>`_
- `macrojames <https://github.com/macrojames>`_
- `Michael Elovskikh <https://github.com/wronglink>`_
- `Mischa Krüger <https://github.com/Makman2>`_
- `naveenvhegde <https://github.com/naveenvhegde>`_
- `neurrone <https://github.com/neurrone>`_
- `njittam <https://github.com/njittam>`_

View file

@ -6,4 +6,5 @@ yapf
pre-commit
beautifulsoup4
pytest
pytest-catchlog
pytest-timeout

View file

@ -31,6 +31,7 @@ from queue import Queue
from telegram import Bot, TelegramError
from telegram.ext import Dispatcher, JobQueue
from telegram.error import Unauthorized, InvalidToken, RetryAfter
from telegram.utils.helpers import get_signal_name
from telegram.utils.request import Request
from telegram.utils.webhookhandler import (WebhookServer, WebhookHandler)
@ -449,6 +450,8 @@ class Updater(object):
def signal_handler(self, signum, frame):
self.is_idle = False
if self.running:
self.logger.info('Received signal {} ({}), stopping...'.format(
signum, get_signal_name(signum)))
self.stop()
if self.user_sig_handler:
self.user_sig_handler(signum, frame)

View file

@ -19,6 +19,7 @@
"""This module contains helper functions."""
import re
import signal
from datetime import datetime
try:
@ -26,6 +27,18 @@ try:
except ImportError:
from cgi import escape as escape_html # noqa: F401
# From https://stackoverflow.com/questions/2549939/get-signal-names-from-numbers-in-python
_signames = {v: k
for k, v in reversed(sorted(vars(signal).items()))
if k.startswith('SIG') and not k.startswith('SIG_')}
def get_signal_name(signum):
"""Returns the signal name of the given signal number."""
return _signames[signum]
# Not using future.backports.datetime here as datetime value might be an input from the user,
# making every isinstace() call more delicate. So we just use our own compat layer.
if hasattr(datetime, 'timestamp'):

View file

@ -16,9 +16,11 @@
#
# You should have received a copy of the GNU Lesser Public License
# along with this program. If not, see [http://www.gnu.org/licenses/].
import logging
import os
import signal
import sys
from functools import partial
from queue import Queue
from random import randrange
from threading import Thread
@ -238,15 +240,25 @@ class TestUpdater(object):
return urlopen(req)
def signal_sender(self):
def signal_sender(self, updater):
sleep(0.2)
while not updater.running:
sleep(0.2)
os.kill(os.getpid(), signal.SIGTERM)
@signalskip
def test_idle(self, updater):
def test_idle(self, updater, caplog):
updater.start_polling(0.01)
Thread(target=self.signal_sender).start()
updater.idle()
Thread(target=partial(self.signal_sender, updater=updater)).start()
with caplog.at_level(logging.INFO):
updater.idle()
rec = caplog.records[-1]
assert rec.msg.startswith('Received signal {}'.format(signal.SIGTERM))
assert rec.levelname == 'INFO'
# If we get this far, idle() ran through
sleep(.5)
assert updater.running is False
@ -260,7 +272,7 @@ class TestUpdater(object):
updater.user_sig_handler = user_signal_inc
updater.start_polling(0.01)
Thread(target=self.signal_sender).start()
Thread(target=partial(self.signal_sender, updater=updater)).start()
updater.idle()
# If we get this far, idle() ran through
sleep(.5)