Metadata-Version: 2.1
Name: channels-zmq
Version: 0.1.0
Summary: A channel layer based on ZMQ
Home-page: https://github.com/franciscoda/channels_zmq/
Author: Francisco Altoe
License: GPLv3
Platform: any
Classifier: Development Status :: 4 - Beta
Classifier: Programming Language :: Python
Description-Content-Type: text/markdown; charset=UTF-8
License-File: LICENSE.txt
Requires-Dist: pyzmq (>=23.2.1)
Requires-Dist: channels
Requires-Dist: importlib-metadata ; python_version < "3.8"
Provides-Extra: testing
Requires-Dist: setuptools ; extra == 'testing'
Requires-Dist: pytest ; extra == 'testing'
Requires-Dist: pytest-cov ; extra == 'testing'
Requires-Dist: pytest-django ; extra == 'testing'
Requires-Dist: pytest-asyncio ; extra == 'testing'

# channels_zmq
[![Tests status](https://github.com/FranciscoDA/channels_zmq/actions/workflows/tests.yml/badge.svg)](https://github.com/FranciscoDA/channels_zmq/actions/workflows/tests.yml)

A channel layer implementation using ZeroMQ PUB-SUB topology.


### Installation


Install package from PyPI:
```sh
pip install channels-zmq
```


### Usage

Configure the layer in your Django settings file. You can choose one of the two implementations described below:


##### Embedded layer

```py
CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels_zmq.core.EmbeddedZmqChannelLayer",
        "CONFIG": {
            "pub_socket_address": "<SOME SOCKET ADDRESS>",
            "capacity": 100,
            "expiry": 60,
        },
    },
}
```

The embedded layer binds a ZeroMQ PUB socket inside the process that calls `send` or `group_send`.
Consumers will connect their SUB sockets to the same socket.

While this is a very lightweight implementation, it only allows a single process to call `send` and `group_send` with
the same layer.

If you need to send data created through other processes, you should create a different layer or use the [dedicated layer](#dedicated-layer).
```
               +----------------+
               |PRODUCER PROCESS|
               |----------------|
               |   PUB SOCKET   |
               +----------------+
                  ^     ^    ^
                  |     |    |
      +-----------+     |    +----------+
      |                 |               |
+------------+   +------------+   +------------+
| SUB SOCKET |   | SUB SOCKET |   | SUB SOCKET |
|------------|   |------------|   |------------|
| CONSUMER 1 |   | CONSUMER 2 |   | CONSUMER 3 |
+------------+   +------------+   +------------+
```


##### Dedicated layer

```py
CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels_zmq.core.DedicatedZmqChannelLayer",
        "CONFIG": {
            "pull_socket_address": "<DAEMON PULL SOCKET ADDRESS>",
            "pub_socket_address": "<DAEMON PUB SOCKET ADDRESS",
            "capacity": 100,
            "expiry": 60,
        },
    },
}
```

The dedicated layer connects a ZeroMQ PUSH socket to a the configured PULL socket location when you call `send` or `group_send`.
Consumers will connect to the configured PUB socket location instead.

While this implementation allows multiple processes to send messages over the same layer, it requires you to implement
a daemon process that will read messages on the PULL socket and send them through the PUB socket.

```
                  +--------------------------+
                  |      DAEMON PROCESS      |
                  |--------------------------|
                  | PUB SOCKET | PULL SOCKET |
                  +--------------------------+
                      ^   ^           ^   ^
                      |   |           |   |
      +---------------+   |           |   +----------------+
      |                   |           |                    |
+------------+   +------------+   +-------------+   +-------------+
| SUB SOCKET |   | SUB SOCKET |   | PUSH SOCKET |   | PUSH SOCKET |
|------------|   |------------|   |-------------|   |-------------|
| CONSUMER 1 |   | CONSUMER 2 |   | PRODUCER 1  |   | PRODUCER 2  |
+------------+   +------------+   +-------------+   +-------------+
```

