Exemplo n.º 1
0
def get_toredis_client():
    redis_client = Client(host=settings.redis_host,
                          port=settings.redis_port,
                          selected_db=settings.redis_db,
                          password=settings.redis_password)
    redis_client.connect()
    return redis_client
Exemplo n.º 2
0
class MessageHandler(WebSocketHandler):
    def __init__(self, *args, **kwargs):
        super(MessageHandler, self).__init__(*args, **kwargs)
        self.redis = Client()
        self.redis.connect()

    def get_current_user(self):
        user = self.get_secure_cookie("user")
        if user is None:
            return ''
        else:
            return user.strip('" ')

    def on_message(self, msg):
        msginfo = loads(msg)
        #listens for handshake from page
        if "user:" in msginfo['msg']:
            self.channel = msginfo['msg'].split(':')[1]
            #need to split the rest off to new func so it can be asynchronous
            self.listen()

    # Decorator turns the function into an asynchronous generator object
    @tornado.gen.engine
    def listen(self):
        #runs task given, with the yield required to get returned value
        #equivalent of callback/wait pairing from tornado.gen
        yield tornado.gen.Task(self.redis.subscribe, self.channel)
        if not self.redis.subscribed:
            self.write_message('ERROR IN SUBSCRIPTION')
        #listen from tornadoredis makes the listen object asynchronous
        #if using standard redis lib, it blocks while listening
        self.redis.listen(self.callback)
        # Try and fight race condition by loading from redis after listen
        # started need to use std redis lib because tornadoredis is in
        # subscribed state
        oldmessages = r_server.lrange(self.channel + ':messages', 0, -1)
        if oldmessages is not None:
            for message in oldmessages:
                self.write_message(message)

    def callback(self, msg):
        if msg.kind == 'message':
            self.write_message(str(msg.body))

    @tornado.gen.engine
    def on_close(self):
        yield tornado.gen.Task(self.redis.unsubscribe, self.channel)
        self.redis.disconnect()
Exemplo n.º 3
0
class MessageHandler(WebSocketHandler):
    def __init__(self, *args, **kwargs):
        super(MessageHandler, self).__init__(*args, **kwargs)
        self.redis = Client()
        self.redis.connect()

    def get_current_user(self):
        user = self.get_secure_cookie("user")
        if user == None:
            return ''
        else:
            return user.strip('" ')

    def on_message(self, msg):
        msginfo = loads(msg)
        #listens for handshake from page
        if "user:" in msginfo['msg']:
            self.channel = msginfo['msg'].split(':')[1]
            #need to split the rest off to new func so it can be asynchronous
            self.listen()

    #decorator turns the function into an asynchronous generator object
    @tornado.gen.engine
    def listen(self):
        #runs task given, with the yield required to get returned value
        #equivalent of callback/wait pairing from tornado.gen
        yield tornado.gen.Task(self.redis.subscribe, self.channel)
        if not self.redis.subscribed:
            self.write_message('ERROR IN SUBSCRIPTION')
        #listen from tornadoredis makes the listen object asynchronous
        #if using standard redis lib, it blocks while listening
        self.redis.listen(self.callback)
        #try and fight race condition by loading from redis after listen started
        #need to use std redis lib because tornadoredis is in subscribed state
        oldmessages = r_server.lrange(self.channel + ':messages', 0, -1)
        if oldmessages != None:
            for message in oldmessages:
                self.write_message(message)

    def callback(self, msg):
        if msg.kind == 'message':
            self.write_message(str(msg.body))

    @tornado.gen.engine
    def on_close(self):
        yield tornado.gen.Task(self.redis.unsubscribe, self.channel)
        self.redis.disconnect()
Exemplo n.º 4
0
class RedisSubscriber:
    _instance = None
    _lock = Lock()

    def __init__(self):
        worker_logger.info('Initialized Redis Subscriber instance')
        self._client = Client(host=REDIS_HOST, port=int(REDIS_PORT))
        self._subscribers = {}
        self._listen()

    def __del__(self):
        worker_logger.info('Redis Subscriber was successfully destroyed')

    @classmethod
    def instance(cls):
        with cls._lock:
            if cls._instance is None:
                cls._instance = RedisSubscriber()
        return cls._instance

    def subscribe(self, channel_key, callback):
        worker_logger.info(
            'Subscribing channel - %s , with the callback - %s' %
            (channel_key, callback.__name__))
        self._subscribers.update({channel_key: callback})

    def unsubscribe(self, channel_key):
        worker_logger.info("Unsubscribing from channel - %s" % channel_key)
        if channel_key in self._subscribers:
            del self._subscribers[channel_key]

    @tornado.gen.engine
    def _listen(self):
        self._client.connect()
        yield tornado.gen.Task(
            self._client.psubscribe,
            "__keyspace*:%s" % (REDIS_GENERAL_CHANNEL % '*'))
        self._client.listen(self._message_handler)

    def _message_handler(self, message):
        if message.kind == 'pmessage':
            channel_key = re.search(REDIS_GENERAL_CHANNEL % '(.*)',
                                    message.channel)
            channel_callbacks = []
            if channel_key is not None:
                channel_key = channel_key.group(0)
                if channel_key in self._subscribers:
                    channel_callbacks[0] = self._subscribers.get(channel_key)
                else:
                    for subscriber_channel_key in self._subscribers.keys():
                        re_channel_key = subscriber_channel_key.replace(
                            '*', '.*')
                        if re.match(re_channel_key, channel_key):
                            channel_callbacks.append(
                                self._subscribers.get(subscriber_channel_key))
            if len(channel_callbacks):
                for channel_callback in channel_callbacks:
                    try:
                        tornado.ioloop.IOLoop.instance().call_later(
                            callback=channel_callback,
                            delay=0,
                            message=message)
                    except Exception as e:
                        worker_logger.warn('Failed to run channel callback')
                        worker_logger.exception(e)