Como definir um timeout para uma função em Python

Lucas Cezimbra
CWI Software
Published in
2 min readOct 28, 2019

Resposta curta: timeout-decorator

pip install timeout-decoratorfrom timeout_decorator import timeout@timeout(5)  # tempo em segundos
def my_slow_function():
...

Contexto

Esses dias eu estava dando manutenção num serviço que lê mensagens de uma fila SQS, processa e apaga a mensagem da fila. Só que estava ocorrendo um problema em que às vezes o processamento demorava mais do que o tempo máximo definido no SQS. A mensagem acabava voltando para fila, era lida por outro processo e gerava duplicação desnecessária.

Para resolver esse problema, comecei a pesquisar alguma forma de colocar um timeout numa função Python, então encontrei a lib timeout-decorator que faz exatamente o que eu precisava.

Como funciona

A lib usa, por padrão, o signals do Unix para gerar uma exceção e parar de executar a função que foi envolvida pelo decorator.

Também é possível passar um parâmetro use_signals=False, daí será usado multithreading ao invés de signals, mas eu não cheguei a testar dessa forma.

Exemplo

Instalando:

pip install timeout-decorator

arquivo.py

from time import sleepfrom timeout_decorator import timeout
@timeout(5) # tempo em segundos
def my_slow_function():
for i in range(1, 10):
print(i)
sleep(1)
if __name__ == '__main__':
my_slow_function()

Resultado:

1
2
3
4
5
Traceback (most recent call last):
...
timeout_decorator.timeout_decorator.TimeoutError: 'Timed Out'

Limitações

Por usar o signal do Unix para gerar a exceção, a lib não funciona em ambiente Windows. No projeto que eu a usei, rodamos em ambientes Linux, então não tivemos problemas em produção. Porém, um dos membros da equipe usa Windows para desenvolvimento, então fizemos um wrapper para o decorator que verifica se é Unix, se não for será retornada a função original sem o timeout-decorator.

--

--