Class: Faye::Dispatcher

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Logging, Publisher
Defined in:
lib/faye/protocol/dispatcher.rb

Defined Under Namespace

Classes: Envelope

Constant Summary collapse

MAX_REQUEST_SIZE =
2048
DEFAULT_RETRY =
5.0
UP =
1
DOWN =
2

Constants included from Logging

Logging::LOG_LEVELS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Publisher

#unbind

Constructor Details

#initialize(client, endpoint, options) ⇒ Dispatcher

Returns a new instance of Dispatcher.



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/faye/protocol/dispatcher.rb', line 21

def initialize(client, endpoint, options)
  super()

  @client     = client
  @endpoint   = Faye.parse_url(endpoint)
  @alternates = options[:endpoints] || {}

  @cookies    = CookieJar::Jar.new
  @disabled   = []
  @envelopes  = {}
  @headers    = {}
  @retry      = options[:retry] || DEFAULT_RETRY
  @state      = 0
  @transports = {}

  @alternates.each do |type, url|
    @alternates[type] = Faye.parse_url(url)
  end

  @max_request_size = MAX_REQUEST_SIZE
end

Instance Attribute Details

#client_idObject

Returns the value of attribute client_id.



18
19
20
# File 'lib/faye/protocol/dispatcher.rb', line 18

def client_id
  @client_id
end

#cookiesObject (readonly)

Returns the value of attribute cookies.



19
20
21
# File 'lib/faye/protocol/dispatcher.rb', line 19

def cookies
  @cookies
end

#endpointObject (readonly)

Returns the value of attribute endpoint.



19
20
21
# File 'lib/faye/protocol/dispatcher.rb', line 19

def endpoint
  @endpoint
end

#headersObject (readonly)

Returns the value of attribute headers.



19
20
21
# File 'lib/faye/protocol/dispatcher.rb', line 19

def headers
  @headers
end

#max_request_sizeObject (readonly)

Returns the value of attribute max_request_size.



19
20
21
# File 'lib/faye/protocol/dispatcher.rb', line 19

def max_request_size
  @max_request_size
end

#retryObject (readonly)

Returns the value of attribute retry.



19
20
21
# File 'lib/faye/protocol/dispatcher.rb', line 19

def retry
  @retry
end

#timeoutObject

Returns the value of attribute timeout.



18
19
20
# File 'lib/faye/protocol/dispatcher.rb', line 18

def timeout
  @timeout
end

#transportsObject (readonly)

Returns the value of attribute transports.



19
20
21
# File 'lib/faye/protocol/dispatcher.rb', line 19

def transports
  @transports
end

Instance Method Details

#closeObject



55
56
57
58
59
# File 'lib/faye/protocol/dispatcher.rb', line 55

def close
  transport = @transport
  @transport = nil
  transport.close if transport
end

#disable(feature) ⇒ Object



47
48
49
# File 'lib/faye/protocol/dispatcher.rb', line 47

def disable(feature)
  @disabled << feature
end

#endpoint_for(connection_type) ⇒ Object



43
44
45
# File 'lib/faye/protocol/dispatcher.rb', line 43

def endpoint_for(connection_type)
  @alternates[connection_type] || @endpoint
end

#handle_error(message, immediate = false) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/faye/protocol/dispatcher.rb', line 106

def handle_error(message, immediate = false)
  return unless envelope = @envelopes[message['id']]
  return unless request = envelope.request

  request.callback do |req|
    req.close if req.respond_to?(:close)
  end

  EventMachine.cancel_timer(envelope.timer)
  envelope.request = envelope.timer = nil

  if immediate
    send_message(envelope.message, envelope.timeout)
  else
    envelope.timer = EventMachine.add_timer(@retry) do
      envelope.timer = nil
      send_message(envelope.message, envelope.timeout)
    end
  end

  return if @state == DOWN
  @state = DOWN
  @client.trigger('transport:down')
end

#handle_response(reply) ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
# File 'lib/faye/protocol/dispatcher.rb', line 94

def handle_response(reply)
  if reply.has_key?('successful') and envelope = @envelopes.delete(reply['id'])
    EventMachine.cancel_timer(envelope.timer) if envelope.timer
  end

  trigger(:message, reply)

  return if @state == UP
  @state = UP
  @client.trigger('transport:up')
end

#select_transport(transport_types) ⇒ Object



61
62
63
64
65
66
67
68
69
70
# File 'lib/faye/protocol/dispatcher.rb', line 61

def select_transport(transport_types)
  Transport.get(self, transport_types, @disabled) do |transport|
    debug('Selected ? transport for ?', transport.connection_type, transport.endpoint)

    next if transport == @transport
    @transport.close if @transport

    @transport = transport
  end
end

#send_message(message, timeout, options = {}) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/faye/protocol/dispatcher.rb', line 72

def send_message(message, timeout, options = {})
  return unless @transport

  id       = message['id']
  attempts  = options[:attempts]
  deadline = options[:deadline] && Time.now.to_f + options[:deadline]
  envelope = @envelopes[id] ||= Envelope.new(message, timeout, attempts, deadline, nil, nil)

  return if envelope.request or envelope.timer

  if attempts_exhausted(envelope) or deadline_passed(envelope)
    @envelopes.delete(id)
    return
  end

  envelope.timer = EventMachine.add_timer(timeout) do
    handle_error(message)
  end

  envelope.request = @transport.send_message(message)
end

#set_header(name, value) ⇒ Object



51
52
53
# File 'lib/faye/protocol/dispatcher.rb', line 51

def set_header(name, value)
  @headers[name.to_s] = value.to_s
end