mirror of
https://github.com/frappe/gunicorn.git
synced 2026-07-01 18:21:30 +08:00
* feat(dirty): add stash - global shared state between workers
Add a simple key-value store (stash) that allows dirty workers to share
state through the arbiter. Tables are stored directly in arbiter memory
for fast access and simplicity.
Features:
- Auto-create tables on first access
- Dict-like interface via stash.table()
- Pattern matching for keys (glob patterns)
- Module-level API: stash.put(), stash.get(), stash.delete(), etc.
Usage:
from gunicorn.dirty import stash
stash.put("sessions", "user:1", {"name": "Alice"})
user = stash.get("sessions", "user:1")
# Or dict-like
sessions = stash.table("sessions")
sessions["user:1"] = {"name": "Alice"}
New files:
- gunicorn/dirty/stash.py - Client API and StashTable class
- Protocol additions for MSG_TYPE_STASH and STASH_OP_* codes
Note: Tables are ephemeral - lost if arbiter restarts.
* test(dirty): add tests for stash protocol and encoding
Test coverage for:
- Stash message creation and encoding
- Protocol constants (MSG_TYPE_STASH, STASH_OP_*)
- Error classes (StashError, StashTableNotFoundError, StashKeyNotFoundError)
- StashTable dict-like interface
- Edge cases: unicode, complex values, special patterns
* example(dirty): add stash usage example and integration tests
- Add SessionApp to dirty_app.py demonstrating stash usage
- Add /session/* endpoints to wsgi_app.py
- Add test_stash_integration.py with Docker tests
- Update docker-compose.yml with stash-test service
- Fix: Set GUNICORN_DIRTY_SOCKET in dirty arbiter for worker access
* docs(dirty): add stash documentation
67 lines
1.9 KiB
YAML
67 lines
1.9 KiB
YAML
#
|
|
# This file is part of gunicorn released under the MIT license.
|
|
# See the NOTICE for more information.
|
|
|
|
services:
|
|
# Run the example tests (protocol, dirty app, worker integration)
|
|
tests:
|
|
build:
|
|
context: ../..
|
|
dockerfile: examples/dirty_example/Dockerfile
|
|
command: >
|
|
bash -c "
|
|
echo '=== Running Protocol Tests ===' &&
|
|
python examples/dirty_example/test_protocol.py &&
|
|
echo '' &&
|
|
echo '=== Running Dirty App Tests ===' &&
|
|
python examples/dirty_example/test_dirty_app.py &&
|
|
echo '' &&
|
|
echo '=== Running Worker Integration Tests ===' &&
|
|
python examples/dirty_example/test_worker_integration.py &&
|
|
echo '' &&
|
|
echo '=== All tests passed! ==='
|
|
"
|
|
|
|
# Run the full gunicorn server with dirty workers
|
|
server:
|
|
build:
|
|
context: ../..
|
|
dockerfile: examples/dirty_example/Dockerfile
|
|
ports:
|
|
- "8001:8000"
|
|
environment:
|
|
- GUNICORN_BIND=0.0.0.0:8000
|
|
command: >
|
|
gunicorn examples.dirty_example.wsgi_app:app
|
|
-c examples/dirty_example/gunicorn_conf.py
|
|
healthcheck:
|
|
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/')"]
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 5
|
|
start_period: 10s
|
|
|
|
# Run integration test against the server
|
|
integration-test:
|
|
build:
|
|
context: ../..
|
|
dockerfile: examples/dirty_example/Dockerfile
|
|
depends_on:
|
|
server:
|
|
condition: service_healthy
|
|
environment:
|
|
- TEST_BASE_URL=http://server:8000
|
|
command: python examples/dirty_example/test_integration.py
|
|
|
|
# Run stash integration test against the server
|
|
stash-test:
|
|
build:
|
|
context: ../..
|
|
dockerfile: examples/dirty_example/Dockerfile
|
|
depends_on:
|
|
server:
|
|
condition: service_healthy
|
|
environment:
|
|
- TEST_BASE_URL=http://server:8000
|
|
command: python examples/dirty_example/test_stash_integration.py
|