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_all_timeouts, #remove_timeout

Constructor Details

#initialize(server, options) ⇒ Memory

Returns a new instance of Memory.


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

def initialize(server, options)
  @server    = server
  @options   = options
  reset
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


53
54
55
# File 'lib/faye/engines/memory.rb', line 53

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

#create_client(&callback) ⇒ Object


29
30
31
32
33
34
35
# File 'lib/faye/engines/memory.rb', line 29

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


37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/faye/engines/memory.rb', line 37

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)
  @server.trigger(:close, client_id)
  callback.call if callback
end

#disconnectObject


17
18
19
20
# File 'lib/faye/engines/memory.rb', line 17

def disconnect
  reset
  remove_all_timeouts
end

#empty_queue(client_id) ⇒ Object


113
114
115
116
117
# File 'lib/faye/engines/memory.rb', line 113

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


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

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


93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/faye/engines/memory.rb', line 93

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

#resetObject


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

def reset
  @namespace = Namespace.new
  @clients   = {}
  @channels  = {}
  @messages  = {}
end

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


65
66
67
68
69
70
71
72
73
74
75
# File 'lib/faye/engines/memory.rb', line 65

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


77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/faye/engines/memory.rb', line 77

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