Made the tail-viewing of a log-file threaded for maximum asynchronicity.

This commit is contained in:
Griatch 2016-04-07 23:22:26 +02:00
parent 5583a8d758
commit 4a58fcb9f1
2 changed files with 29 additions and 10 deletions

View file

@ -100,8 +100,9 @@ class ChannelCommand(command.Command):
if self.history_start is not None: if self.history_start is not None:
# Try to view history # Try to view history
log_file = channel.attributes.get("log_file", default="channel_%s.log" % channel.key) log_file = channel.attributes.get("log_file", default="channel_%s.log" % channel.key)
self.msg("".join(line.split("[-]", 1)[1] if "[-]" in line else line send_msg = lambda lines: self.msg("".join(line.split("[-]", 1)[1]
for line in tail_log_file(log_file, self.history_start, 20))) if "[-]" in line else line for line in lines))
tail_log_file(log_file, self.history_start, 20, callback=send_msg)
else: else:
channel.msg(msg, senders=self.caller, online=True) channel.msg(msg, senders=self.caller, online=True)

View file

@ -208,7 +208,7 @@ def log_file(msg, filename="game.log"):
deferToThread(callback, filehandle, msg).addErrback(errback) deferToThread(callback, filehandle, msg).addErrback(errback)
def tail_log_file(filename, offset, nlines): def tail_log_file(filename, offset, nlines, callback=None):
""" """
Return the tail of the log file. Return the tail of the log file.
@ -219,16 +219,19 @@ def tail_log_file(filename, offset, nlines):
reading from. 0 means to start at the latest entry. reading from. 0 means to start at the latest entry.
nlines (int): How many lines to return, counting backwards nlines (int): How many lines to return, counting backwards
from the offset. If file is shorter, will get all lines. from the offset. If file is shorter, will get all lines.
callback (callable, optional): A function to manage the result of the
asynchronous file access. This will get a list of lines. If unset,
the tail will happen synchronously.
Returns: Returns:
lines (list): The nline entries from the end of the file, or lines (deferred or list): This will be a deferred if `callable` is given,
otherwise it will be a list with The nline entries from the end of the file, or
all if the file is shorter than nlines. all if the file is shorter than nlines.
""" """
lines_found = [] def seek_file(filehandle, offset, nlines, callback):
filehandle = _open_log_file(filename) "step backwards in chunks and stop only when we have enough lines"
if filehandle: lines_found = []
# step backwards in chunks and stop only when we have enough lines
buffer_size = 4098 buffer_size = 4098
block_count = -1 block_count = -1
while len(lines_found) < (offset + nlines): while len(lines_found) < (offset + nlines):
@ -242,8 +245,23 @@ def tail_log_file(filename, offset, nlines):
break break
lines_found = filehandle.readlines() lines_found = filehandle.readlines()
block_count -= 1 block_count -= 1
# return the right number of lines # return the right number of lines
return lines_found[-nlines-offset:-offset if offset else None] lines_found = lines_found[-nlines-offset:-offset if offset else None]
if callback:
callback(lines_found)
else:
return lines_found
def errback(failure):
"Catching errors to normal log"
log_trace()
filehandle = _open_log_file(filename)
if filehandle:
if callback:
deferToThread(seek_file, filehandle, offset, nlines, callback).addErrback(errback)
else:
return seek_file(filehandle, offset, nlines, callback)