В настоящее время я создаю скрипт Python, который включает и отключает определенные порты на коммутаторах, чтобы увидеть, как коммутатор будет действовать в целях обеспечения качества. Я использовал библиотеку Python под названием paramiko, которая реализует SSH для подключения к любым устройствам, которые я хочу, и я имею в виду устаревший код, переданный одним из моих товарищей по команде для написания дополнительных сценариев. В одном из устаревших файлов кода есть функция _run_poll, и я не понимаю, что именно она делает.
Я попытался провести некоторое исследование того, что означает «опрос» в отношении SSH, но я до сих пор не понимаю, что происходит, когда мы проводим «опрос». Определение для него кажется немного расплывчатым. Вот функция:
def _run_poll(self, session, timeout, input_data):
interval = 0.1
maxseconds = timeout
maxcount = maxseconds / interval
i = 0
timeout_flag = False
self.info('polling (%d, %d)' % (maxseconds, maxcount))
start = datetime.datetime.now()
start_secs = time.mktime(start.timetuple())
output = ''
session.setblocking(0)
while True:
if session.recv_ready(): # returns true if data has been buffered
data = session.recv(self.bufsize) # receive data from the channel
output += data
self.info('read %d bytes, total %d' % (len(data), len(output)))
if session.send_ready():
# We received a potential prompt.
# In the future this could be made to work more like
# pexpect with pattern matching.
if i < len(input_data):
data = input_data[input_idx] + '\n'
i += 1
self.info('sending input data %d' % (len(data)))
session.send(data)
self.info('session.exit_status_ready() = %s' % (str(session.exit_status_ready())))
if session.exit_status_ready():
break
# Timeout check
now = datetime.datetime.now()
now_secs = time.mktime(now.timetuple())
et_secs = now_secs - start_secs
self.info('timeout check %d %d' % (et_secs, maxseconds))
if et_secs > maxseconds:
self.info('polling finished - timeout')
timeout_flag = True
break
time.sleep(0.200)
self.info('polling loop ended')
if session.recv_ready():
data = session.recv(self.bufsize)
output += data
self.info('read %d bytes, total %d' % (len(data), len(output)))
self.info('polling finished - %d output bytes' % (len(output)))
if timeout_flag:
self.info('appending timeout message')
output += '\nERROR: timeout after %d seconds\n' % (timeout)
session.close()
return output
Я не могу найти много онлайн-ресурсов, чтобы описать, что здесь происходит, или об «опросе» в целом. Может ли кто-нибудь помочь мне объяснить, что такое «опрос» и что здесь происходит?
Статья Википедии о Опрос определяет его как:
Actively sampling the status of an external device by a client program as a synchronous activity.
В вашем коде это означает, что он регулярно (каждые 200 мс) проверяет SSH-соединение на наличие любых входящих данных и наличие свободной емкости в выходной очереди.
В программировании есть два способа обработки асинхронных событий.
Один из способов — использовать прерывания: у вас есть код, который не выполняется до тех пор, пока его не «разбудит» какой-то механизм, а затем он выполняется. Этот механизм должен поддерживаться на более низком уровне, чем тот, на котором выполняется ваш код. Микроконтроллеры, например, имеют специальное встроенное оборудование, которое может прерывать приложение и переходить к определенному адресу, чтобы начать выполнение инструкций для обработки прерывания.
Построение системы прерываний сложно и требует значительного объема работы. Для некоторых приложений это просто невозможно. Почти всегда проще (хотя и менее эффективно) опросить или несколько раз проверить условие, пока оно не станет истинным, а затем перейти к выполнению чего-то еще.
В вашем примере обратите внимание, как он использует петлю while True:
. True никогда не будет False, поэтому этот цикл while можно разорвать только с помощью оператора break
. Мы находим этот оператор break в
if session.exit_status_ready():
break
Поэтому автор этого кода решил делать что-то постоянно, пока session.exit_status_ready()
не станет True. Поскольку это paramiko, вполне вероятно, что он выполнил удаленную команду через SSH и ждет, пока команда завершится и вернет код выхода. Смысл этого цикла в том, чтобы удерживать программу в цикле до тех пор, пока команда не завершит выполнение и не вернет результат. Также может истечь время ожидания:
if et_secs > maxseconds:
self.info('polling finished - timeout')
timeout_flag = True
break
Поэтому, если команда занимает больше, чем maxseconds
, программа не будет сидеть и ждать вечно.
Как только он выходит из цикла, он печатает:
self.info('polling loop ended')
Поэтому, когда вы видите это сообщение, вы знаете, что удаленная команда завершила выполнение или истекло время ожидания.
Смысл опроса состоит в многократной проверке чего-либо до тех пор, пока не возникнет определенное условие. В вашем случае это условие «выполнение удаленной команды завершено» или «прошло определенное количество времени».
Если вы не против принять мой ответ, я был бы признателен!
Это имело смысл. Большое спасибо !