Class: Rapns::Daemon::AppRunner

Inherits:
Object
  • Object
show all
Extended by:
Reflectable
Includes:
Reflectable
Defined in:
lib/rapns/daemon/app_runner.rb

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Reflectable

reflect

Constructor Details

#initialize(app) ⇒ AppRunner

Returns a new instance of AppRunner.



72
73
74
# File 'lib/rapns/daemon/app_runner.rb', line 72

def initialize(app)
  @app = app
end

Class Attribute Details

.runnersObject (readonly)

Returns the value of attribute runners.



8
9
10
# File 'lib/rapns/daemon/app_runner.rb', line 8

def runners
  @runners
end

Instance Attribute Details

#appObject (readonly)

Returns the value of attribute app.



69
70
71
# File 'lib/rapns/daemon/app_runner.rb', line 69

def app
  @app
end

#batchObject

Returns the value of attribute batch.



70
71
72
# File 'lib/rapns/daemon/app_runner.rb', line 70

def batch
  @batch
end

Class Method Details

.debugObject



57
58
59
# File 'lib/rapns/daemon/app_runner.rb', line 57

def self.debug
  runners.values.map(&:debug)
end

.enqueue(notifications) ⇒ Object



13
14
15
16
17
18
19
20
21
22
# File 'lib/rapns/daemon/app_runner.rb', line 13

def self.enqueue(notifications)
  notifications.group_by(&:app_id).each do |app_id, group|
    batch = Batch.new(group)
    if app = runners[app_id]
      app.enqueue(batch)
    else
      Rapns.logger.error("No such app '#{app_id}' for notifications #{batch.describe}.")
    end
  end
end

.idleObject



61
62
63
# File 'lib/rapns/daemon/app_runner.rb', line 61

def self.idle
  runners.values.select(&:idle?)
end

.new_runner(app) ⇒ Object



47
48
49
50
# File 'lib/rapns/daemon/app_runner.rb', line 47

def self.new_runner(app)
  type = app.class.parent.name.demodulize
  "Rapns::Daemon::#{type}::AppRunner".constantize.new(app)
end

.stopObject



52
53
54
55
# File 'lib/rapns/daemon/app_runner.rb', line 52

def self.stop
  runners.values.map(&:stop)
  runners.clear
end

.syncObject



24
25
26
27
28
29
# File 'lib/rapns/daemon/app_runner.rb', line 24

def self.sync
  apps = Rapns::App.all
  apps.each { |app| sync_app(app) }
  removed = runners.keys - apps.map(&:id)
  removed.each { |app_id| runners.delete(app_id).stop }
end

.sync_app(app) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/rapns/daemon/app_runner.rb', line 31

def self.sync_app(app)
  if runners[app.id]
    runners[app.id].sync(app)
  else
    runner = new_runner(app)
    begin
      runner.start
      runners[app.id] = runner
    rescue StandardError => e
      Rapns.logger.error("[#{app.name}] Exception raised during startup. Notifications will not be delivered for this app.")
      Rapns.logger.error(e)
      reflect(:error, e)
    end
  end
end

.waitObject



65
66
67
# File 'lib/rapns/daemon/app_runner.rb', line 65

def self.wait
  sleep 0.1 while !runners.values.all?(&:idle?)
end

Instance Method Details

#after_startObject



77
# File 'lib/rapns/daemon/app_runner.rb', line 77

def after_start; end

#after_stopObject



79
# File 'lib/rapns/daemon/app_runner.rb', line 79

def after_stop; end

#batch_processedObject



147
148
149
# File 'lib/rapns/daemon/app_runner.rb', line 147

def batch_processed
  batch ? batch.num_processed : 0
end

#batch_sizeObject



143
144
145
# File 'lib/rapns/daemon/app_runner.rb', line 143

def batch_size
  batch ? batch.num_notifications : 0
end

#before_startObject



76
# File 'lib/rapns/daemon/app_runner.rb', line 76

def before_start; end

#before_stopObject



78
# File 'lib/rapns/daemon/app_runner.rb', line 78

def before_stop; end

#debugObject



123
124
125
126
127
128
129
130
131
132
133
# File 'lib/rapns/daemon/app_runner.rb', line 123

def debug
  Rapns.logger.info <<-EOS

#{@app.name}:
  handlers: #{num_handlers}
  queued: #{queue_size}
  batch size: #{batch_size}
  batch processed: #{batch_processed}
  idle: #{idle?}
  EOS
end

#decrement_handlers(num) ⇒ Object



115
116
117
# File 'lib/rapns/daemon/app_runner.rb', line 115

def decrement_handlers(num)
  num.times { handlers.pop }
end

#enqueue(batch) ⇒ Object



94
95
96
97
98
99
100
# File 'lib/rapns/daemon/app_runner.rb', line 94

def enqueue(batch)
  self.batch = batch
  batch.notifications.each do |notification|
    queue.push([notification, batch])
    reflect(:notification_enqueued, notification)
  end
end

#idle?Boolean

Returns:

  • (Boolean)


135
136
137
# File 'lib/rapns/daemon/app_runner.rb', line 135

def idle?
  batch ? batch.complete? : true
end

#increment_handlers(num) ⇒ Object



119
120
121
# File 'lib/rapns/daemon/app_runner.rb', line 119

def increment_handlers(num)
  num.times { handlers.push(start_handler) }
end

#num_handlersObject



151
152
153
# File 'lib/rapns/daemon/app_runner.rb', line 151

def num_handlers
  handlers.size
end

#queue_sizeObject



139
140
141
# File 'lib/rapns/daemon/app_runner.rb', line 139

def queue_size
  queue.size
end

#startObject



81
82
83
84
85
86
# File 'lib/rapns/daemon/app_runner.rb', line 81

def start
  before_start
  app.connections.times { handlers.push(start_handler) }
  after_start
  Rapns.logger.info("[#{app.name}] Started, #{handlers_str}.")
end

#stopObject



88
89
90
91
92
# File 'lib/rapns/daemon/app_runner.rb', line 88

def stop
  before_stop
  handlers.stop
  after_stop
end

#sync(app) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/rapns/daemon/app_runner.rb', line 102

def sync(app)
  @app = app
  diff = handlers.size - app.connections
  return if diff == 0
  if diff > 0
    decrement_handlers(diff)
    Rapns.logger.info("[#{app.name}] Stopped #{handlers_str(diff)}. #{handlers_str} running.")
  else
    increment_handlers(diff.abs)
    Rapns.logger.info("[#{app.name}] Started #{handlers_str(diff)}. #{handlers_str} running.")
  end
end