def run_in_thread(self, daemon=False): for channel, handler in iteritems(self.channels): if handler is None: raise PubSubError("Channel: '%s' has no handler registered") for pattern, handler in iteritems(self.patterns): if handler is None: raise PubSubError("Pattern: '%s' has no handler registered") loop = asyncio.get_event_loop() thread = PubSubWorkerThread(self, loop, daemon=daemon) thread.start() return thread
def run_in_thread(self, daemon=False): for channel, handler in iteritems(self.channels): if handler is None: raise PubSubError( "Channel: '{}' has no handler registered".format(channel)) for pattern, handler in iteritems(self.patterns): if handler is None: raise PubSubError( "Pattern: '{}' has no handler registered".format(pattern)) thread = PubSubWorkerThread(self, daemon=daemon) thread.start() return thread
async def on_connect(self, connection): "Re-subscribe to any channels and patterns previously subscribed to" # NOTE: for python3, we can't pass bytestrings as keyword arguments # so we need to decode channel/pattern names back to str strings # before passing them to [p]subscribe. if self.channels: channels = {} for k, v in iteritems(self.channels): channels[k] = v await self.subscribe(**channels) if self.patterns: patterns = {} for k, v in iteritems(self.patterns): patterns[k] = v await self.psubscribe(**patterns)
async def zaddoption(self, name, option=None, *args, **kwargs): """ Differs from zadd in that you can set either 'XX' or 'NX' option as described here: https://redis.io/commands/zadd. Only for Redis 3.0.2 or later. The following example would add four values to the 'my-key' key: redis.zaddoption('my-key', 'XX', 1.1, 'name1', 2.2, 'name2', name3=3.3, name4=4.4) redis.zaddoption('my-key', 'NX CH', name1=2.2) """ if not option: raise RedisError("ZADDOPTION must take options") options = set(opt.upper() for opt in option.split()) if options - VALID_ZADD_OPTIONS: raise RedisError("ZADD only takes XX, NX, CH, or INCR") if 'NX' in options and 'XX' in options: raise RedisError("ZADD only takes one of XX or NX") pieces = list(options) members = [] if args: if len(args) % 2 != 0: raise RedisError("ZADD requires an equal number of " "values and scores") members.extend(args) for pair in iteritems(kwargs): members.append(pair[1]) members.append(pair[0]) if 'INCR' in options and len(members) != 2: raise RedisError("ZADD with INCR only takes one score-name pair") return await self.execute_command('ZADD', name, *pieces, *members)
async def hmset(self, name, mapping): """ Set key to value within hash ``name`` for each corresponding key and value from the ``mapping`` dict. """ if not mapping: raise DataError("'hmset' with 'mapping' of length 0") items = [] for pair in iteritems(mapping): items.extend(pair) return await self.execute_command('HMSET', name, *items)
async def mset(self, *args, **kwargs): """ Sets key/values based on a mapping. Mapping can be supplied as a single dictionary argument or as kwargs. """ if args: if len(args) != 1 or not isinstance(args[0], dict): raise RedisError('MSET requires **kwargs or a single dict arg') kwargs.update(args[0]) items = [] for pair in iteritems(kwargs): items.extend(pair) return await self.execute_command('MSET', *items)
def __init__(self, sentinels, min_other_sentinels=0, sentinel_kwargs=None, **connection_kwargs): # if sentinel_kwargs isn't defined, use the socket_* options from # connection_kwargs if sentinel_kwargs is None: sentinel_kwargs = dict([(k, v) for k, v in iteritems(connection_kwargs) if k.startswith('socket_') ]) self.sentinel_kwargs = sentinel_kwargs self.sentinels = [StrictRedis(hostname, port, **self.sentinel_kwargs) for hostname, port in sentinels] self.min_other_sentinels = min_other_sentinels self.connection_kwargs = connection_kwargs
async def msetnx(self, *args, **kwargs): """ Sets key/values based on a mapping if none of the keys are already set. Mapping can be supplied as a single dictionary argument or as kwargs. Returns a boolean indicating if the operation was successful. """ if args: if len(args) != 1 or not isinstance(args[0], dict): raise RedisError('MSETNX requires **kwargs or a single ' 'dict arg') kwargs.update(args[0]) items = [] for pair in iteritems(kwargs): items.extend(pair) return await self.execute_command('MSETNX', *items)
async def mset(self, *args, **kwargs): """ Sets key/values based on a mapping. Mapping can be supplied as a single dictionary argument or as kwargs. Cluster impl: Itterate over all items and do SET on each (k,v) pair Operation is no longer atomic. """ if args: if len(args) != 1 or not isinstance(args[0], dict): raise RedisError('MSET requires **kwargs or a single dict arg') kwargs.update(args[0]) for pair in iteritems(kwargs): await self.set(pair[0], pair[1]) return True
async def subscribe(self, *args, **kwargs): """ Subscribe to channels. Channels supplied as keyword arguments expect a channel name as the key and a callable as the value. A channel's callable will be invoked automatically when a message is received on that channel rather than producing a message via ``listen()`` or ``get_message()``. """ if args: args = list_or_args(args[0], args[1:]) new_channels = {} new_channels.update(dict.fromkeys(map(self.encode, args))) for channel, handler in iteritems(kwargs): new_channels[self.encode(channel)] = handler ret_val = await self.execute_command('SUBSCRIBE', *iterkeys(new_channels)) # update the channels dict AFTER we send the command. we don't want to # subscribe twice to these channels, once for the command and again # for the reconnection. self.channels.update(new_channels) return ret_val
async def psubscribe(self, *args, **kwargs): """ Subscribes to channel patterns. Patterns supplied as keyword arguments expect a pattern name as the key and a callable as the value. A pattern's callable will be invoked automatically when a message is received on that pattern rather than producing a message via ``listen()``. """ if args: args = list_or_args(args[0], args[1:]) new_patterns = {} new_patterns.update(dict.fromkeys(map(self.encode, args))) for pattern, handler in iteritems(kwargs): new_patterns[self.encode(pattern)] = handler ret_val = await self.execute_command('PSUBSCRIBE', *iterkeys(new_patterns)) # update the patterns dict AFTER we send the command. we don't want to # subscribe twice to these patterns, once for the command and again # for the reconnection. self.patterns.update(new_patterns) return ret_val
async def zadd(self, name, *args, **kwargs): """ Set any number of score, element-name pairs to the key ``name``. Pairs can be specified in two ways: As *args, in the form of: score1, name1, score2, name2, ... or as **kwargs, in the form of: name1=score1, name2=score2, ... The following example would add four values to the 'my-key' key: redis.zadd('my-key', 1.1, 'name1', 2.2, 'name2', name3=3.3, name4=4.4) """ pieces = [] if args: if len(args) % 2 != 0: raise RedisError("ZADD requires an equal number of " "values and scores") pieces.extend(args) for pair in iteritems(kwargs): pieces.append(pair[1]) pieces.append(pair[0]) return await self.execute_command('ZADD', name, *pieces)