Закрытие файла после загрузки по SFTP по-прежнему заставляет клиента повторить ту же загрузку в `close` sftp_response изPython

Программы на Python
Ответить
Anonymous
 Закрытие файла после загрузки по SFTP по-прежнему заставляет клиента повторить ту же загрузку в `close` sftp_response из

Сообщение Anonymous »

Я запускаю собственный SFTP-сервер с помощью Paramiko, который получает видеофайлы с камер NVR и загружает их в облачное хранилище. Схема проста: клиент (NVR) подключается и проходит аутентификацию, мы записываем входящий файл локально, затем помещаем его в Google Cloud Storage и удаляем локальную копию. После этого соединение должно закрыться, и NVR перестанет пытаться повторно отправить тот же файл. Я вижу, что вместо этого некоторые NVR продолжают повторять одну и ту же загрузку в цикле сразу после того, как мы удаляем локальный файл, что приводит к повторной записи на сервер.
Вот сокращенная версия обработчика, который закрывает соединение сразу после загрузки:

Код: Выделить всё

import os, logging, paramiko

class SFTPFileHandle(paramiko.SFTPHandle):
def __init__(self, flags, upload_file, file_name, file_path, rename_file) -> None:
super().__init__(flags)
self.upload_file = upload_file
self.file_name = file_name
self.file_path = file_path
self.rename_file = rename_file

def chattr(self, path, attr):
pass

def stat(self):
return paramiko.SFTPAttributes.from_stat(os.fstat(self.readfile.fileno()))

def close(self):
try:
super().close()

try:
exists = os.path.exists(self.file_path)
size = os.path.getsize(self.file_path) if exists else -1
logging.info(f"[Close] path='{self.file_path}' exists={exists} size={size}")
except Exception as e:
logging.warning(f"[Close] stat failed for '{self.file_path}': {e}")

fname = self.rename_file(file_name=self.file_name, file_path=self.file_path)

if fname:
if fname == "camera_off":
try:
os.remove(self.file_path)
logging.info("[Cleanup] removed local file (camera_off)")
except Exception as e:
logging.warning(f"[Cleanup] remove failed: {e}")
else:
ok = self.upload_file(fname, self.file_path)
if ok:
try:
os.remove(self.file_path)
logging.info("[Cleanup] removed local file after upload")
except Exception as e:
logging.warning(f"[Cleanup] remove failed after upload: {e}")
else:
logging.error("[Close] upload failed")
else:
logging.error("[Close] failed to build final name")

except Exception:
logging.exception("[Close] error while finalizing")
Я ожидал, что как только функция close() завершится без каких-либо ошибок, клиент увидит, что передача прошла успешно, и прекратит повторные попытки. Вместо этого NVR немедленно продолжает попытку загрузки, и мы наблюдаем повторную загрузку одного и того же файла. В журналах сервера не отображается ошибка протокола, и загрузка в GCS происходит успешно, после чего локальный файл удаляется.
Это говорит о том, что мой клиент не получил явного сигнала об успешном завершении...
PS: Если кому-то интересно, как и мне самому, к сожалению, нет, невозможно получить доступ к журналам на NVR, чтобы увидеть, что происходит после завершения загрузки. Сетевые видеорегистраторы представляют собой картофельные камеры, практически не имеющие управления, со встроенным программным обеспечением, которое позволяет изменять только DNS SFTP-сервера, и никаких других опций нет.

Подробнее здесь: https://stackoverflow.com/questions/797 ... ad-in-clos
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»