Class: AcpcTableManager::TableQueue

Inherits:
Object
  • Object
show all
Includes:
SimpleLogging
Defined in:
lib/acpc_table_manager/table_queue.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from SimpleLogging

#log, #log_with, #logger

Constructor Details

#initialize(game_definition_key_) ⇒ TableQueue

Returns a new instance of TableQueue.



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/acpc_table_manager/table_queue.rb', line 24

def initialize(game_definition_key_)
  @logger = AcpcTableManager.new_log 'queue.log'
  @matches_to_start = []
  @running_matches = {}
  @game_definition_key = game_definition_key_

  log(
    __method__,
    {
      game_definition_key: @game_definition_key,
      max_num_matches: AcpcTableManager.exhibition_config.games[@game_definition_key]['max_num_matches']
    }
  )

  # Clean up old matches
  my_matches.running_or_started.each do |m|
    m.delete
  end
end

Instance Attribute Details

#running_matchesObject (readonly)

Returns the value of attribute running_matches.



20
21
22
# File 'lib/acpc_table_manager/table_queue.rb', line 20

def running_matches
  @running_matches
end

Instance Method Details

#available_special_portsObject



109
110
111
112
113
114
115
# File 'lib/acpc_table_manager/table_queue.rb', line 109

def available_special_ports
  if AcpcTableManager.exhibition_config.special_ports_to_dealer
    AcpcTableManager.exhibition_config.special_ports_to_dealer - ports_in_use
  else
    []
  end
end

#change_in_number_of_running_matches?Boolean

Returns:

  • (Boolean)


90
91
92
93
94
# File 'lib/acpc_table_manager/table_queue.rb', line 90

def change_in_number_of_running_matches?
  prevNumMatchesRunning = @running_matches.length
  yield if block_given?
  prevNumMatchesRunning != @running_matches.length
end

#check_queue!Array

Returns The list of PID information about the matches that were dequeued.

Returns:

  • (Array)

    The list of PID information about the matches that were dequeued.



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/acpc_table_manager/table_queue.rb', line 141

def check_queue!
  log __method__

  kill_matches!

  log __method__, {num_running_matches: @running_matches.length, num_matches_to_start: @matches_to_start.length}

  matches_started = []
  while !@matches_to_start.empty? && @running_matches.length < AcpcTableManager.exhibition_config.games[@game_definition_key]['max_num_matches']
    matches_started << dequeue
  end

  log __method__, {matches_started: matches_started, num_running_matches: @running_matches.length, num_matches_to_start: @matches_to_start.length}

  matches_started
end

#enqueue!(match_id, dealer_options) ⇒ Object

Returns self.

Returns:

  • self



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/acpc_table_manager/table_queue.rb', line 118

def enqueue!(match_id, dealer_options)
  log(
    __method__,
    {
      match_id: match_id,
      running_matches: @running_matches.map { |r| r.first },
      game_definition_key: @game_definition_key,
      max_num_matches: AcpcTableManager.exhibition_config.games[@game_definition_key]['max_num_matches']
    }
  )

  if @running_matches[match_id]
    log(
      __method__,
      msg: "Match #{match_id} already started!"
    )
  else
      @matches_to_start << {match_id: match_id, options: dealer_options}
  end
  self
end

#fix_running_matches_statuses!Object



159
160
161
162
163
164
165
166
167
# File 'lib/acpc_table_manager/table_queue.rb', line 159

def fix_running_matches_statuses!
  log __method__
  my_matches.running do |m|
    if !(@running_matches[m.id.to_s] && AcpcDealer::dealer_running?(@running_matches[m.id.to_s][:dealer]))
      m.is_running = false
      m.save
    end
  end
end

#force_kill_match!(match_id) ⇒ Object



192
193
194
195
196
197
# File 'lib/acpc_table_manager/table_queue.rb', line 192

def force_kill_match!(match_id)
  log __method__, match_id: match_id
  kill_match! match_id
  ::AcpcTableManager::Match.delete_match! match_id
  log __method__, match_id: match_id, msg: 'Match successfully deleted'
end

#kill_match!(match_id) ⇒ Object



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/acpc_table_manager/table_queue.rb', line 169

def kill_match!(match_id)
  return unless match_id

  begin
    match = Match.find match_id
  rescue Mongoid::Errors::DocumentNotFound
  else
    match.is_running = false
    match.save!
  end

  match_info = @running_matches[match_id]
  if match_info
    @running_matches.delete(match_id)
  end
  @matches_to_start.delete_if { |m| m[:match_id] == match_id }

  kill_dealer!(match_info[:dealer]) if match_info && match_info[:dealer]
  kill_proxy!(match_info[:proxy]) if match_info && match_info[:proxy]

  log __method__, match_id: match_id, msg: 'Match successfully killed'
end

#lengthObject



96
97
98
# File 'lib/acpc_table_manager/table_queue.rb', line 96

def length
  @matches_to_start.length
end

#my_matchesObject



86
87
88
# File 'lib/acpc_table_manager/table_queue.rb', line 86

def my_matches
  Match.where(game_definition_key: @game_definition_key.to_sym)
end

#ports_in_useObject



100
101
102
103
104
105
106
107
# File 'lib/acpc_table_manager/table_queue.rb', line 100

def ports_in_use
  @running_matches.values.inject([]) do |ports, m|
    if m[:dealer] && m[:dealer][:port_numbers]
      m[:dealer][:port_numbers].each { |n| ports << n.to_i }
    end
    ports
  end
end

#start_players!(match) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/acpc_table_manager/table_queue.rb', line 44

def start_players!(match)
  opponents = match.bots(AcpcTableManager.config.dealer_host)

  if opponents.empty?
    force_kill_match! match.id.to_s
    raise StandardError.new("No opponents found to start for #{match.id.to_s}! Killed match.")
  end

  Opponents.start(
    *opponents.map { |name, info| [info[:runner], info[:host], info[:port]] }
  )
  log(__method__, msg: "Opponents started for #{match.id.to_s}")

  start_proxy match
end

#start_proxy(match) ⇒ Object



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
# File 'lib/acpc_table_manager/table_queue.rb', line 60

def start_proxy(match)
  command = "bundle exec acpc_proxy -t #{AcpcTableManager.config_file} -m #{match.id.to_s}"
  log(
    __method__,
    {
      msg: "Starting proxy for #{match.id.to_s}",
      command: command
    }
  )

  @running_matches[match.id.to_s][:proxy] = Timeout::timeout(3) do
    pid = Process.spawn(command)
    Process.detach(pid)
    pid
  end

  log(
    __method__,
    {
      msg: "Started proxy for #{match.id.to_s}",
      pid: @running_matches[match.id.to_s][:proxy]
    }
  )
  @running_matches[match.id.to_s]
end