acpc_table_manager 3.0.18 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/.travis.yml +2 -0
- data/README.md +8 -21
- data/Rakefile +1 -0
- data/acpc_table_manager.gemspec +11 -23
- data/exe/acpc_proxy +146 -58
- data/exe/acpc_table_manager +45 -26
- data/exe/acpc_testing_bot +115 -0
- data/lib/acpc_table_manager.rb +635 -13
- data/lib/acpc_table_manager/config.rb +31 -141
- data/lib/acpc_table_manager/match.rb +52 -79
- data/lib/acpc_table_manager/proxy_utils.rb +290 -0
- data/lib/acpc_table_manager/version.rb +1 -1
- metadata +39 -127
- data/lib/acpc_table_manager/dealer.rb +0 -59
- data/lib/acpc_table_manager/maintainer.rb +0 -31
- data/lib/acpc_table_manager/match_slice.rb +0 -194
- data/lib/acpc_table_manager/match_view.rb +0 -203
- data/lib/acpc_table_manager/opponents.rb +0 -62
- data/lib/acpc_table_manager/proxy.rb +0 -346
- data/lib/acpc_table_manager/table_queue.rb +0 -240
@@ -1,240 +0,0 @@
|
|
1
|
-
require 'acpc_poker_types'
|
2
|
-
require 'acpc_dealer'
|
3
|
-
require 'timeout'
|
4
|
-
|
5
|
-
require_relative 'dealer'
|
6
|
-
require_relative 'opponents'
|
7
|
-
require_relative 'config'
|
8
|
-
require_relative 'match'
|
9
|
-
|
10
|
-
require_relative 'simple_logging'
|
11
|
-
using AcpcTableManager::SimpleLogging::MessageFormatting
|
12
|
-
|
13
|
-
require 'contextual_exceptions'
|
14
|
-
using ContextualExceptions::ClassRefinement
|
15
|
-
|
16
|
-
module AcpcTableManager
|
17
|
-
class TableQueue
|
18
|
-
include SimpleLogging
|
19
|
-
|
20
|
-
attr_reader :running_matches
|
21
|
-
|
22
|
-
exceptions :no_port_for_dealer_available
|
23
|
-
|
24
|
-
def initialize(game_definition_key_)
|
25
|
-
@logger = AcpcTableManager.new_log 'queue.log'
|
26
|
-
@game_definition_key = game_definition_key_
|
27
|
-
|
28
|
-
log(
|
29
|
-
__method__,
|
30
|
-
game_definition_key: @game_definition_key,
|
31
|
-
max_num_matches: AcpcTableManager.exhibition_config.games[@game_definition_key]['max_num_matches']
|
32
|
-
)
|
33
|
-
end
|
34
|
-
|
35
|
-
def start_players!(match)
|
36
|
-
Opponents.start(match)
|
37
|
-
log(__method__, msg: "Opponents started for #{match.id}")
|
38
|
-
|
39
|
-
start_proxy! match
|
40
|
-
end
|
41
|
-
|
42
|
-
def start_proxy!(match)
|
43
|
-
command = "#{File.expand_path('../../../exe/acpc_proxy', __FILE__)} -t #{AcpcTableManager.config_file} -m #{match.id}"
|
44
|
-
log(
|
45
|
-
__method__,
|
46
|
-
msg: "Starting proxy for #{match.id}",
|
47
|
-
command: command
|
48
|
-
)
|
49
|
-
|
50
|
-
match.proxy_pid = Timeout.timeout(3) do
|
51
|
-
pid = Process.spawn(command)
|
52
|
-
Process.detach(pid)
|
53
|
-
pid
|
54
|
-
end
|
55
|
-
match.save!
|
56
|
-
|
57
|
-
log(
|
58
|
-
__method__,
|
59
|
-
msg: "Started proxy for \"#{match.name}\" (#{match.id})",
|
60
|
-
pid: match.proxy_pid
|
61
|
-
)
|
62
|
-
self
|
63
|
-
end
|
64
|
-
|
65
|
-
def matches_to_start
|
66
|
-
my_matches.queue
|
67
|
-
end
|
68
|
-
|
69
|
-
def my_matches
|
70
|
-
Match.where(game_definition_key: @game_definition_key.to_sym)
|
71
|
-
end
|
72
|
-
|
73
|
-
def change_in_number_of_running_matches?
|
74
|
-
prevNumMatchesRunning = Match.running(my_matches).length
|
75
|
-
yield if block_given?
|
76
|
-
prevNumMatchesRunning != Match.running(my_matches).length
|
77
|
-
end
|
78
|
-
|
79
|
-
def length
|
80
|
-
matches_to_start.length
|
81
|
-
end
|
82
|
-
|
83
|
-
def available_special_ports
|
84
|
-
if AcpcTableManager.exhibition_config.special_ports_to_dealer
|
85
|
-
AcpcTableManager.exhibition_config.special_ports_to_dealer - Match.ports_in_use
|
86
|
-
else
|
87
|
-
[]
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
def check!
|
92
|
-
return if length < 1
|
93
|
-
|
94
|
-
my_matches_to_start = matches_to_start.to_a
|
95
|
-
|
96
|
-
max_running_matches = AcpcTableManager.exhibition_config.games[@game_definition_key]['max_num_matches']
|
97
|
-
check_num_running_matches = max_running_matches > 0
|
98
|
-
|
99
|
-
num_running_matches = 0
|
100
|
-
if check_num_running_matches
|
101
|
-
num_running_matches = Match.running(my_matches).length
|
102
|
-
log(
|
103
|
-
__method__,
|
104
|
-
num_running_matches: num_running_matches,
|
105
|
-
num_matches_to_start: my_matches_to_start.length
|
106
|
-
)
|
107
|
-
end
|
108
|
-
|
109
|
-
matches_started = []
|
110
|
-
while
|
111
|
-
!my_matches_to_start.empty? &&
|
112
|
-
(
|
113
|
-
!check_num_running_matches ||
|
114
|
-
num_running_matches < max_running_matches
|
115
|
-
)
|
116
|
-
|
117
|
-
matches_started << dequeue(my_matches_to_start.pop)
|
118
|
-
num_running_matches += 1
|
119
|
-
end
|
120
|
-
|
121
|
-
log(
|
122
|
-
__method__,
|
123
|
-
matches_started: matches_started,
|
124
|
-
num_running_matches: num_running_matches,
|
125
|
-
num_matches_to_start: matches_to_start.length
|
126
|
-
)
|
127
|
-
|
128
|
-
matches_started
|
129
|
-
end
|
130
|
-
|
131
|
-
protected
|
132
|
-
|
133
|
-
def port(available_ports)
|
134
|
-
port_ = available_ports.pop
|
135
|
-
until AcpcDealer.port_available?(port_)
|
136
|
-
if available_ports.empty?
|
137
|
-
raise NoPortForDealerAvailable, "None of the special ports (#{available_special_ports}) are open"
|
138
|
-
end
|
139
|
-
port_ = available_ports.pop
|
140
|
-
end
|
141
|
-
unless port_
|
142
|
-
raise NoPortForDealerAvailable, "None of the special ports (#{available_special_ports}) are open"
|
143
|
-
end
|
144
|
-
port_
|
145
|
-
end
|
146
|
-
|
147
|
-
def ports_to_use(special_port_requirements, available_ports = nil)
|
148
|
-
ports = special_port_requirements.map do |r|
|
149
|
-
if r
|
150
|
-
# Slow. Only check available special ports if necessary
|
151
|
-
available_ports ||= available_special_ports
|
152
|
-
port(available_ports)
|
153
|
-
else
|
154
|
-
0
|
155
|
-
end
|
156
|
-
end
|
157
|
-
[ports, available_ports]
|
158
|
-
end
|
159
|
-
|
160
|
-
# @return [Object] The match that has been started or +nil+ if none could
|
161
|
-
# be started.
|
162
|
-
def dequeue(match)
|
163
|
-
log(
|
164
|
-
__method__,
|
165
|
-
msg: "Starting dealer for match \"#{match.name}\" (#{match.id})",
|
166
|
-
options: match.dealer_options
|
167
|
-
)
|
168
|
-
|
169
|
-
special_port_requirements = match.bot_special_port_requirements
|
170
|
-
|
171
|
-
# Add user's port
|
172
|
-
special_port_requirements.insert(match.seat - 1, false)
|
173
|
-
|
174
|
-
ports_to_be_used, available_ports = ports_to_use(special_port_requirements)
|
175
|
-
|
176
|
-
num_repetitions = 0
|
177
|
-
dealer_info = nil
|
178
|
-
|
179
|
-
while dealer_info.nil?
|
180
|
-
log(
|
181
|
-
__method__,
|
182
|
-
msg: "Added #{match.id} list of running matches",
|
183
|
-
available_special_ports: available_ports,
|
184
|
-
special_port_requirements: special_port_requirements,
|
185
|
-
:'ports_to_be_used_(zero_for_random)' => ports_to_be_used
|
186
|
-
)
|
187
|
-
begin
|
188
|
-
dealer_info = Dealer.start(match, port_numbers: ports_to_be_used)
|
189
|
-
rescue Timeout::Error => e
|
190
|
-
log(
|
191
|
-
__method__,
|
192
|
-
{ warning: "The dealer for match \"#{match.name}\" (#{match.id}) timed out." },
|
193
|
-
Logger::Severity::WARN
|
194
|
-
)
|
195
|
-
begin
|
196
|
-
ports_to_be_used, available_ports = ports_to_use(special_port_requirements, available_ports)
|
197
|
-
rescue NoPortForDealerAvailable => e
|
198
|
-
available_ports = available_special_ports
|
199
|
-
log(
|
200
|
-
__method__,
|
201
|
-
{ warning: "#{ports_to_be_used} ports unavailable, retrying with all special ports, #{available_ports}." },
|
202
|
-
Logger::Severity::WARN
|
203
|
-
)
|
204
|
-
end
|
205
|
-
if num_repetitions < 1
|
206
|
-
sleep 1
|
207
|
-
log(
|
208
|
-
__method__,
|
209
|
-
{ warning: "Retrying with all special ports, #{available_ports}." },
|
210
|
-
Logger::Severity::WARN
|
211
|
-
)
|
212
|
-
num_repetitions += 1
|
213
|
-
else
|
214
|
-
log(
|
215
|
-
__method__,
|
216
|
-
{ warning: 'Unable to start match after retry, giving up.' },
|
217
|
-
Logger::Severity::ERROR
|
218
|
-
)
|
219
|
-
match.unable_to_start_dealer = true
|
220
|
-
match.save!
|
221
|
-
raise e
|
222
|
-
end
|
223
|
-
end
|
224
|
-
end
|
225
|
-
|
226
|
-
log(
|
227
|
-
__method__,
|
228
|
-
msg: "Dealer started for \"#{match.name}\" (#{match.id}) with pid #{match.dealer_pid}",
|
229
|
-
ports: match.port_numbers
|
230
|
-
)
|
231
|
-
|
232
|
-
match.ready_to_start = false
|
233
|
-
match.save!
|
234
|
-
|
235
|
-
start_players! match
|
236
|
-
|
237
|
-
match.id
|
238
|
-
end
|
239
|
-
end
|
240
|
-
end
|