Improved the auto flushing, made it time and buffer size based.

In case a specific directory was taking a while, I changed it to auto
flush after a specified period of time.  Right now autoflush is
automatically disabled, you have to enable it when creating the console.

TODO:  I'll probably hook the console up to the stdout and stderr so you
can use ordinary print statements, we'll see. This is desirable for
easily hooking it into an existing module.
This commit is contained in:
Brian 2014-05-09 17:36:49 -06:00
parent c175b21dcf
commit 55a5e41b00
1 changed files with 10 additions and 3 deletions

View File

@ -11,7 +11,7 @@
# todo: buffer output, after exceeding a certain amount print to the output. # todo: buffer output, after exceeding a certain amount print to the output.
# todo: allow logging output besides console output, or redirection altogether # todo: allow logging output besides console output, or redirection altogether
import inspect, multiprocessing, optparse, os, platform, re, stat, subprocess, sys, threading, traceback import datetime, inspect, multiprocessing, optparse, os, re, stat, subprocess, sys, threading, traceback
# trying ntpath, need to test on linux # trying ntpath, need to test on linux
import ntpath import ntpath
@ -115,13 +115,15 @@ class PDict( dict ):
class Console( threading.Thread ): class Console( threading.Thread ):
MSG = enum('WRITE', 'FLUSH', 'SHUTDOWN', 'CLEAR' ) MSG = enum('WRITE', 'FLUSH', 'SHUTDOWN', 'CLEAR' )
# auto_flush_time is time in milliseconds since last flush to trigger a flush when writing
def __init__( self, auto_flush_num = None, auto_flush_time = None ): def __init__( self, auto_flush_num = None, auto_flush_time = None ):
threading.Thread.__init__( self ) threading.Thread.__init__( self )
self.buffers = {} self.buffers = {}
self.buffer_write_times = {}
self.running = True self.running = True
self.queue = multiprocessing.JoinableQueue( ) self.queue = multiprocessing.JoinableQueue( )
self.auto_flush_num = auto_flush_num if auto_flush_num is not None else -1 self.auto_flush_num = auto_flush_num if auto_flush_num is not None else -1
self.auto_flush_time = auto_flush_time if auto_flush_time is not None else -1 self.auto_flush_time = auto_flush_time * 1000 if auto_flush_time is not None else -1
def write( self, data, pid = None ): def write( self, data, pid = None ):
self.queue.put( ( Console.MSG.WRITE, pid if pid is not None else os.getpid(), data ) ) self.queue.put( ( Console.MSG.WRITE, pid if pid is not None else os.getpid(), data ) )
@ -164,9 +166,13 @@ class Console( threading.Thread ):
if pid not in self.buffers: if pid not in self.buffers:
self.buffers[ pid ] = [] self.buffers[ pid ] = []
if pid not in self.buffer_write_times:
self.buffer_write_times[ pid ] = datetime.datetime.now( )
self.buffers[ pid ].append( s ) self.buffers[ pid ].append( s )
if self.auto_flush_num >= 0 and len( self.buffers[ pid ] ) > self.auto_flush_num: if self.auto_flush_num >= 0 and len( self.buffers[ pid ] ) >= self.auto_flush_num:
self.flush( pid )
elif self.auto_flush_time >= 0 and ( datetime.datetime.now( ) - self.buffer_write_times[ pid ] ).microseconds >= self.auto_flush_time:
self.flush( pid ) self.flush( pid )
elif event == Console.MSG.FLUSH: elif event == Console.MSG.FLUSH:
pid = data[ 1 ] pid = data[ 1 ]
@ -174,6 +180,7 @@ class Console( threading.Thread ):
for line in self.buffers[ pid ]: for line in self.buffers[ pid ]:
print( line ) print( line )
self.buffers.pop( pid, None ) self.buffers.pop( pid, None )
self.buffer_write_times[ pid ] = datetime.datetime.now( )
elif event == Console.MSG.CLEAR: elif event == Console.MSG.CLEAR:
pid = data[ 1 ] pid = data[ 1 ]
if pid in self.buffers: if pid in self.buffers: