gunicorn/examples/dirty_example/docker-compose.yml
Benoit Chesneau 709a6ad159
feat(dirty): add stash - global shared state between workers (#3503)
* 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
2026-02-12 21:45:49 +01:00

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