Class: Tkellem::TkellemServer

Inherits:
Object
  • Object
show all
Includes:
EasyLogger
Defined in:
lib/tkellem/tkellem_server.rb

Defined Under Namespace

Classes: Observer

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from EasyLogger

#failsafe, #log_name, logger, logger=, trace, #trace, trace=

Constructor Details

#initializeTkellemServer

Returns a new instance of TkellemServer.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/tkellem/tkellem_server.rb', line 27

def initialize
  @listeners = {}
  @bouncers = {}
  $tkellem_server = self

  unless ActiveRecord::Base.connected?
    ActiveRecord::Base.establish_connection({
      :adapter => 'sqlite3',
      :database => File.expand_path("~/.tkellem/tkellem.sqlite3"),
    })
    ActiveRecord::Migrator.migrate(File.expand_path("../migrations", __FILE__), nil)
  end

  ListenAddress.all.each { |a| listen(a) }
  NetworkUser.find_each { |nu| add_bouncer(nu) }
  Observer.forward_to << self
end

Instance Attribute Details

#bouncersObject (readonly)

Returns the value of attribute bouncers.



25
26
27
# File 'lib/tkellem/tkellem_server.rb', line 25

def bouncers
  @bouncers
end

Instance Method Details

#add_bouncer(network_user) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
# File 'lib/tkellem/tkellem_server.rb', line 85

def add_bouncer(network_user)
  unless network_user.user && network_user.network
    info "Terminating orphan network user #{network_user.inspect}"
    network_user.destroy
    return
  end

  key = bouncers_key(network_user)
  raise("bouncer already exists: #{key}") if @bouncers.include?(key)
  @bouncers[key] = Bouncer.new(network_user)
end

#after_create(obj) ⇒ Object

callbacks for AR observer events



50
51
52
53
54
55
56
57
# File 'lib/tkellem/tkellem_server.rb', line 50

def after_create(obj)
  case obj
  when ListenAddress
    listen(obj)
  when NetworkUser
    add_bouncer(obj)
  end
end

#after_destroy(obj) ⇒ Object



59
60
61
62
63
64
65
66
# File 'lib/tkellem/tkellem_server.rb', line 59

def after_destroy(obj)
  case obj
  when ListenAddress
    stop_listening(obj)
  when NetworkUser
    stop_bouncer(obj)
  end
end

#bouncers_key(network_user) ⇒ Object



120
121
122
# File 'lib/tkellem/tkellem_server.rb', line 120

def bouncers_key(network_user)
  [network_user.user_id, network_user.network.name]
end

#find_bouncer(user, network_name) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/tkellem/tkellem_server.rb', line 105

def find_bouncer(user, network_name)
  key = [user.id, network_name]
  bouncer = @bouncers[key]
  if !bouncer
    # find the public network with this name, and attempt to auto-add this user to it
    network = Network.first(:conditions => { :user_id => nil, :name => network_name })
    if network
      NetworkUser.create!(:user => user, :network => network)
      # AR callback should create the bouncer in sync
      bouncer = @bouncers[key]
    end
  end
  bouncer
end

#listen(listen_address) ⇒ Object



68
69
70
71
72
73
74
75
76
# File 'lib/tkellem/tkellem_server.rb', line 68

def listen(listen_address)
  info "Listening on #{listen_address}"

  @listeners[listen_address.id] = EM.start_server(listen_address.address,
                                                  listen_address.port,
                                                  BouncerConnection,
                                                  self,
                                                  listen_address.ssl)
end

#stopObject



45
46
47
# File 'lib/tkellem/tkellem_server.rb', line 45

def stop
  Observer.forward_to.delete(self)
end

#stop_bouncer(obj) ⇒ Object



97
98
99
100
101
102
103
# File 'lib/tkellem/tkellem_server.rb', line 97

def stop_bouncer(obj)
  key = bouncers_key(network_user)
  bouncer = @bouncers.delete(key)
  if bouncer
    bouncer.kill!
  end
end

#stop_listening(listen_address) ⇒ Object



78
79
80
81
82
83
# File 'lib/tkellem/tkellem_server.rb', line 78

def stop_listening(listen_address)
  listener = @listeners[listen_address.id]
  return unless listener
  EM.stop_server(listener)
  info "No longer listening on #{listen_address}"
end