Das Schließen der Datei nach dem SFTP-Upload führt immer noch dazu, dass der Client denselben Upload in „close“ sftp_resPython

Python-Programme
Anonymous
 Das Schließen der Datei nach dem SFTP-Upload führt immer noch dazu, dass der Client denselben Upload in „close“ sftp_res

Post by Anonymous »

Ich betreibe mit Paramiko einen benutzerdefinierten SFTP-Server, der Videodateien von NVR-Kameras empfängt und in einen Cloud-Speicher hochlädt. Der Ablauf ist einfach: Der Client (NVR) stellt eine Verbindung her und authentifiziert sich. Wir schreiben die eingehende Datei lokal, übertragen sie dann an Google Cloud Storage und entfernen die lokale Kopie. Danach sollte die Verbindung geschlossen werden und der NVR sollte aufhören zu versuchen, dieselbe Datei erneut zu senden. Was ich sehe, ist, dass einige NVRs stattdessen immer wieder genau denselben Upload in einer Schleife versuchen, direkt nachdem wir die lokale Datei gelöscht haben, was den Server mit wiederholten Schreibvorgängen überschwemmt.
Hier ist eine reduzierte Version des Handlers, der die Verbindung direkt nach dem Upload schließt:

Code: Select all

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")
Ich habe erwartet, dass der Client die Übertragung als erfolgreich ansehen und den erneuten Versuch abbrechen würde, sobald close() ohne Fehlerauslösung abgeschlossen wurde. Stattdessen versucht der NVR den Upload sofort weiter und wir beobachten doppelte Uploads derselben Datei. Serverprotokolle zeigen keinen Protokollfehler an und der Upload zum GCS erfolgt erfolgreich, gefolgt vom Entfernen der lokalen Datei.
Das deutet darauf hin, dass mein Client beim Schließen kein klares Erfolgssignal erhalten hat...
PS: Falls sich jemand fragt, wie ich mich selbst gefragt habe: Leider nein, es ist nicht möglich, auf Protokolle auf dem NVR zuzugreifen, um zu sehen, was passiert, nachdem der Upload abgeschlossen ist. Bei den NVRs handelt es sich um Kartoffelkameras mit wenig bis gar keiner Verwaltung, mit eingebetteter Software, die nur die Änderung des DNS des SFTP-Servers ermöglicht und keine andere Option zur Verfügung stellt.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post