platypush/platypush/backend/redis/__init__.py

93 lines
2.8 KiB
Python
Raw Normal View History

2018-05-14 20:09:25 +02:00
import json
from typing import Optional
2018-05-14 20:09:25 +02:00
from redis import Redis
from platypush.backend import Backend
from platypush.context import get_plugin
2018-05-14 20:09:25 +02:00
from platypush.message import Message
class RedisBackend(Backend):
"""
2018-06-26 00:16:39 +02:00
Backend that reads messages from a configured Redis queue (default:
``platypush_bus_mq``) and posts them to the application bus. Very
useful when you have plugin whose code is executed in another process
2018-05-14 20:09:25 +02:00
and can't post events or requests to the application bus.
"""
2019-12-27 19:22:48 +01:00
def __init__(self, queue='platypush_bus_mq', redis_args=None, *args, **kwargs):
2018-05-14 20:09:25 +02:00
"""
2018-06-26 00:16:39 +02:00
:param queue: Queue name to listen on (default: ``platypush_bus_mq``)
:type queue: str
2019-12-27 19:22:48 +01:00
:param redis_args: Arguments that will be passed to the redis-py constructor (e.g. host, port, password), see
https://redis-py.readthedocs.io/en/latest/
2018-06-26 00:16:39 +02:00
:type redis_args: dict
2018-05-14 20:09:25 +02:00
"""
2018-06-26 00:16:39 +02:00
2018-05-14 20:09:25 +02:00
super().__init__(*args, **kwargs)
2019-12-27 19:22:48 +01:00
if redis_args is None:
redis_args = {}
2018-05-14 20:09:25 +02:00
self.queue = queue
if not redis_args:
2019-12-27 19:22:48 +01:00
redis_plugin = get_plugin('redis')
if redis_plugin and redis_plugin.kwargs:
redis_args = redis_plugin.kwargs
2019-12-27 19:22:48 +01:00
self.redis_args = redis_args
self.redis: Optional[Redis] = None
2018-05-14 20:09:25 +02:00
2019-12-27 19:22:48 +01:00
def send_message(self, msg, queue_name=None, **kwargs):
msg = str(msg)
if queue_name:
self.redis.rpush(queue_name, msg)
else:
self.redis.rpush(self.queue, msg)
def get_message(self, queue_name=None):
queue = queue_name or self.queue
data = self.redis.blpop(queue, timeout=1)
if data is None:
return
msg = data[1].decode()
try:
msg = Message.build(msg)
2021-04-05 00:58:44 +02:00
except Exception as e:
self.logger.debug(str(e))
try:
import ast
msg = Message.build(ast.literal_eval(msg))
2021-04-05 00:58:44 +02:00
except Exception as ee:
self.logger.debug(str(ee))
try:
msg = json.loads(msg)
2021-04-05 00:58:44 +02:00
except Exception as eee:
self.logger.exception(eee)
return msg
2018-05-14 20:09:25 +02:00
def run(self):
super().run()
self.logger.info('Initialized Redis backend on queue {} with arguments {}'.format(self.queue, self.redis_args))
2018-05-14 20:09:25 +02:00
with Redis(**self.redis_args) as self.redis:
while not self.should_stop():
try:
msg = self.get_message()
if not msg:
continue
self.logger.info('Received message on the Redis backend: {}'.format(msg))
self.on_message(msg)
except Exception as e:
self.logger.exception(e)
2018-05-14 20:09:25 +02:00
self.logger.info('Redis backend terminated')
2018-05-14 20:09:25 +02:00
# vim:sw=4:ts=4:et: