Class: Faye::Engine::Memory

Inherits:
Object
  • Object
show all
Includes:
Timeouts
Defined in:
lib/faye/engines/memory.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Timeouts

#add_timeout, #remove_timeout

Constructor Details

#initialize(server, options) ⇒ Memory

Returns a new instance of Memory.



11
12
13
14
15
16
17
18
# File 'lib/faye/engines/memory.rb', line 11

def initialize(server, options)
  @server    = server
  @options   = options
  @namespace = Namespace.new
  @clients   = {}
  @channels  = {}
  @messages  = {}
end

Class Method Details

.create(server, options) ⇒ Object



7
8
9
# File 'lib/faye/engines/memory.rb', line 7

def self.create(server, options)
  new(server, options)
end

Instance Method Details

#client_exists(client_id, &callback) ⇒ Object



43
44
45
# File 'lib/faye/engines/memory.rb', line 43

def client_exists(client_id, &callback)
  callback.call(@namespace.exists?(client_id))
end

#create_client(&callback) ⇒ Object



20
21
22
23
24
25
26
# File 'lib/faye/engines/memory.rb', line 20

def create_client(&callback)
  client_id = @namespace.generate
  @server.debug 'Created new client ?', client_id
  ping(client_id)
  @server.trigger(:handshake, client_id)
  callback.call(client_id)
end

#destroy_client(client_id, &callback) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/faye/engines/memory.rb', line 28

def destroy_client(client_id, &callback)
  return unless @namespace.exists?(client_id)
  
  if @clients.has_key?(client_id)
    @clients[client_id].each { |channel| unsubscribe(client_id, channel) }
  end
  
  remove_timeout(client_id)
  @namespace.release(client_id)
  @messages.delete(client_id)
  @server.debug 'Destroyed client ?', client_id
  @server.trigger(:disconnect, client_id)
  callback.call if callback
end

#empty_queue(client_id) ⇒ Object



103
104
105
106
107
# File 'lib/faye/engines/memory.rb', line 103

def empty_queue(client_id)
  return unless @server.has_connection?(client_id)
  @server.deliver(client_id, @messages[client_id])
  @messages.delete(client_id)
end

#ping(client_id) ⇒ Object



47
48
49
50
51
52
53
# File 'lib/faye/engines/memory.rb', line 47

def ping(client_id)
  timeout = @server.timeout
  return unless Numeric === timeout
  @server.debug 'Ping ?, ?', client_id, timeout
  remove_timeout(client_id)
  add_timeout(client_id, 2 * timeout) { destroy_client(client_id) }
end

#publish(message, channels) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/faye/engines/memory.rb', line 83

def publish(message, channels)
  @server.debug 'Publishing message ?', message
  
  clients = Set.new
  
  channels.each do |channel|
    next unless subs = @channels[channel]
    subs.each(&clients.method(:add))
  end
  
  clients.each do |client_id|
    @server.debug 'Queueing for client ?: ?', client_id, message
    @messages[client_id] ||= []
    @messages[client_id] << Faye.copy_object(message)
    empty_queue(client_id)
  end

  @server.trigger(:publish, message['clientId'], message['channel'], message['data'])
end

#subscribe(client_id, channel, &callback) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
# File 'lib/faye/engines/memory.rb', line 55

def subscribe(client_id, channel, &callback)
  @clients[client_id] ||= Set.new
  should_trigger = @clients[client_id].add?(channel)
  
  @channels[channel] ||= Set.new
  @channels[channel].add(client_id)
  
  @server.debug 'Subscribed client ? to channel ?', client_id, channel
  @server.trigger(:subscribe, client_id, channel) if should_trigger
  callback.call(true) if callback
end

#unsubscribe(client_id, channel, &callback) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/faye/engines/memory.rb', line 67

def unsubscribe(client_id, channel, &callback)
  if @clients.has_key?(client_id)
    should_trigger = @clients[client_id].delete?(channel)
    @clients.delete(client_id) if @clients[client_id].empty?
  end
  
  if @channels.has_key?(channel)
    @channels[channel].delete(client_id)
    @channels.delete(channel) if @channels[channel].empty?
  end
  
  @server.debug 'Unsubscribed client ? from channel ?', client_id, channel
  @server.trigger(:unsubscribe, client_id, channel) if should_trigger
  callback.call(true) if callback
end