@geesoff

Как завершить вычитывание генератора из другого экземпляра программы?

Всем здравствуйте.

Работаю с 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'ами) да и вообще не пробовал, возможно ли это..
  • Вопрос задан
  • 97 просмотров
Пригласить эксперта
Ответы на вопрос 1
@santaatnas
Java, Python, Php
Вам нужен второй поток, который будет слушать соединение (TCP, HTTP, Web Socket - не важно) и по обращению к нему - вызывайте close()
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы
áxmit Петрозаводск
от 60 000 до 120 000 руб.
ICONIC Москва
от 160 000 до 230 000 руб.
21 янв. 2019, в 01:19
10000 руб./за проект
20 янв. 2019, в 22:33
30000 руб./за проект
20 янв. 2019, в 22:03
1000 руб./за проект