Skip to content

Commit 7d9cf16

Browse files
committed
Restart search automatically after a timeout
1 parent 4c0a791 commit 7d9cf16

File tree

2 files changed

+68
-2
lines changed

2 files changed

+68
-2
lines changed

server/ladder_service.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -379,17 +379,38 @@ async def confirm_match(
379379

380380
await self.start_game(s1.players, s2.players, queue)
381381
except OfferTimeoutError:
382+
unready_players = list(offer.get_unready_players())
382383
self._logger.info(
383384
"Match failed to start. Some players did not ready up in time: %s",
384-
list(player.login for player in offer.get_unready_players())
385+
[player.login for player in unready_players]
385386
)
386387
# TODO: Refactor duplication
387388
msg = {"command": "match_cancelled"}
388389
for player in all_players:
389390
if player.state == PlayerState.STARTING_AUTOMATCH:
390391
player.state = PlayerState.IDLE
391392
player.write_message(msg)
392-
# TODO: Unmatch and return to queue
393+
394+
# Return any player that accepted the match back to the queue
395+
# TODO: make this work with parties
396+
for player in s1.players:
397+
if player in unready_players:
398+
self.cancel_search(player)
399+
else:
400+
s1.unmatch()
401+
asyncio.create_task(queue.search(s1))
402+
403+
for player in s2.players:
404+
if player in unready_players:
405+
self.cancel_search(player)
406+
else:
407+
s2.unmatch()
408+
asyncio.create_task(queue.search(s2))
409+
except Exception as e:
410+
self._logger.exception(
411+
"Error processing match between searches %s, and %s: %s",
412+
s1, s2, e
413+
)
393414

394415
def create_match_offer(self, players: Iterable[Player]):
395416
offer = MatchOffer(

tests/integration_tests/test_matchmaker.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,51 @@ async def test_game_matchmaking_start_while_matched(lobby_server):
122122
assert msg["text"].startswith("Can't join a queue while ladder1 is in")
123123

124124

125+
@fast_forward(100)
126+
async def test_game_matchmaking_search_after_timeout(lobby_server, database):
127+
proto1 = await queue_player_for_matchmaking(
128+
('ladder1', 'ladder1'),
129+
lobby_server,
130+
"ladder1v1"
131+
)
132+
proto2 = await queue_player_for_matchmaking(
133+
('ladder2', 'ladder2'),
134+
lobby_server,
135+
"ladder1v1"
136+
)
137+
138+
await read_until_command(proto1, "match_info")
139+
await read_until_command(proto2, "match_info")
140+
141+
# Only player 1 readies up
142+
await proto1.send_message({"command": "match_ready"})
143+
144+
# So the match times out
145+
await read_until_command(proto1, "match_cancelled")
146+
await read_until_command(proto2, "match_cancelled")
147+
148+
# At this point the search for player 2 should be cancelled, but player 1
149+
# should still be in the queue
150+
msg = await read_until_command(proto2, "search_info")
151+
assert msg == {
152+
"command": "search_info",
153+
"queue_name": "ladder1v1",
154+
"state": "stop"
155+
}
156+
157+
# Player 2 joins the queue again
158+
await proto2.send_message({
159+
"command": "game_matchmaking",
160+
"state": "start",
161+
"faction": "seraphim",
162+
"mod": "ladder1v1"
163+
})
164+
165+
# The players should match
166+
await read_until_command(proto1, "match_info")
167+
await read_until_command(proto2, "match_info")
168+
169+
125170
@fast_forward(120)
126171
async def test_game_matchmaking_timeout(lobby_server, game_service):
127172
proto1, proto2 = await queue_players_for_matchmaking(lobby_server)

0 commit comments

Comments
 (0)