Metadata-Version: 2.3
Name: caesura
Version: 1.0.0
Summary: Mid-execution distributed locking with zero boilerplate.
Keywords: serialization,locks,distributed,concurrency,decorator
Author: Wannes Vantorre
Author-email: Wannes Vantorre <vantorrewannes@gmail.com>
License: MIT
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.14
Project-URL: Homepage, https://codeberg.org/ProductionCode/caesura
Project-URL: Repository, https://codeberg.org/ProductionCode/caesura
Project-URL: Issues, https://codeberg.org/ProductionCode/caesura/issues
Description-Content-Type: text/markdown

# caesura 📜

**Mid-execution distributed locking with zero boilerplate.**

Standard distributed locks force you to wrap your entire function in a `with` block, even if you need heavy parsing or database lookups just to find out _what_ needs locking. `caesura` lets you safely acquire locks mid-execution: `yield` signals exactly where the blocking I/O happens, and the decorator manages teardown—even on crash.

```bash
uv add caesura
```

## Why

| Concept                     | Standard Context Managers       | `caesura`                               |
| :-------------------------- | :------------------------------ | :------------------------------------ |
| **Lock Boundary**           | The entire function.            | Exactly where it matters.             |
| **Deadlock Prevention**     | Manual ordering required.       | Mathematically guaranteed via tuples. |
| **Infrastructure Coupling** | High (imports Redis/Postgres).  | Zero (accepts any context manager).   |
| **Type Visibility**         | Lost behind the wrapper.        | See-through: signature & return preserved. |

## Usage

```python
import caesura

@caesura.serialize
def process_webhook(payload):
    parsed_data = heavy_json_parse(payload)  # lock-free work first

    yield redis.lock(f"user:{parsed_data.user_id}")  # hand the lock to the decorator

    db.update_balance(parsed_data.user_id)  # resumes safely locked
    return True  # locks released on return — or on crash — via Python's ExitStack
```

### Deadlock Prevention

Yield multiple resources as a `tuple`. `caesura` sorts them by their `name` (falling back to `str()`) and acquires them in an identical, deterministic order across all workers — making deadlocks mathematically impossible.

```python
@caesura.serialize
def transfer_funds(sender_id, receiver_id):
    yield (redis.lock(sender_id), redis.lock(receiver_id))  # sorted before acquiring
    db.execute_transfer(sender_id, receiver_id)
```
