Я пытаюсь разработать некоторый код, чтобы повторять попытку вызова функции, если выполнение занимает слишком много времени.У меня есть код, который, по-видимому, хорошо работает для этой задачи с простыми тестами, но когда я использую его по назначению, вызывая API, который время от времени истекает (через очень долгое время, например, 30 минут), таймер не 't, кажется, работает.
Базовая настройка и тестирование (с использованием цикла, который сокращает время ожидания на каждой итерации):
from contextlib import contextmanager
import threading
import _thread
from datetime import datetime
import time
class TimeoutException(Exception):
def __init__(self, msg=''):
self.msg = msg
@contextmanager
def time_limit(seconds, msg=''):
timer = threading.Timer(seconds, lambda: _thread.interrupt_main())
timer.start()
try:
yield
except KeyboardInterrupt:
raise TimeoutException("Timed out for operation {}".format(msg))
finally:
# if the action ends in specified time, timer is canceled
timer.cancel()
ii=3
result = None
while result is None:
try:
with time_limit(1, 'sleep'):
print('A ' + datetime.now().strftime("%H:%M:%S"))
time.sleep(ii)
result=2.71828
except:
print('Timeout pass')
ii=ii-1
pass
print('B ' + datetime.now().strftime("%H:%M:%S"))
Это работает, как и ожидалось.Однако, когда я заменяю контрольный пример вызовом API, с которым я работаю (https://github.com/swar/nba_api), таймер никогда не перехватывает API, когда он истекает, и я все еще застрял с первоначальной проблемойодин вызов API иногда занимает вечность.
Пример вызова API внутри такой структуры проверки (с сохранением вышеуказанных функций defs и import):
from nba_api.stats.endpoints import boxscoreadvancedv2
successful=None
while successful is None:
try:
with time_limit(4,'sleep'):
cur_boxsc_adv=boxscoreadvancedv2.BoxScoreAdvancedV2(game_id='0028000934').get_normalized_dict()
successful=3.1415
except:
print('Timeout pass')
pass
В этом случае, даже есливызов API занимает 20 минут (что на самом деле больше, чем 4 секунды, на которые я установил таймер). «Тайм-аут» никогда не печатается, и таймер никогда не вызывает ошибку, которая могла бы сбросить вызов. Любая идея, почему таймер не работаетПохоже, работает для этого случая и какие-либо идеи о том, как заставить его работать?