OpenSlides/openslides/utils/redis.py

61 lines
1.4 KiB
Python
Raw Normal View History

2019-03-27 22:51:33 +01:00
import asyncio
from typing import Any
from django.conf import settings
from . import logging
logger = logging.getLogger(__name__)
try:
import aioredis
except ImportError:
use_redis = False
else:
from channels_redis.core import ConnectionPool
# set use_redis to true, if there is a value for REDIS_ADDRESS in the settings
2019-01-06 16:22:33 +01:00
redis_address = getattr(settings, "REDIS_ADDRESS", "")
use_redis = bool(redis_address)
if use_redis:
logger.info(f"Redis address {redis_address}")
pool = ConnectionPool({"address": redis_address})
counter = 0
2019-03-27 22:51:33 +01:00
class RedisConnectionContextManager:
"""
Async context manager for connections
"""
2019-01-06 16:22:33 +01:00
# TODO: contextlib.asynccontextmanager can be used in python 3.7
2019-01-06 16:22:33 +01:00
async def __aenter__(self) -> "aioredis.RedisConnection":
2019-09-10 15:00:55 +02:00
global counter
while counter > 100:
await asyncio.sleep(0.1)
counter += 1
2019-03-27 22:51:33 +01:00
self.conn = await pool.pop()
return self.conn
async def __aexit__(self, exc_type: Any, exc: Any, tb: Any) -> None:
if exc:
logger.warn(f"Redis Exception: {exc}. Do not reuse connection...")
pool.conn_error(self.conn)
else:
pool.push(self.conn)
self.conn = None
2019-09-10 15:00:55 +02:00
global counter
counter -= 1
def get_connection() -> RedisConnectionContextManager:
"""
Returns contextmanager for a redis connection.
"""
2019-03-27 22:51:33 +01:00
return RedisConnectionContextManager()