Всем здравствуйте.
Работаю с paramiko и channels (web-socket) в Django.
Реализован класс для создания подключения и выполнения комманд на сервере через paramiko.Transport.
Экземляр этого класса в данном контексте - executer.
Создаю экземпляр класса - executer, выполняю команду, результат выполнения которой поступает в self.session.recv (который я собираюсь вычитывать через следующий метод-генератор).
Метод-генератор из класса executer:
def gen(self):
while not self.session.exit_status_ready():
yield self.session.recv(self.RECV_BYTES).decode("utf-8") \
or self.session.recv_stderr(self.RECV_BYTES).decode("utf-8")
Выполняю команду "tail -f textfile".
Вычитываю из генератора постоянно поступающие данные (никогда не прервётся) и отправляю через web-socket результат:
Экземпляр класса WebsocketConsumer:
for message in self.executer.gen:
self.send(text_data=json.dumps({
'message': str(message)
}))
Проблема в том, что данный генератор всегда будет находиться в ожидании, т.к. self.session.exit_status_ready() никогда не вернёт True (в случает с командой "tail -f textfile").
ВОПРОС:
Нахожусь в поиске решения,
как завершить вычитывание из генератора из вне (например, через веб-сокет, вызовом какой-то функции которая подключится к self.session и вызовет метод close())
Какие ещё мысли?
Худшая:
В генераторе сделать вычитывание из базы (по какому-либо уникальному ключу выполняемой команды и если там "done") - завершать выполнение генератора.
Минусы: много запросов в базу; если выполняемая команда ничего не возвращает - не срабатывает yield и в базу мы не смотрим -> завершение так же не произойдёт
Не реализуемая:
Вызывать цикл вычитывания из генератора асинхронно через asyncio.Future и завершать выполнение через close. С использованием веб-сокета так же невозможно, т.к. невозможно будет обратиться к выполняемому контексту.
и т.п.
Недобитая:
Сохранять через pickle экземпляр объекта paramiko.Transport для выполняемой команды, в случае необходимости подгружать его и завершать сессию (не получилось сохранить объект из-за объектов с lock'ами) да и вообще не пробовал, возможно ли это..