Время от времени, при разработке очередного API, которое работает поверх HTTP или создается Socket-сервер после остановки и попытки запуска сервера получаю ошибку:

socket.error: [Errno 98] Address already in use

Проблема заключается в том, что при аварийном (Ctrl+Z) завершении сервера в операционной системе остается запущенным процесс, который слушает нужный мне порт. В разных ОС время жизни такого процесса разное: в RHEL это около двух минут, в Ubuntu - больше. 

Решение достаточно простое. Т.к. при нажатии клавиш Ctrl+Z процесс получает команду “keyboard interrupt”, то достаточно обработать нужное исключение и корректно завершить процесс:

 

 

Надеюсь теперь не буду забывать писать нужный try-except...

 

Пример кода на GitHub: https://github.com/e0ne/BlogSamples/tree/master/SocketError. Для его запуска необходимо наличие утановленного пакета SOAPPy.


Comments

Алексей Качаев Ukraine

Wednesday, February 8, 2012 3:21 PM

Алексей Качаев

... процесс получает команду “keyboard interrupt” - это очень далеко от правды. и собственно привело к не очень корректному решению Smile

в стандарте POSIX нет таких комманд. да и вообще, процессы могут получать только сигналы, а не команды. в описанной ситуации кернель отправляет процессу SIGINT, который по дефолту обрабатывается интерпритатором выбрасыванием  KeyboardInterrupt. описанное решение с try/catch будет работать нестабильно в различных ситуациях. например, в multithreading env. в асинхронном коде еще хуже ситуация с этим.

import signal
# в shutdown определяешь то, что нужно сделать в таком случае.
# такой подход сработает железобетонно-одинаково во всех случаях
signal.signal(signal.SIGINT, shutdown)

e0ne United States

Wednesday, February 8, 2012 3:29 PM

e0ne

Спасибо за дополнение, матчасть у меня хромает Frown.

Пок у меня не было проблем с моим способом. Не то, чтобы очень часато его применял, но в моих случаяих при мспользовании eventlet оно решало проблему и новых замечено не было.

Comments are closed