Metadata-Version: 2.1
Name: sanic-synchro-ctx
Version: 0.1.0
Summary: Synchronize Sanic contects between instances when using multiple workers
Home-page: https://github.com/ashleysommer/sanic-synchro-ctx
License: MIT
Keywords: Linked Data,Semantic Web,RDF,Python,SHACL,Shapes,Schema,Validate
Author: Ashley Sommer
Author-email: ashleysommer@gmail.com
Requires-Python: >=3.8.0,<4.0.0
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Utilities
Provides-Extra: dev-lint
Provides-Extra: dev-type-checking
Provides-Extra: redis
Requires-Dist: aioredis[hiredis] (>=2.0.1); extra == "redis"
Requires-Dist: hiredis (>=1.0.0); extra == "redis"
Requires-Dist: sanic (>=21.9.3)
Project-URL: Repository, https://github.com/ashleysommer/sanic-synchro-ctx
Description-Content-Type: text/markdown


# Sanic-Synchro-Ctx
Plugin to provide an App context that is shared across multiple workers

Can use native python SyncManager backend, or Redis if you want. (Redis is much faster).

## Installation
```bash
$ pip3 install sanic-synchro-ctx
```

Or in a python virtualenv _(these example commandline instructions are for a Linux/Unix based OS)_
```bash
$ python3 -m virtualenv --python=python3 --no-site-packages .venv
$ source ./.venv/bin/activate
$ pip3 install sanic sanic-synchro-ctx
```

To exit the virtual enviornment:
```bash
$ deactivate
```

## Redis Extension
You can install the relevant Redis libraries for this plugin, with the installable redis extension:
```bash
$ pip3 install sanic-synchro-ctx[redis]
```
That is the same as running:
```bash
$ pip3 install "sanic-synchro-ctx" "aioredis>=2.0" "hiredis>=1.0"
```

## Compatibility
* Works with Python 3.8 and greater.
* Works with Sanic v21.9.0 and greater.
* If you are installing the redis library separately, use aioredis >= 2.0


## Usage
A very simple example, it uses the native python SyncManager backend, doesn't require a Redis connection.
```python3
from sanic_synchro_ctx import SanicSynchroCtx
app = Sanic("sample")
s = SanicSynchroCtx(app)

@app.after_server_start
def handler(app, loop=None):
    # This will only set this value if it doesn't already exist
    # So only the first worker will set this value
    app.ctx.synchro.set_default({"counter": 0})

@app.route("/inc")
def increment(request: Request):
    # atomic increment operation
    counter = request.app.ctx.synchro.increment("counter")
    print("counter: {}".format(counter), flush=True)
    return html("<p>Incremented!</p>")

@app.route("/count")
def increment(request: Request):
    # Get from shared context:
    counter = request.app.ctx.synchro.counter
    print("counter: {}".format(counter), flush=True)
    return html(f"<p>count: {counter}</p>")

app.run("127.0.0.1", port=8000, workers=8)
```

Redis example:
```python3
from sanic_synchro_ctx import SanicSynchroCtx
redis = aioredis.from_url("redis://localhost")
app = Sanic("sample")
s = SanicSynchroCtx(app, backend="redis", redis_client=redis)

@app.after_server_start
async def handler(app, loop=None):
    # This will only set this value if it doesn't already exist
    # So only the first worker will set this value
    await app.ctx.synchro.set_default({"counter": 0})

@app.route("/inc")
async def increment(request: Request):
    # atomic increment operation
    counter = await request.app.ctx.synchro.increment("counter")
    print(f"counter: {counter}", flush=True)
    return html("<p>Incremented!</p>")

@app.route("/count")
async def increment(request: Request):
    # Get from shared context:
    counter = await request.app.ctx.synchro.counter
    print(f"counter: {counter}", flush=True)
    return html(f"<p>count: {counter}</p>")

app.run("127.0.0.1", port=8000, workers=8)
```


## Changelog
A comprehensive changelog is kept in the [CHANGELOG file](https://github.com/ashleysommer/sanic-synchro-ctx/blob/master/CHANGELOG.md).


## Benchmarks
I've done some basic benchmarks. SyncManager works surprisingly well, but Redis backend is much faster. 


## License
This repository is licensed under the MIT License. See the [LICENSE deed](https://github.com/ashleysommer/sanic-synchro-ctx/blob/master/LICENSE.txt) for details.


