Only return definitely-writen lines from IRCSocket._send, refactor in prep for

lines that request to be sent 'immediately'
This commit is contained in:
jesopo 2019-06-04 14:28:35 +01:00
parent a802e66dcf
commit 4a4d0a37d7
3 changed files with 29 additions and 20 deletions

View file

@ -126,12 +126,13 @@ class SentLine(IRCObject.Object):
encoded += encoded_character encoded += encoded_character
return (encoded, truncated) return (encoded, truncated)
def _data(self) -> bytes: def _for_wire(self) -> bytes:
return self._encode_truncate()[0] return self._encode_truncate()[0]
def data(self) -> bytes: def for_wire(self) -> bytes:
return b"%s\r\n" % self._data() return b"%s\r\n" % self._for_wire()
def decoded_data(self) -> str: def decoded_data(self) -> str:
return self._data().decode("utf8") return self._for_wire().decode("utf8")
def truncated(self) -> str: def truncated(self) -> str:
return self._encode_truncate()[1] return self._encode_truncate()[1]

View file

@ -242,7 +242,7 @@ class Server(IRCObject.Object):
return lines return lines
def send(self, line_parsed: IRCLine.ParsedLine): def send(self, line_parsed: IRCLine.ParsedLine, immediate: bool=False):
if not self.send_enabled: if not self.send_enabled:
return None return None
@ -254,7 +254,7 @@ class Server(IRCObject.Object):
line = line_parsed.format() line = line_parsed.format()
line_obj = IRCLine.SentLine(datetime.datetime.utcnow(), self.hostmask(), line_obj = IRCLine.SentLine(datetime.datetime.utcnow(), self.hostmask(),
line_parsed) line_parsed)
self.socket.send(line_obj) self.socket.send(line_obj, immediate=immediate)
return line_obj return line_obj
def send_raw(self, line: str): def send_raw(self, line: str):
return self.send(utils.irc.parse_line(line)) return self.send(utils.irc.parse_line(line))
@ -262,8 +262,10 @@ class Server(IRCObject.Object):
def _send(self): def _send(self):
lines = self.socket._send() lines = self.socket._send()
for line in lines: for line in lines:
self.bot.log.debug("%s (raw send) | %s", [str(self), line.format()]) self.bot.log.debug("%s (raw send) | %s", [
self.events.on("raw.send").call_unsafe(server=self, line=line) str(self), line.parsed_line.format()])
self.events.on("raw.send").call_unsafe(server=self,
line=line.parsed_line)
def send_user(self, username: str, realname: str) -> IRCLine.SentLine: def send_user(self, username: str, realname: str) -> IRCLine.SentLine:
return self.send(utils.irc.protocol.user(username, realname)) return self.send(utils.irc.protocol.user(username, realname))

View file

@ -119,12 +119,17 @@ class Socket(IRCObject.Object):
self.last_read = time.monotonic() self.last_read = time.monotonic()
return decoded_lines return decoded_lines
def send(self, line: IRCLine.SentLine): def _immediate_buffer(self, line: IRCLine.SentLine):
self._write_buffer += line.for_wire()
self._buffered_lines.append(line)
def send(self, line: IRCLine.SentLine, immediate: bool=False):
if immediate:
self._immediate_buffer(line)
else:
self._queued_lines.append(line) self._queued_lines.append(line)
def _send(self) -> typing.List[IRCLine.ParsedLine]: def _send(self) -> typing.List[IRCLine.SentLine]:
sent_lines = []
if not self._write_buffer and self._throttle_when_empty: if not self._write_buffer and self._throttle_when_empty:
self._throttle_when_empty = False self._throttle_when_empty = False
self._write_throttling = True self._write_throttling = True
@ -135,23 +140,24 @@ class Socket(IRCObject.Object):
to_buffer = self._queued_lines[:throttle_space] to_buffer = self._queued_lines[:throttle_space]
self._queued_lines = self._queued_lines[throttle_space:] self._queued_lines = self._queued_lines[throttle_space:]
for line in to_buffer: for line in to_buffer:
sent_lines.append(line.parsed_line) self._immediate_buffer(line)
self._write_buffer += line.data()
self._buffered_lines.append(line)
bytes_written_i = self._socket.send(self._write_buffer) bytes_written_i = self._socket.send(self._write_buffer)
bytes_written = self._write_buffer[:bytes_written_i] bytes_written = self._write_buffer[:bytes_written_i]
lines_sent = bytes_written.count(b"\r\n")
for i in range(lines_sent): sent_lines_count = bytes_written.count(b"\r\n")
self._buffered_lines.pop(0).sent() sent_lines = [] # type: typing.List[IRCLine.SentLine]
for i in range(sent_lines_count):
sent_line = self._buffered_lines.pop(0)
sent_line.sent()
sent_lines.append(sent_line)
self._write_buffer = self._write_buffer[bytes_written_i:] self._write_buffer = self._write_buffer[bytes_written_i:]
self.bytes_written += bytes_written_i self.bytes_written += bytes_written_i
now = time.monotonic() now = time.monotonic()
self._recent_sends.extend([now]*lines_sent) self._recent_sends.extend([now]*sent_lines_count)
self.last_send = now self.last_send = now
return sent_lines return sent_lines