feature: архитектура v2 — api + очередь + worker, удержание окна браузера (#78)
- Сервис api (FastAPI, без Chrome): POST /v2/tasks, GET /v2/tasks/{id} (доступ по cookie
сессии), DELETE /v2/sessions/current; /v1/solve — прежний контракт поверх очереди.
- Сервис worker (dramatiq + RabbitMQ): слоты браузера, окна сессий между задачами
(browser_idle_timeout 0–120 мин, простой — TTL ключа в Redis), heartbeat.
- Маршрутизация задач сессии в персональную очередь воркера с открытым окном.
- Redis: задачи, результаты (RESULT_TTL_HOURS), окна, воркеры. Прокси и ключ 2captcha
в Redis не сохраняются.
- Движок: AsyncStealthySession.run() — действия на текущей странице без навигации.
- Два образа (robotex-api, robotex-worker), compose с rabbitmq и redis,
make up/down/logs/smoke, релиз собирает все образы.
- Тесты: api + worker в одном процессе (fakeredis), настоящий воркер dramatiq на
StubBroker, браузерные тесты на новой схеме, smoke для запущенного стенда.
- Документация: README, API (v2), Deployment, Usage.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
fe509c25c3
commit
7b511d5d38
38 files changed
+2142
-545
No files matched your search
@@ -5,10 +5,16 @@ WHEELS_DIR := wheels
|
||||
REQUIREMENTS := requirements.txt
|
||||
ver ?= latest
|
||||
|
||||
MAKECMDGOALS_TARGETS := install freeze wheels sync sync-offline clean help build release sync-dev test test-browser
|
||||
MAKECMDGOALS_TARGETS := install freeze wheels sync sync-offline clean help build release sync-dev test test-browser up down logs smoke
|
||||
PKG := $(filter-out $(MAKECMDGOALS_TARGETS),$(MAKECMDGOALS))
|
||||
|
||||
.PHONY: install freeze wheels sync sync-offline clean help venv build release sync-dev test test-browser
|
||||
.PHONY: install freeze wheels sync sync-offline clean help venv build release sync-dev test test-browser up down logs smoke
|
||||
|
||||
# образы сервисов: api — без Chrome, worker — Chrome + Xvfb; rabbitmq и redis — сторонние, кладутся в релиз
|
||||
API_IMAGE := robotex-api
|
||||
WORKER_IMAGE := robotex-worker
|
||||
DEPS_IMAGES := rabbitmq:4.1-alpine redis:8.2-alpine
|
||||
API_URL ?= http://localhost:8000
|
||||
|
||||
help:
|
||||
@echo "make install <pkg> [<pkg> ...] - установить пакет(ы) в $(VENV), обновить $(REQUIREMENTS), собрать wheel в $(WHEELS_DIR)/"
|
||||
@@ -17,8 +23,12 @@ help:
|
||||
@echo "make freeze - перезаписать $(REQUIREMENTS) текущим состоянием окружения"
|
||||
@echo "make wheels - собрать wheel для всех пакетов из $(REQUIREMENTS)"
|
||||
@echo "make clean - удалить $(WHEELS_DIR)/"
|
||||
@echo "make build [ver=latest] - собрать docker-образ robotex:<ver>"
|
||||
@echo "make release ver=<ver> - собрать образ и пакет для деплоя в build/<ver>/ (compose, .env, образ .tar.gz)"
|
||||
@echo "make build [ver=latest] - собрать образы $(API_IMAGE):<ver> и $(WORKER_IMAGE):<ver>"
|
||||
@echo "make release ver=<ver> - собрать образы и пакет для деплоя в build/<ver>/ (compose, .env, образы .tar.gz)"
|
||||
@echo "make up - собрать и запустить локально: api, worker, rabbitmq, redis"
|
||||
@echo "make down - остановить локальный стенд"
|
||||
@echo "make logs - логи api и worker"
|
||||
@echo "make smoke [API_URL=...] - проверить запущенный стенд: /health, /v1/solve, /v2/tasks, удержание окна"
|
||||
@echo "make sync-dev - установить зависимости для тестов (requirements-dev.txt)"
|
||||
@echo "make test - юнит-тесты без браузера"
|
||||
@echo "make test-browser [ver=latest] - собрать образ и прогнать сквозные тесты с Chrome в Docker (нужна сеть)"
|
||||
@@ -53,8 +63,20 @@ clean:
|
||||
rm -rf $(WHEELS_DIR)
|
||||
|
||||
build:
|
||||
@echo "build an application"
|
||||
docker build -t robotex:$(ver) .
|
||||
docker build -f Dockerfile.api -t $(API_IMAGE):$(ver) .
|
||||
docker build -t $(WORKER_IMAGE):$(ver) .
|
||||
|
||||
up: build
|
||||
docker compose up -d
|
||||
|
||||
down:
|
||||
docker compose down
|
||||
|
||||
logs:
|
||||
docker compose logs -f api worker
|
||||
|
||||
smoke:
|
||||
$(PYTHON) tests/smoke.py $(API_URL)
|
||||
|
||||
sync-dev: venv
|
||||
$(PIP) install -r requirements-dev.txt
|
||||
@@ -66,7 +88,7 @@ test-browser: build
|
||||
docker run --rm --shm-size=2g \
|
||||
-v $(CURDIR)/tests:/app/tests:ro -v $(CURDIR)/pytest.ini:/app/pytest.ini:ro \
|
||||
-v $(CURDIR)/requirements-dev.txt:/app/requirements-dev.txt:ro \
|
||||
-w /app robotex:$(ver) sh -c 'pip install -q --user -r requirements-dev.txt && \
|
||||
-w /app $(WORKER_IMAGE):$(ver) sh -c 'pip install -q --user -r requirements-dev.txt && \
|
||||
xvfb-run -a --server-args="-screen 0 1920x1080x24" python -m pytest -m browser -p no:cacheprovider -s'
|
||||
|
||||
RELEASE_DIR := build/$(ver)
|
||||
@@ -80,9 +102,11 @@ endif
|
||||
release: build
|
||||
@echo "make release $(ver) -> $(RELEASE_DIR)/"
|
||||
@mkdir -p $(RELEASE_DIR)
|
||||
sed 's|image: robotex:.*|image: robotex:$(ver)|' docker-compose.prod.yml > $(RELEASE_DIR)/docker-compose.yml
|
||||
sed -e 's|image: $(API_IMAGE):.*|image: $(API_IMAGE):$(ver)|' -e 's|image: $(WORKER_IMAGE):.*|image: $(WORKER_IMAGE):$(ver)|' \
|
||||
docker-compose.prod.yml > $(RELEASE_DIR)/docker-compose.yml
|
||||
cp dot_env $(RELEASE_DIR)/.env
|
||||
docker save robotex:$(ver) | gzip > $(RELEASE_DIR)/robotex-$(ver).tar.gz
|
||||
for img in $(DEPS_IMAGES); do docker image inspect $$img >/dev/null 2>&1 || docker pull $$img; done
|
||||
docker save $(API_IMAGE):$(ver) $(WORKER_IMAGE):$(ver) $(DEPS_IMAGES) | gzip > $(RELEASE_DIR)/robotex-$(ver).tar.gz
|
||||
@printf '%s\n' \
|
||||
'# Robotex $(ver)' \
|
||||
'' \
|
||||
@@ -91,7 +115,7 @@ release: build
|
||||
'docker compose up -d' \
|
||||
'```' \
|
||||
'' \
|
||||
'Настройки (порт, CPU, память) — в .env.' > $(RELEASE_DIR)/README.md
|
||||
'Настройки (порт, слоты, CPU и память воркера, пароль RabbitMQ) — в .env.' > $(RELEASE_DIR)/README.md
|
||||
@echo "Готово: $(RELEASE_DIR)/"
|
||||
|
||||
# позволяет передавать имя пакета как аргумент: make install redis
|
||||
|
||||
Reference in new issue
Block a user