From 5a209620155e563c85891f5fa45b61730ee106a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Tue, 28 Jul 2026 10:49:21 +0400 Subject: [PATCH] =?UTF-8?q?v1.0.99:=20fix=20all=20Flask-proxy=20in=20backg?= =?UTF-8?q?round=20thread=20=E2=80=94=20user=5Femail=20+=20app=5Fversion?= =?UTF-8?q?=20as=20params?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DOCS/HISTORY.md | 16 ++++++++++++++++ site/routes/api_test.py | 10 ++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/DOCS/HISTORY.md b/DOCS/HISTORY.md index 39b9e3f..9e20194 100644 --- a/DOCS/HISTORY.md +++ b/DOCS/HISTORY.md @@ -46,6 +46,22 @@ - Максимум 500 записей, удаление старше 1 часа - `_ts` timestamp в каждой записи +## v1.0.99 (28.07.2026) — фикс: Flask-прокси в фоновом потоке + +### Найденные ошибки +1. `get_token_info()` → `request.cookies` → в потоке нет request-контекста → RuntimeError +2. `current_app.config.get("VERSION")` → Flask-proxy → та же проблема +3. `except: pass` глушил ошибки → записи молча не сохранялись + +### Исправление +- `user_email` и `app_version` получаются в `api_test()` (где есть request) + и передаются параметрами в `_finish_op` → `save_run` +- Добавлено логирование ошибок в `save_run` (больше не глухое `pass`) + +### Урок +`py_compile` проверяет только синтаксис. Flask-прокси (`request`, `current_app`, `g`, `session`) +**не работают** в фоновых потоках. Все нужные значения — до `threading.Thread` параметрами. + ## v1.0.89 (27.07.2026) — Sonnet Rounds 1-3 + документирование ### 1. PostgreSQL connection string diff --git a/site/routes/api_test.py b/site/routes/api_test.py index b594a1d..9cc9ee5 100644 --- a/site/routes/api_test.py +++ b/site/routes/api_test.py @@ -235,7 +235,8 @@ def api_test(): # фоном ждать завершения user_email = get_token_info().get("email", "") - threading.Thread(target=_finish_op, args=(client, op_uid, instance_uid, svc_id, display_name, op_name, svc_op_id, True, get_client_id(), get_stand(), params, user_email), daemon=True).start() + app_version = current_app.config.get("VERSION", "") + threading.Thread(target=_finish_op, args=(client, op_uid, instance_uid, svc_id, display_name, op_name, svc_op_id, True, get_client_id(), get_stand(), params, user_email, app_version), daemon=True).start() return jsonify({"status": "RUNNING", "opUid": op_uid, "instanceUid": instance_uid, "displayName": display_name}) else: @@ -265,7 +266,8 @@ def api_test(): if not display_name: display_name = _get_instance_display_name(client, instance_uid) user_email = get_token_info().get("email", "") - threading.Thread(target=_finish_op, args=(client, op_uid, instance_uid, svc_id, display_name, op_name, svc_op_id, False, get_client_id(), get_stand(), is_delete, params, user_email), daemon=True).start() + app_version = current_app.config.get("VERSION", "") + threading.Thread(target=_finish_op, args=(client, op_uid, instance_uid, svc_id, display_name, op_name, svc_op_id, False, get_client_id(), get_stand(), is_delete, params, user_email, app_version), daemon=True).start() return jsonify({"status": "RUNNING", "opUid": op_uid, "instanceUid": instance_uid, "displayName": display_name}) except Exception as e: @@ -304,7 +306,7 @@ def _get_instance_display_name(client, instance_uid): return instance_uid -def _finish_op(client, op_uid, instance_uid, svc_id, display_name, op_name, svc_op_id, is_create, client_id, stand, is_delete=False, params=None, user_email=""): +def _finish_op(client, op_uid, instance_uid, svc_id, display_name, op_name, svc_op_id, is_create, client_id, stand, is_delete=False, params=None, user_email="", app_version=""): """Фоном ждать dtFinish и сохранить результат.""" import time _cleanup_op_results() # очистить старые записи перед добавлением новой @@ -354,7 +356,7 @@ def _finish_op(client, op_uid, instance_uid, svc_id, display_name, op_name, svc_ str(err) if err else "", params or {}, op.get("stages", []), - current_app.config.get("VERSION", "")) + app_version) except Exception as e: import traceback print(f"[DB] save_run FAILED: {e}", flush=True)