fix: code review #2 — _cfg.DELAY + VERSION в config/loader + мёртвые импорты
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# polygon v0.2.0
|
||||
# polygon v0.2.2
|
||||
|
||||
Эмулятор REST API облачной платформы Nubes для интеграционных тестов app-autotest.
|
||||
|
||||
@@ -14,12 +14,27 @@ polygon/
|
||||
│ ├── test_converter.py # 10 юнит-тестов from_stands.py
|
||||
│ └── test_state_machine.py # 9 юнит-тестов state_machine.py
|
||||
└── site/
|
||||
├── app.py # Flask (17 эндпоинтов)
|
||||
├── app.py # Flask: только blueprint'ы + app.run() (57 строк)
|
||||
├── routes/ # 6 blueprint-файлов по доменам
|
||||
│ ├── root.py # /health, /
|
||||
│ ├── services_routes.py# /api/v1/svc/services
|
||||
│ ├── instances_routes.py# /api/v1/svc/instances
|
||||
│ ├── operations_routes.py# /api/v1/svc/instanceOperations/*
|
||||
│ ├── run.py # /api/v1/svc/instanceOperations/<uid>/run
|
||||
│ └── mock_routes.py # /api/v1/svc/_mock/*
|
||||
├── mock_state.py # MockState: instances, operations, op_params
|
||||
├── state_machine.py # apply_effect() — мутация состояния
|
||||
├── config_loader.py # загрузка services/*.yaml
|
||||
├── config/
|
||||
│ └── loader.py # загрузка YAML + SERVICES/OPS_INDEX/DELAY/VERSION
|
||||
├── utils/
|
||||
│ ├── now.py # now() — UTC ISO с 'Z'
|
||||
│ └── pluralize.py # pluralize() — плюрализация
|
||||
├── from_stands.py # конвертер STANDS YAML → polygon config
|
||||
└── services/ # 37 YAML-конфигов (сгенерированы)
|
||||
├── static/
|
||||
│ └── style.css # тёмная тема
|
||||
├── templates/
|
||||
│ └── index.html # Jinja2-шаблон
|
||||
└── services/ # YAML-конфиги (сгенерированы from_stands.py)
|
||||
```
|
||||
|
||||
⛔ **Ровно 1 gunicorn-воркер.** Состояние в памяти, не shared.
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
polygon v0.2.1 — Mock Nubes API.
|
||||
polygon v0.2.2 — Mock Nubes API.
|
||||
Эмулятор REST API облачной платформы Nubes для интеграционных тестов.
|
||||
|
||||
Blueprint'ы (каждый — отдельный файл в routes/):
|
||||
@@ -35,7 +35,8 @@ from routes.operations_routes import bp as operations_bp
|
||||
from routes.run import bp as run_bp
|
||||
from routes.mock_routes import bp as mock_bp
|
||||
|
||||
VERSION = "0.2.2"
|
||||
# Версия — единый источник правды в config/loader.py
|
||||
from config.loader import VERSION
|
||||
|
||||
# Flask-приложение с Jinja2-шаблонами и статикой
|
||||
app = Flask(__name__, template_folder="templates", static_folder="static")
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
config/loader.py — загрузка сервисов и глобальные конфигурационные переменные.
|
||||
|
||||
Этот модуль загружает все YAML-конфиги сервисов при первом импорте и хранит их
|
||||
как модульные переменные. Все routes/*.py импортируют SERVICES, OPS_INDEX, DELAY
|
||||
отсюда — без дублирования загрузки и без циклических импортов.
|
||||
как модульные переменные. Все routes/*.py импортируют SERVICES, OPS_INDEX, DELAY,
|
||||
VERSION отсюда — без дублирования загрузки и без циклических импортов.
|
||||
|
||||
Переменные модуля (вычисляются ОДИН раз при старте):
|
||||
VERSION — str, версия полигона (единая для app.py и root.py)
|
||||
SERVICES — {service_id: service_def} все сервисы
|
||||
OPS_INDEX — {svcOperationId: service_def} поиск сервиса по ID операции
|
||||
DELAY — float, задержка операции из MOCK_OP_DELAY (по умолчанию 0.1)
|
||||
@@ -64,4 +65,10 @@ SERVICES, OPS_INDEX = _load_all()
|
||||
|
||||
# Задержка операции в секундах (для синхронного sleep в /run).
|
||||
# Меняется на лету через POST /_mock/delay/<s> — см. mock_routes.py.
|
||||
# ⛔ Импортировать ТОЛЬКО через `import config.loader as _cfg` и читать `_cfg.DELAY` —
|
||||
# иначе float копируется по значению и не реагирует на изменение.
|
||||
DELAY = float(os.getenv("MOCK_OP_DELAY", "0.1"))
|
||||
|
||||
# Версия полигона — единый источник правды для app.py и routes/root.py.
|
||||
# Меняется при КАЖДОМ изменении кода.
|
||||
VERSION = "0.2.2"
|
||||
|
||||
@@ -11,8 +11,7 @@ Blueprint "mock" с префиксом /api/v1/svc/_mock.
|
||||
from flask import Blueprint, jsonify
|
||||
|
||||
import mock_state
|
||||
from config.loader import SERVICES, DELAY as _DELAY
|
||||
import config.loader as _cfg # для модификации модульной переменной DELAY
|
||||
import config.loader as _cfg # для чтения/записи модульных переменных DELAY, SERVICES
|
||||
|
||||
bp = Blueprint("mock", __name__, url_prefix="/api/v1/svc/_mock")
|
||||
|
||||
@@ -73,7 +72,7 @@ def mock_services():
|
||||
не дёргая реальный /api/v1/svc/services.
|
||||
"""
|
||||
result = {}
|
||||
for svc_id, svc_def in SERVICES.items():
|
||||
for svc_id, svc_def in _cfg.SERVICES.items():
|
||||
result[str(svc_id)] = {
|
||||
"name": svc_def.get("name", ""),
|
||||
"displayName": svc_def.get("service_display_name", ""),
|
||||
|
||||
@@ -8,10 +8,9 @@ Blueprint "operations" с префиксом /api/v1/svc.
|
||||
POST /instanceOperationCfsParams — установить параметр
|
||||
GET /instanceOperations/<uid>/validate-cfs — пустое тело, 200
|
||||
|
||||
ВАЖНО: порядок маршрутов в蓝图 критичен.
|
||||
/instanceOperations/default/<int:op_id> ДОЛЖЕН быть выше
|
||||
/instanceOperations/<uid>
|
||||
Иначе Flask распарсит "default" как uid и уйдёт не в тот обработчик.
|
||||
Порядок маршрутов: default/<int:op_id> (целое число) и <uid> (строка UUID)
|
||||
различаются Flask/Werkzeug автоматически — конфликта нет, но default размещён
|
||||
выше для ясности.
|
||||
"""
|
||||
|
||||
from flask import Blueprint, jsonify, make_response, request
|
||||
|
||||
+6
-7
@@ -8,11 +8,10 @@ Blueprint "root" регистрируется в app.py БЕЗ url_prefix.
|
||||
from flask import Blueprint, render_template
|
||||
|
||||
import mock_state
|
||||
from config.loader import SERVICES, DELAY
|
||||
from utils.now import now as _now
|
||||
import config.loader as _cfg
|
||||
|
||||
# Версия — показывается на HTML-странице и в healthcheck (опционально)
|
||||
VERSION = "0.2.2"
|
||||
# Версия — из config/loader.py (единый источник правды)
|
||||
VERSION = _cfg.VERSION
|
||||
|
||||
# Blueprint без префикса — роуты /health и / будут на корне домена
|
||||
bp = Blueprint("root", __name__)
|
||||
@@ -36,12 +35,12 @@ def index():
|
||||
текущую задержку операций. Использует Jinja2-шаблон templates/index.html
|
||||
и внешний CSS из static/style.css.
|
||||
"""
|
||||
svc_count = len(SERVICES)
|
||||
svc_count = len(_cfg.SERVICES)
|
||||
inst_count = len(mock_state.state.instances)
|
||||
return render_template(
|
||||
"index.html",
|
||||
version=VERSION,
|
||||
version=_cfg.VERSION,
|
||||
svc_count=svc_count,
|
||||
inst_count=inst_count,
|
||||
delay=DELAY,
|
||||
delay=_cfg.DELAY,
|
||||
)
|
||||
|
||||
+5
-4
@@ -14,7 +14,7 @@ from flask import Blueprint, jsonify
|
||||
|
||||
import mock_state
|
||||
import state_machine
|
||||
from config.loader import SERVICES, DELAY
|
||||
import config.loader as _cfg
|
||||
from utils.now import now as _now
|
||||
|
||||
bp = Blueprint("run", __name__, url_prefix="/api/v1/svc")
|
||||
@@ -48,12 +48,13 @@ def run_operation(uid):
|
||||
op["dtStart"] = _now()
|
||||
|
||||
# Эмулируем задержку выполнения (по умолчанию 0.1с)
|
||||
if DELAY > 0:
|
||||
time.sleep(DELAY)
|
||||
# ⛔ _cfg.DELAY — модульная переменная, может меняться через /_mock/delay
|
||||
if _cfg.DELAY > 0:
|
||||
time.sleep(_cfg.DELAY)
|
||||
|
||||
# Применить эффект операции к состоянию инстанса
|
||||
# (create → running+params, delete → удалить, modify → мерж params, ...)
|
||||
state_machine.apply_effect(uid, mock_state.state, SERVICES)
|
||||
state_machine.apply_effect(uid, mock_state.state, _cfg.SERVICES)
|
||||
|
||||
# Фиксируем время завершения — операция выполнена успешно
|
||||
op["dtFinish"] = _now()
|
||||
|
||||
@@ -29,7 +29,7 @@ def apply_effect(op_uid, mock_state, services):
|
||||
Args:
|
||||
op_uid — UUID операции
|
||||
mock_state — экземпляр MockState
|
||||
services — {service_id: service_def} из config_loader
|
||||
services — {service_id: service_def} из config/loader.py
|
||||
"""
|
||||
op = mock_state.operations.get(op_uid)
|
||||
if not op:
|
||||
|
||||
Reference in New Issue
Block a user