-
-
Notifications
You must be signed in to change notification settings - Fork 72
Expand file tree
/
Copy pathservice.rb
More file actions
119 lines (105 loc) · 3.07 KB
/
service.rb
File metadata and controls
119 lines (105 loc) · 3.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
module SlackRubyBotServer
class Service
include SlackRubyBot::Loggable
def self.start!
Thread.new do
Thread.current.abort_on_exception = true
instance.start_from_database!
end
end
def self.instance
@instance ||= new
end
def initialize
@callbacks = Hash.new { |h, k| h[k] = [] }
end
def on(type, &block)
@callbacks[type.to_s] << block
end
def create!(team)
run_callbacks :creating, team
start!(team)
run_callbacks :created, team
end
def start!(team)
run_callbacks :starting, team
logger.info "Starting team #{team}."
options = { team: team }
options[:ping] = SlackRubyBotServer::Config.ping if SlackRubyBotServer::Config.ping
server = SlackRubyBotServer::Config.server_class.new(options)
start_server! team, server
run_callbacks :started, team
server
rescue StandardError => e
run_callbacks :error, team, e
logger.error e
end
def restart!(team, server, wait = 1)
run_callbacks :restarting, team
start_server! team, server, wait
run_callbacks :restarted, team
end
def stop!(team)
logger.info "Stopping team #{team}."
run_callbacks :stopping, team
team.server.stop! if team.server
run_callbacks :stopped, team
rescue StandardError => e
run_callbacks :error, team, e
logger.error e
ensure
team.server = nil
end
def start_from_database!
SlackRubyBotServer::Team.active.each do |team|
run_callbacks :booting, team
start!(team)
run_callbacks :booted, team
end
end
def deactivate!(team)
run_callbacks :deactivating, team
team.deactivate!
run_callbacks :deactivated, team
rescue Mongoid::Errors::Validations => e
run_callbacks :error, team, e
logger.error "#{team.name}: #{e.message}, error - #{e.document.class}, #{e.document.errors.to_hash}, ignored."
rescue StandardError => e
run_callbacks :error, team, e
logger.error "#{team.name}: #{e.class}, #{e.message}, ignored."
ensure
team.server = nil
end
def self.reset!
@instance = nil
end
private
def start_server!(team, server, wait = 1)
team.server = server
server.start_async
rescue StandardError => e
run_callbacks :error, team, e
case e.message
when 'account_inactive', 'invalid_auth' then
logger.error "#{team.name}: #{e.message}, team will be deactivated."
deactivate!(team)
else
wait = e.retry_after if e.is_a?(Slack::Web::Api::Errors::TooManyRequestsError)
logger.error "#{team.name}: #{e.message}, restarting in #{wait} second(s)."
sleep(wait)
start_server! team, server, [wait * 2, 60].min
end
end
def run_callbacks(type, team = nil, error = nil)
callbacks = @callbacks[type.to_s]
return false unless callbacks
callbacks.each do |c|
c.call team, error
end
true
rescue StandardError => e
logger.error e
false
end
end
end