class EventMachine::Hiredis::PubsubClient
Constants
- PING_CHANNEL
- PUBSUB_MESSAGES
Public Class Methods
EventMachine::Hiredis::BaseClient::new
# File lib/em-hiredis/pubsub_client.rb, line 7 def initialize(host='localhost', port='6379', password=nil, db=nil) @subs, @psubs = [], [] @pubsub_defs = Hash.new { |h,k| h[k] = [] } super end
Public Instance Methods
EventMachine::Hiredis::BaseClient#connect
# File lib/em-hiredis/pubsub_client.rb, line 13 def connect @sub_callbacks = Hash.new { |h, k| h[k] = [] } @psub_callbacks = Hash.new { |h, k| h[k] = [] } # Resubsubscribe to channels on reconnect on(:reconnected) { raw_send_command(:subscribe, @subs) if @subs.any? raw_send_command(:psubscribe, @psubs) if @psubs.any? } super end
Pubsub connections to not support even the PING command, but it is useful, especially with read-only connections like pubsub, to be able to check that the TCP connection is still usefully alive.
This is not particularly elegant, but it's probably the best we can do for now. Ping support for pubsub connections is being considerred: github.com/antirez/redis/issues/420
# File lib/em-hiredis/pubsub_client.rb, line 138 def ping subscribe(PING_CHANNEL).callback { unsubscribe(PING_CHANNEL) } end
Pattern subscribe to a pubsub channel
If an optional proc / block is provided then it will be called (with the channel name and message) when a message is received on a matching channel
@return [Deferrable] Redis psubscribe call
# File lib/em-hiredis/pubsub_client.rb, line 86 def psubscribe(pattern, proc = nil, &block) if cb = proc || block @psub_callbacks[pattern] << cb end @psubs << pattern raw_send_command(:psubscribe, [pattern]) return pubsub_deferrable(pattern) end
Pattern unsubscribe all callbacks for a given pattern
@return [Deferrable] Redis punsubscribe call
# File lib/em-hiredis/pubsub_client.rb, line 99 def punsubscribe(pattern) @psub_callbacks.delete(pattern) @psubs.delete(pattern) raw_send_command(:punsubscribe, [pattern]) return pubsub_deferrable(pattern) end
Unsubscribe a given callback from a pattern. Will unsubscribe from redis if there are no remaining subscriptions on this pattern
@return [Deferrable] Succeeds when the punsubscribe has completed or
fails if callback could not be found. Note that success may happen immediately in the case that there are other callbacks for the same pattern (and therefore no punsubscription from redis is necessary)
# File lib/em-hiredis/pubsub_client.rb, line 114 def punsubscribe_proc(pattern, proc) df = EM::DefaultDeferrable.new if @psub_callbacks[pattern].delete(proc) if @psub_callbacks[pattern].any? # Succeed deferrable immediately - no need to punsubscribe df.succeed else punsubscribe(pattern).callback { |_| df.succeed } end else df.fail end return df end
Subscribe to a pubsub channel
If an optional proc / block is provided then it will be called when a message is received on this channel
@return [Deferrable] Redis subscribe call
# File lib/em-hiredis/pubsub_client.rb, line 33 def subscribe(channel, proc = nil, &block) if cb = proc || block @sub_callbacks[channel] << cb end @subs << channel raw_send_command(:subscribe, [channel]) return pubsub_deferrable(channel) end
Unsubscribe all callbacks for a given channel
@return [Deferrable] Redis unsubscribe call
# File lib/em-hiredis/pubsub_client.rb, line 46 def unsubscribe(channel) @sub_callbacks.delete(channel) @subs.delete(channel) raw_send_command(:unsubscribe, [channel]) return pubsub_deferrable(channel) end
Unsubscribe a given callback from a channel. Will unsubscribe from redis if there are no remaining subscriptions on this channel
@return [Deferrable] Succeeds when the unsubscribe has completed or
fails if callback could not be found. Note that success may happen immediately in the case that there are other callbacks for the same channel (and therefore no unsubscription from redis is necessary)
# File lib/em-hiredis/pubsub_client.rb, line 61 def unsubscribe_proc(channel, proc) df = EM::DefaultDeferrable.new if @sub_callbacks[channel].delete(proc) if @sub_callbacks[channel].any? # Succeed deferrable immediately - no need to unsubscribe df.succeed else unsubscribe(channel).callback { |_| df.succeed } end else df.fail end return df end