Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

herault detects presence and removes advertisements

  • Loading branch information...
commit dbeff025cf0965764b6aa1d273dae177e1fcd87b 1 parent a69cc93
Lee Jensen outerim authored
17 examples/actors/herault.rb
View
@@ -5,12 +5,29 @@ def self.operation_map
@operation_map ||= Hash.new { |h,k| h[k] = {} }
end
+ def self.handle_presence(who)
+ agent.protocol.subscribe_presence who do |ident, state|
+ logger.debug "Herault got presence for #{ident}, #{state}"
+ expire_operations_for(ident) if state == :unavailable
+ end
+ end
+
+ def self.expire_operations_for(ident)
+ operation_map.each do |op, idents|
+ if idents.keys.include?(ident)
+ operation_map[op].delete(ident)
+ end
+ end
+ end
+
operation "/security/advertise"
def advertise
identity = params[:identity]
params[:operations].each do |operation, resources|
add_identity_for_operation(identity, operation, resources)
end
+ self.class.handle_presence(identity)
+
finish
end
1  lib/pelvis/actor.rb
View
@@ -159,6 +159,5 @@ def fail(args)
def resources_changed
self.class.instance_eval "resources_changed"
end
-
end
end
9 lib/pelvis/protocol.rb
View
@@ -43,11 +43,16 @@ def advertise?
end
def presence_handlers
- @presence_handlers ||= {}
+ @presence_handlers ||= Hash.new { |h,k| h[k] = [] }
+ end
+
+ def call_presence_handlers(ident, state)
+ return unless presence_handlers.key?(ident)
+ presence_handlers[ident].each { |b| b.call(ident,state) }
end
def subscribe_presence(identity, &block)
- presence_handlers[identity] = block
+ presence_handlers[identity] << block
handle_subscribe_presence(identity)
end
11 lib/pelvis/protocols/local.rb
View
@@ -6,14 +6,12 @@ class Local < Protocol
register :local
SET = []
- PRESENCE_HANDLERS = {}
+ PRESENCE_HANDLERS = Hash.new { |h,k| h[k] = [] }
def connect
logger.debug "connecting using #{self}: identity=#{identity.inspect}"
- if presence_handlers[identity]
- presence_handlers[identity].call(identity, :available)
- end
+ call_presence_handlers(identity, :available)
on_spawned do |agent|
SET << agent
@@ -21,6 +19,11 @@ def connect
connected
end
+ def stop
+ SET.delete(identity)
+ call_presence_handlers(identity, :unavailable)
+ end
+
def evoke(identity, job)
if remote_agent = agent_for(identity)
remote_agent.invoke(agent.identity, job)
10 lib/pelvis/protocols/xmpp.rb
View
@@ -44,10 +44,8 @@ def receive_data(stanza)
when Blather::Stanza::Iq::Roster
# ignore
when Blather::Stanza::Presence::Status
- logger.debug "Got presence announcement from #{stanza.from}"
- if presence_handlers[stanza.from.to_s]
- presence_handlers[stanza.from.to_s].call stanza.from, stanza.state
- end
+ logger.debug "Got presence announcement from #{stanza.from} state #{stanza.state}"
+ call_presence_handlers stanza.from.to_s, stanza.state
when Blather::Stanza::Presence::Subscription
if stanza.subscribe?
logger.debug "Got subscription request from #{stanza.from}"
@@ -99,6 +97,10 @@ def agents
@agents ||= {}
end
+ def stop
+ @stream.instance_eval { stop }
+ end
+
def jid=(jid)
end
1  spec/helpers.rb
View
@@ -38,6 +38,7 @@ def start_agents(after=nil, &block)
end
def connect(agent, &block)
+ raise "no such agent #{agent}" unless CONFIGS[agent]
options = CONFIGS[agent].dup
Pelvis.connect(PROTOCOL.registered_as, options, &block)
end
30 spec/herault_spec.rb
View
@@ -0,0 +1,30 @@
+require File.dirname(__FILE__) + '/spec_helper'
+require 'examples/actors/herault'
+
+describe "Herault" do
+ include Pelvis::Helpers
+ before(:each) do
+ end
+
+ it "should subscribe to the presence messages of agents that advertise to it and remove advertisements on unavailable" do
+ @agents = [[:herault]]
+ start_agents do |herault|
+ herault.add_actor Herault
+ connect(:foo) do |foo|
+ foo.add_actor Simple
+ foo.on_advertised {
+ herault.protocol.presence_handlers.keys.should == [ identity_for(:foo) ]
+ Herault.operation_map['/echo'].should == { identity_for(:foo) => nil }
+
+ herault.protocol.subscribe_presence(identity_for(:foo)) do |i, s|
+ if s == :unavailable
+ Herault.operation_map['/echo'].should == {}
+ EM.stop
+ end
+ end
+ foo.protocol.stop
+ }
+ end
+ end
+ end
+end
32 spec/protocol_spec.rb
View
@@ -23,25 +23,23 @@ class DummyActor < Pelvis::Actor; end
}
end
- if ENV['PROTOCOL'] = 'xmpp'
- it "should call the block when the specified identity leaves" do
- block = Proc.new { |id, status|
- if status != :available
- id.should == identity_for(:foo)
- status.should == :unavailable
- EM.stop
- end
- }
+ it "should call the block when the specified identity leaves" do
+ block = Proc.new { |id, status|
+ if status != :available
+ id.should == identity_for(:foo)
+ status.should == :unavailable
+ EM.stop
+ end
+ }
- @agents = [[:herault]]
- start_agents { |agent|
- agent.protocol.subscribe_presence(identity_for(:foo), &block)
- connect(:foo) { |foo_agent|
- EM.add_timer(10) { raise "Didn't get subscription advertisement" }
- foo_agent.protocol.stream.instance_eval { stop }
- }
+ @agents = [[:herault]]
+ start_agents { |agent|
+ agent.protocol.subscribe_presence(identity_for(:foo), &block)
+ connect(:foo) { |foo_agent|
+ EM.add_timer(10) { raise "Didn't get subscription advertisement" }
+ foo_agent.protocol.stop
}
- end
+ }
end
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.