Class: Colossus::Engine::MemoryMonitor

Inherits:
Object
  • Object
show all
Includes:
Observable
Defined in:
lib/colossus/engines/memory_monitor/memory.rb

Overview

The Memory Engine is a non-distributed, in process, threadsafe engine. Based on EventMachine in order to provide the ttl to disconnect clients.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ttl) ⇒ MemoryMonitor

Returns a new instance of MemoryMonitor.

Parameters:

  • ttl (Integer/Float)

    TTL in seconds



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

def initialize(ttl)
  @client_sessions = Hash.new do |hash, key|
    hash[key] = Colossus::Engine::Memory::ClientSessionStore.new
  end
  @ttl     = ttl
  @monitor = Monitor.new
end

Instance Attribute Details

#client_sessionsObject (readonly)

Returns the value of attribute client_sessions.



9
10
11
# File 'lib/colossus/engines/memory_monitor/memory.rb', line 9

def client_sessions
  @client_sessions
end

#monitorObject (readonly)

Returns the value of attribute monitor.



9
10
11
# File 'lib/colossus/engines/memory_monitor/memory.rb', line 9

def monitor
  @monitor
end

#ttlObject (readonly)

Returns the value of attribute ttl.



9
10
11
# File 'lib/colossus/engines/memory_monitor/memory.rb', line 9

def ttl
  @ttl
end

Instance Method Details

#delete(user_id) ⇒ Object



65
66
67
68
69
# File 'lib/colossus/engines/memory_monitor/memory.rb', line 65

def delete(user_id)
  synchronize do
    client_sessions.delete(user_id)
  end
end

#delete_expired_users(user_ids) ⇒ Object



106
107
108
109
110
111
# File 'lib/colossus/engines/memory_monitor/memory.rb', line 106

def delete_expired_users(user_ids)
  user_ids.each do |user_id|
    delete(user_id)
    user_changed(user_id, DISCONNECTED)
  end
end

#gc_ttlObject



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

def gc_ttl
  user_ids_to_delete = []

  client_sessions.each_pair do |user_id, session_store|
    sessions_dupped = session_store.sessions.dup

    session_store.sessions.each_pair do |session_id, session|
      if (session.last_seen + ttl) < Time.now
        sessions_dupped.delete(session_id)
      end
    end

    synchronize { session_store.sessions = sessions_dupped }

    if (session_store.last_seen + ttl) < Time.now
      user_ids_to_delete << user_id
    end
  end

  delete_expired_users(user_ids_to_delete)
end

#get(user_id) ⇒ Object



45
46
47
48
49
50
51
# File 'lib/colossus/engines/memory_monitor/memory.rb', line 45

def get(user_id)
  if client_sessions.has_key?(user_id)
    { user_id => client_sessions[user_id].status }
  else
    { user_id => DISCONNECTED }
  end
end

#get_allObject



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

def get_all
  statuses = {}
  client_sessions.each_pair do |user_id, session_store|
    statuses[user_id] = session_store.status
  end
  statuses
end

#get_multi(*user_ids) ⇒ Object



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

def get_multi(*user_ids)
  user_ids.inject({}) { |memo, user_id| memo.merge!(get(user_id)) }
end

#new_periodic_ttlObject



79
80
81
82
# File 'lib/colossus/engines/memory_monitor/memory.rb', line 79

def new_periodic_ttl
  secs_ttl = Colossus.config.seconds_before_ttl_check
  @periodic_ttl = EM::Synchrony.add_periodic_timer(secs_ttl, &method(:gc_ttl))
end

#reset!Object



71
72
73
74
75
76
77
# File 'lib/colossus/engines/memory_monitor/memory.rb', line 71

def reset!
  synchronize do
    @client_sessions = Hash.new do |hash, key|
      hash[key] = Colossus::Engine::Memory::ClientSessionStore.new
    end
  end
end

#set(user_id, client_id, given_status) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/colossus/engines/memory_monitor/memory.rb', line 25

def set(user_id, client_id, given_status)
  synchronize do
    if given_status == DISCONNECTED
      client_sessions[user_id].delete(client_id)
    else
      client_sessions[user_id][client_id] = given_status
    end
  end

  if client_sessions[user_id].sessions.empty? ||
      client_sessions[user_id].status_changed?
    status = client_sessions[user_id].status
    delete(user_id) if status == DISCONNECTED
    user_changed(user_id, status)
    return true
  end

  false
end

#synchronize(&block) ⇒ Object



113
114
115
# File 'lib/colossus/engines/memory_monitor/memory.rb', line 113

def synchronize(&block)
  monitor.synchronize(&block)
end

#user_changed(user_id, status) ⇒ Object



20
21
22
23
# File 'lib/colossus/engines/memory_monitor/memory.rb', line 20

def user_changed(user_id, status)
  changed
  notify_observers(user_id, status)
end