Skip to content

Commit 02451fd

Browse files
authored
Merge pull request #149 from simonlindholm/line-buffering
Do manual line buffering in Python
2 parents 39e166e + 0e06ed9 commit 02451fd

1 file changed

Lines changed: 20 additions & 12 deletions

File tree

battlecode-manager/server.py

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -346,8 +346,26 @@ def __init__(self, *args, **kwargs):
346346
self.error = ""
347347
self.logged_in = False
348348
self.is_unix_stream = is_unix_stream
349+
self.buffer_small = b''
350+
self.buffer_large = []
351+
349352
super(ReceiveHandler, self).__init__(*args, **kwargs)
350353

354+
def read_line(self):
355+
while True:
356+
if self.buffer_small:
357+
pos = self.buffer_small.find(b'\n')
358+
if pos != -1:
359+
ret = b''.join(self.buffer_large) + self.buffer_small[:pos]
360+
self.buffer_small = self.buffer_small[pos+1:]
361+
self.buffer_large = []
362+
return ret
363+
else:
364+
self.buffer_large.append(self.buffer_small)
365+
self.buffer_small = self.request.recv(4096)
366+
if not self.buffer_small:
367+
raise IOError("reached socket EOF before finding newline")
368+
351369
def get_next_message(self) -> object:
352370
'''
353371
Returns the json loaded object of the next string that is sent over the
@@ -361,16 +379,14 @@ def get_next_message(self) -> object:
361379
recv_socket = self.request
362380
game = self.game
363381

364-
wrapped_socket = recv_socket.makefile('rwb', 1)
365382
logging.debug("Client %s: Waiting for next message", self.client_id)
366383
try:
367-
data = next(wrapped_socket)
384+
data = self.read_line()
368385
except (StopIteration, IOError):
369386
print("{} has not sent message for {} seconds, assuming they're dead".format(
370387
self.game.get_player(self.client_id)['player'],
371388
TIMEOUT
372389
))
373-
wrapped_socket.close()
374390
recv_socket.close()
375391
if bc.Team.Red == self.game.get_player(self.client_id)['player'].team:
376392
self.game.winner = 'player2'
@@ -386,7 +402,6 @@ def get_next_message(self) -> object:
386402
self.game.game_over = True
387403
raise TimeoutError()
388404
except KeyboardInterrupt:
389-
wrapped_socket.close()
390405
recv_socket.close()
391406
if bc.Team.Red == self.game.get_player(self.client_id)['player'].team:
392407
self.game.winner = 'player2'
@@ -401,8 +416,6 @@ def get_next_message(self) -> object:
401416
self.game.disconnected = True
402417
self.game.game_over = True
403418
raise KeyboardInterrupt()
404-
finally:
405-
wrapped_socket.close()
406419

407420
data = data.decode("utf-8").strip()
408421
return data
@@ -432,11 +445,9 @@ def send_message(self, obj: object) -> None:
432445
logging.debug("Client %s: Sending message %s", self.client_id,
433446
encoded_message)
434447

435-
wrapped_socket = send_socket.makefile('rwb', 1)
436448
try:
437-
wrapped_socket.write(encoded_message)
449+
self.request.sendall(encoded_message)
438450
except IOError:
439-
wrapped_socket.close()
440451
send_socket.close()
441452
print("{} has not accepted message for {} seconds, assuming they're dead".format(
442453
[p for p in self.game.players if p['id'] == self.client_id][0]['player'],
@@ -456,7 +467,6 @@ def send_message(self, obj: object) -> None:
456467
self.game.game_over = True
457468
raise TimeoutError()
458469
except KeyboardInterrupt:
459-
wrapped_socket.close()
460470
send_socket.close()
461471
if bc.Team.Red == self.game.get_player(self.client_id)['player'].team:
462472
self.game.winner = 'player2'
@@ -471,8 +481,6 @@ def send_message(self, obj: object) -> None:
471481
self.game.disconnected = True
472482
self.game.game_over = True
473483
raise KeyboardInterrupt()
474-
finally:
475-
wrapped_socket.close()
476484
return
477485

478486
def message(self, state_diff):

0 commit comments

Comments
 (0)