Как использовать контекст времени ожидания в контексте времени ожидания в Python - PullRequest
0 голосов
/ 15 ноября 2018

Большинство решений для контекста времени ожидания используют сигналы.Но сигналы перезаписываются и остается только последний обработчик сигнала.Следствием этого является то, что вы не можете использовать контекст тайм-аута, если код уже находится в контексте тайм-аута (который мог быть запущен вами, другим разработчиком, библиотекой, фреймворком, кто знает?).

Итак,в основном мой упрощенный вариант использования таков:

with Timeout(1): #A
   with Timeout(100): #B
      sleep(10) #C
   print('Fail')

Этот код никогда не должен печатать "Fail".Но каждая реализация Timeout (), которую я видел до сих пор, делает одно и то же:

  • Timeout A запускает контекст тайм-аута
  • Timeout B запускает новый контекст тайм-аута (перезаписывая Timeoutконтекст из A)
  • Тайм-аут никогда не наступает, поскольку вычисления в C занимают менее 100 с
  • Выполнение возобновляется без контекста тайм-аута и длится более 1 с

Предыдущий пример кажется немного глупым, но реальный вариант использования больше похож на:

with Timeout(30):
   for a in list:
      with Timeout(10):
         heavy_computing(a)

Я не знаю длину «списка», я не хочу брать больше 10 секунд наэлемент списка и не более 30 с.

Итак, мой вопрос: какова будет лучшая реализация контекста Timeout (), который не использует сигнал и поддерживает встроенные контексты внутри контекстов?

Редактировать:

  • Решение не должно быть поточно-ориентированным, просто безопасным из другого контекста времени ожидания с более высоким уровнем области видимости.
  • Если возможноЯ бы предпочел растворЭто менее инвазивная возможность, так как я могу использовать ее для вызова библиотеки, которую я не писал.

Edit2:

Хорошо, небольшое пояснение относительно того, как я считаюТайм-аут.Для меня Timeout - это ненавязчивое решение для возврата частичного результата (или вообще никакого результата), если операция «черного ящика» занимает слишком много времени.Результат должен быть возвращен быстро, но может быть неполным.

def function(argument):
   results = []
   with Timeout(50):
      for a in arguments:
         with Timeout(20):
            results.append(black_box(a))
   return results

Если функция занимает более 50 с, выполнение прекращается и возвращается неполный результат.И если для black_box требуется более 10 секунд, он будет пропущен, чтобы перейти к следующему результату.

Пример: arguments = [a, b, c, d] black_box (a) берет 25 секунд и возвращает w black_box (b) берет 20 секунд и возвращает x black_box (c) берет 5 секунд и возвращает y black_box (d) берет 10 секунд и возвращает z результаты = [x, y]

объяснения: a заняло более 20 секунд и было пропущено b занятоНа 20 секунд больше (всего 40 секунд) и была успешно рассчитана c потребовалось 5 секунд больше (всего 45 секунд), но менее 50 секунд d было прервано из-за тайм-аута 50 секунд

Функция blackbox не знает, что онавызывается из контекста времени ожидания и не содержит кода, зависящего от времени ожидания.

Этот код является примером и может немного отличаться.Может быть, нам нужна попытка ... кроме как для обнаружения ошибок тайм-аута и т. Д. Но black_box нельзя изменить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...