Class: Vines::Cluster::PubSub
- Inherits:
-
Object
- Object
- Vines::Cluster::PubSub
- Defined in:
- lib/vines/cluster/pubsub.rb
Overview
Manages the pubsub topic list and subscribers stored in redis. When a message is published to a topic, the receiving cluster node broadcasts the message to all subscribers at all other cluster nodes.
Instance Method Summary collapse
-
#add_node(domain, node) ⇒ Object
Create a pubsub topic (a.k.a. node), in the given domain, to which messages may be published.
-
#delete_node(domain, node) ⇒ Object
Remove a pubsub topic so messages may no longer be broadcast to it.
-
#initialize(cluster) ⇒ PubSub
constructor
A new instance of PubSub.
-
#node?(domain, node) ⇒ Boolean
Return true if the pubsub topic exists and messages may be published to it.
-
#subscribe(domain, node, jid) ⇒ Object
Subscribe the JID to the pubsub topic so it will receive any messages published to it.
-
#subscribed?(domain, node, jid) ⇒ Boolean
Return true if the JID is a registered subscriber to the pubsub topic and messages published to it should be routed to the JID.
-
#subscribers(domain, node) ⇒ Object
Return a list of JIDs subscribed to the pubsub topic.
-
#unsubscribe(domain, node, jid) ⇒ Object
Unsubscribe the JID from the pubsub topic, deregistering its interest in receiving any messages published to it.
-
#unsubscribe_all(domain, jid) ⇒ Object
Unsubscribe the JID from all pubsub topics.
Constructor Details
#initialize(cluster) ⇒ PubSub
Returns a new instance of PubSub.
9 10 11 |
# File 'lib/vines/cluster/pubsub.rb', line 9 def initialize(cluster) @cluster = cluster end |
Instance Method Details
#add_node(domain, node) ⇒ Object
Create a pubsub topic (a.k.a. node), in the given domain, to which messages may be published. The domain argument will be one of the configured pubsub subdomains in conf/config.rb (e.g. games.wonderland.lit, topics.wonderland.lit, etc).
17 18 19 |
# File 'lib/vines/cluster/pubsub.rb', line 17 def add_node(domain, node) redis.sadd("pubsub:#{domain}:nodes", node) end |
#delete_node(domain, node) ⇒ Object
Remove a pubsub topic so messages may no longer be broadcast to it.
22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/vines/cluster/pubsub.rb', line 22 def delete_node(domain, node) redis.smembers("pubsub:#{domain}:subscribers_#{node}") do |subscribers| redis.multi subscribers.each do |jid| redis.srem("pubsub:#{domain}:subscriptions_#{jid}", node) end redis.del("pubsub:#{domain}:subscribers_#{node}") redis.srem("pubsub:#{domain}:nodes", node) redis.exec end end |
#node?(domain, node) ⇒ Boolean
Return true if the pubsub topic exists and messages may be published to it.
69 70 71 |
# File 'lib/vines/cluster/pubsub.rb', line 69 def node?(domain, node) @cluster.query(:sismember, "pubsub:#{domain}:nodes", node) == 1 end |
#subscribe(domain, node, jid) ⇒ Object
Subscribe the JID to the pubsub topic so it will receive any messages published to it.
36 37 38 39 40 41 42 |
# File 'lib/vines/cluster/pubsub.rb', line 36 def subscribe(domain, node, jid) jid = JID.new(jid) redis.multi redis.sadd("pubsub:#{domain}:subscribers_#{node}", jid.to_s) redis.sadd("pubsub:#{domain}:subscriptions_#{jid}", node) redis.exec end |
#subscribed?(domain, node, jid) ⇒ Boolean
Return true if the JID is a registered subscriber to the pubsub topic and messages published to it should be routed to the JID.
75 76 77 78 |
# File 'lib/vines/cluster/pubsub.rb', line 75 def subscribed?(domain, node, jid) jid = JID.new(jid) @cluster.query(:sismember, "pubsub:#{domain}:subscribers_#{node}", jid.to_s) == 1 end |
#subscribers(domain, node) ⇒ Object
Return a list of JIDs subscribed to the pubsub topic.
81 82 83 |
# File 'lib/vines/cluster/pubsub.rb', line 81 def subscribers(domain, node) @cluster.query(:smembers, "pubsub:#{domain}:subscribers_#{node}") end |
#unsubscribe(domain, node, jid) ⇒ Object
Unsubscribe the JID from the pubsub topic, deregistering its interest in receiving any messages published to it.
46 47 48 49 50 51 52 53 54 55 |
# File 'lib/vines/cluster/pubsub.rb', line 46 def unsubscribe(domain, node, jid) jid = JID.new(jid) redis.multi redis.srem("pubsub:#{domain}:subscribers_#{node}", jid.to_s) redis.srem("pubsub:#{domain}:subscriptions_#{jid}", node) redis.exec redis.scard("pubsub:#{domain}:subscribers_#{node}") do |count| delete_node(domain, node) if count == 0 end end |
#unsubscribe_all(domain, jid) ⇒ Object
Unsubscribe the JID from all pubsub topics. This is useful when the JID’s session ends by logout or disconnect.
59 60 61 62 63 64 65 66 |
# File 'lib/vines/cluster/pubsub.rb', line 59 def unsubscribe_all(domain, jid) jid = JID.new(jid) redis.smembers("pubsub:#{domain}:subscriptions_#{jid}") do |nodes| nodes.each do |node| unsubscribe(domain, node, jid) end end end |