Class: Spire::API::Subscription

Inherits:
Resource
  • Object
show all
Defined in:
lib/spire/api/subscription.rb

Overview

The subscription class represents a read connection to a Spire channel

You can get a subscription by calling subscribe on a spire object with the name of the channel or by calling subscribe on a channel object

  • spire = Spire.new

  • spire.start(“your api secret”)

THEN

  • subscription = spire.subscribe(“subscription name”, “channel name”)

OR

  • channel = spire[“channel name”]

  • subscription = channel.subscribe(“subscription name”)

Constant Summary collapse

EVENT_TYPES =
["message", "join", "part"]

Instance Attribute Summary

Attributes inherited from Resource

#capabilities, #properties, #url

Instance Method Summary collapse

Methods inherited from Resource

#[], #delete, #get, #initialize, #key, #media_type, #method_missing, #respond_to?, #schema, #update

Methods included from Requestable

included

Constructor Details

This class inherits a constructor from Spire::API::Resource

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Spire::API::Resource

Instance Method Details

#add_listener(type, listener_name = nil, &block) ⇒ Object

provided named listeners, threading, and a stop_listening method.

Raises:

  • (ArgumentError)


62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/spire/api/subscription.rb', line 62

def add_listener(type, listener_name = nil, &block)
  type ||= ""
  type.downcase!
  if !EVENT_TYPES.include?(type)
    throw "Listener type must be one of #{EVENT_TYPES}"
  end

  raise ArgumentError unless block_given?
  listener_name ||= generate_listener_name
  listener = wrap_listener(&block)
  listeners[type][listener_name] = listener
  listener_name
end

#generate_listener_nameObject



105
106
107
108
109
110
111
112
# File 'lib/spire/api/subscription.rb', line 105

def generate_listener_name
  listener_name = nil
  while !listener_name
    new_name = "Listener-#{rand(9999999)}"
    listener_name = new_name unless listeners.has_key?(new_name)
  end
  listener_name
end

#lastObject



20
21
22
# File 'lib/spire/api/subscription.rb', line 20

def last
  @last
end

#listenersObject



48
49
50
51
52
53
54
55
56
57
58
# File 'lib/spire/api/subscription.rb', line 48

def listeners
  if @listeners
    @listeners
  else
    @listeners = { }
    EVENT_TYPES.each do |type|
      @listeners[type] = {}
    end
    @listeners
  end
end

#long_poll(options = {}) ⇒ Object



161
162
163
164
165
# File 'lib/spire/api/subscription.rb', line 161

def long_poll(options={})
  options[:timeout] ||= 30
  options[:last] = @last if @last
  retrieve_events(options)
end

#poll(options = {}) ⇒ Object



154
155
156
157
158
159
# File 'lib/spire/api/subscription.rb', line 154

def poll(options={})
  # timeout option of 0 means no long poll,
  # so we force it here.
  options[:timeout] = 0
  long_poll(options)
end

#remove_listener(type, arg) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/spire/api/subscription.rb', line 76

def remove_listener(type, arg)
  type ||= ""
  type.downcase!
  if !EVENT_TYPES.include?(type)
    throw "Listener type must be one of #{EVENT_TYPES}"
  end

  if arg.is_a? String
    listener = listeners[type].delete(arg)
  else
    listener_name, _listener = listeners.detect {|k,v| v == arg }
    listener = listeners[type].delete(listener_name)
  end

  if listener
    listeners[type].delete(listener)
  end
end

#resource_nameObject



22
23
24
# File 'lib/spire/api/subscription.rb', line 22

def resource_name
  "subscription"
end

#retrieve_events(options = {}) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/spire/api/subscription.rb', line 125

def retrieve_events(options={})
  response = request(:events, options)
  unless response.status == 200
    raise "Error retrieving messages from #{self.class.name}: (#{response.status}) #{response.body}"
  end
  @last = response.data["last"] if response.data and response.data["last"]

  event_hash = {
    :first => response.data["first"],
    :last => response.data["last"]
  }

  EVENT_TYPES.each do |type|
    type_pl = "#{type}s"
    event_hash[type_pl.to_sym] = []
    response.data[type_pl].each do |event|
      klass_name = type.capitalize
      klass = API.const_get(klass_name)
      event_obj = klass.new(@api, event)
      event_hash[type_pl.to_sym].push(event_obj)

      listeners[type].each_value do |listener|
        listener.call(event_obj)
      end
    end
  end
  event_hash
end

#start_listening(options = {}) ⇒ Object



114
115
116
117
118
119
# File 'lib/spire/api/subscription.rb', line 114

def start_listening(options={})
  @listening = true
  Thread.new do
    long_poll(options) while @listening
  end
end

#stop_listeningObject



121
122
123
# File 'lib/spire/api/subscription.rb', line 121

def stop_listening
  @listening = false
end

#wrap_listener(&block) ⇒ Object



95
96
97
98
99
100
101
102
103
# File 'lib/spire/api/subscription.rb', line 95

def wrap_listener(&block)
  lambda do |message|
    Thread.new do
      # Messages received after a call to stop_listening
      # will not be processed.
      yield message if @listening
    end
  end
end