From ae70e7a39b96fb8f40fcd2ba0ae7c4ae66ae5faf Mon Sep 17 00:00:00 2001 From: bot-backend Date: Wed, 9 Sep 2026 10:13:44 +0300 Subject: [PATCH] =?UTF-8?q?fix(msk-collector):=20=D1=80=D0=B5=D1=82=D1=80?= =?UTF-8?q?=D0=B0=D0=B9=20=D0=B7=D0=B0=D0=BB=D0=B8=D0=B2=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=B1=D0=B0=D1=82=D1=87=D0=B0=20=D0=BD=D0=B0=20=D0=BE=D0=B1?= =?UTF-8?q?=D1=80=D1=8B=D0=B2=D0=B5=20ssh?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Прогон длится часами, и ssh рвётся: живьём поймано Connection reset by peer (ssh 255) прямо посреди заливки — умирал весь прогон, несброшенный батч (до 1000 карточек) терялся, resume перечитывал страницы заново. Ретрай безопасен: SQL идемпотентен целиком — batch через ON CONFLICT DO NOTHING, карточки через ON CONFLICT (source_id,batch_id,kind) DO NOTHING. Ретраится ТОЛЬКО транспорт (код 255); ошибка самого psql под ON_ERROR_STOP поднимается сразу — это дефект данных или SQL, повтор его не лечит. --- .../scripts/local-avito-msk/collect.py | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/_wt-mskcol/tradein-mvp/scripts/local-avito-msk/collect.py b/_wt-mskcol/tradein-mvp/scripts/local-avito-msk/collect.py index f172b10b..5b0f2461 100644 --- a/_wt-mskcol/tradein-mvp/scripts/local-avito-msk/collect.py +++ b/_wt-mskcol/tradein-mvp/scripts/local-avito-msk/collect.py @@ -434,18 +434,35 @@ def build_finalize_sql(batch_id: str, query: str, notes: str) -> str: ) -def run_psql(sql: str, ssh_host: str, container: str, db_user: str, db_name: str) -> None: +def run_psql(sql: str, ssh_host: str, container: str, db_user: str, db_name: str, + attempts: int = 4) -> None: + """Заливка батча через ssh с ретраем на обрыв транспорта. + + Прогон длится часами, и ssh рвётся: живьём поймано «Connection reset by peer» + (ssh возвращает 255) прямо посреди заливки — весь прогон умирал, а несброшенный + батч терялся. Ретраить безопасно: SQL идемпотентен (batch через ON CONFLICT DO + NOTHING, карточки через ON CONFLICT (source_id,batch_id,kind) DO NOTHING). + + Ретраится ТОЛЬКО транспорт (ssh 255). Ошибка самого psql (ON_ERROR_STOP, любой + другой код) — это дефект данных или SQL, её повтор не лечит: поднимаем сразу. + """ cmd = [ "ssh", ssh_host, f"docker exec -i {container} psql -U {db_user} -d {db_name} " "-v ON_ERROR_STOP=1 -f -", ] - proc = subprocess.run(cmd, input=sql.encode("utf-8"), capture_output=True) - out = (proc.stdout + proc.stderr).decode("utf-8", "replace").strip() - if proc.returncode != 0: - raise RuntimeError(f"psql через ssh вернул {proc.returncode}:\n{out}") - if out: - print(f" psql: {out}", flush=True) + for i in range(attempts): + proc = subprocess.run(cmd, input=sql.encode("utf-8"), capture_output=True) + out = (proc.stdout + proc.stderr).decode("utf-8", "replace").strip() + if proc.returncode == 0: + if out: + print(f" psql: {out}", flush=True) + return + if proc.returncode != 255 or i == attempts - 1: + raise RuntimeError(f"psql через ssh вернул {proc.returncode}:\n{out}") + tail = out.splitlines()[-1] if out else "без вывода" + print(f" ssh оборвался ({tail}), повтор заливки {i + 2}/{attempts}", flush=True) + time.sleep(15.0 * (i + 1)) # --- накопитель карточек --------------------------------------------------- -- 2.45.3