Metadata-Version: 2.4
Name: onloq
Version: 0.2.2
Summary: Single-execution lock decorator with Redis and file-based backends.
Author-email: EightShift <the8shift@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/EightShift/onloq
Keywords: lock,decorator,redis,file,distributed,idempotency
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pywin32>=226; platform_system == "Windows"
Dynamic: license-file

# Onloq

Lightweight worker concurrency control via redis or file locks.

When multiple workers run the same task simultaneously, `Onloq` ensures only one proceeds - the rest skip silently. Supports TTL-based expiry, decorator and direct-call usage, and custom error handling.

---

## Install

```bash
pip install onloq
```

---

## Quick Start

```python
from onloq import Onloq

loq = Onloq()  # uses filesystem locks by default

@loq
def my_task():
    ...
```

```python
# Redis-backed
import redis
loq = Onloq(redis=redis.Redis())
```

---

## Usage

### Decorator

```python
@loq
def send_report():
    ...

@loq(name="custom.lock.name", ttl=60)
def sync_data():
    ...
```

### Direct call

```python
loq.execute(send_report, ttl=30)
```

---

## Options

| Parameter | Default | Description |
|---|---|---|
| `redis` | `None` | Redis client instance. Falls back to file locks if not set. |
| `locks_dir` | `tempdir/onloq_locks` | Directory for file-based lock files. |
| `ttl` | `25` | Lock lifetime in seconds. |
| `on_error` | `'raise'` | Error behavior: `'raise'`, `None` (log and suppress), or a callable `(name, exc, *args, **kwargs)`. |
| `logger` | `None` | Standard logger for warnings and errors. |

---

## Behavior

- If the lock is already held, the call **returns `None` immediately** - no waiting, no retry.
- File locks use `mtime` to enforce TTL, preventing stale locks from blocking indefinitely.
- Lock names default to `module.qualname` of the wrapped function.

---

## License

MIT
