# ZeroMqThreadPool

A dynamic ZMQ-based thread pool for the e-deploy ecosystem. It manages DEALER worker threads that connect to a frontend ROUTER socket, with automatic scaling (create on demand, remove when idle).

## Installation

```bash
pip install ZeroMqThreadPool --extra-index-url https://pip.e-deploy.com.br
```

## Usage

Subclass `WorkerThread` and implement `do_work(data)` and `create_worker_thread()`:

```python
from zeromqthreadpool import WorkerThread, ThreadPoolParameters, ZeroMqThreadPool


class MyWorker(WorkerThread):
    def do_work(self, data):
        # Process the message
        return b"OK"


class MyThreadPool(ZeroMqThreadPool):
    def create_worker_thread(self, address, context):
        return MyWorker(address, context)


params = ThreadPoolParameters(
    name="my-pool",
    initial_count=4,
    max_count=16,
    idle_timeout=30000,
    monitor_timeout=5000,
)

pool = MyThreadPool(frontend_address="tcp://127.0.0.1:5555", parameters=params)
pool.start()
```

## Configuration

| Parameter         | Description                                                |
| ----------------- | ---------------------------------------------------------- |
| `name`            | Pool name prefix for thread/socket identity                |
| `initial_count`   | Starting number of workers                                 |
| `max_count`       | Maximum workers allowed                                    |
| `idle_timeout`    | Milliseconds before an idle worker is eligible for removal |
| `monitor_timeout` | Milliseconds between monitor cycles                        |

### Environment Variables

| Variable                    | Description                                                                                                                         |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `ZMQ_SOCKET_CLOSE_STRATEGY` | `DISCONNECT` (default): calls `disconnect()` + `close(linger=0)` to force TCP FD teardown. Any other value: `close(linger=N)` only. |

## How It Works

- **Worker threads** use `zmq.DEALER` sockets identified as `Worker-{uuid}`, connecting to a frontend ROUTER.
- A **monitor thread** runs periodically and scales the pool: creates new workers when all are busy (up to `max_count`), stops idle workers when the pool exceeds `initial_count`.
- Workers follow a lifecycle protocol: `READY` on start, `DYING` + final reply on shutdown, `DIED` on exit.

## Requirements

- Python >= 3.8
- pyzmq ~= 26.2
