def timeout(process, callback): for (timeout, complaint) in config.timeouts(): try: return_code = process.wait(timeout) if return_code != 0: return "ERROR: compressor returned status {0}".format(return_code) else: return callback() except subprocess.TimeoutExpired: print(complaint) # timed out p.kill() return float('inf')
def my_compressor(fname, paranoia, base, algorithms): try: def error_str(suffix): return 'multi_compressor: {0} with {1} (paranoia={2}) on {3}: {4}'\ .format(base, algorithms, paranoia, fname, suffix) if paranoia: # Slow but makes sure the results are valid. # Uses the standard Compressor interface to compress the file then decompress it, # and verifies the decompressed file is the same as the original compressor = build_my_compressor(base, algorithms) return compressed_filesize(compressor, fname, paranoia) else: # Uses the MultiCompressor interface with the measure command. # Runs commands in the same JVM, one after the other, and doesn't write any files. # Faster, but doesn't perform any verification checks. global multi_compressor if not multi_compressor: multi_compressor = run_multicompressor() cmd = 'measure {0} '.format(corpus_path(fname)) cmd += ' '.join(my_compressor_end_args(base, algorithms)) + '\n' try: multi_compressor.stdin.write(cmd) except BrokenPipeError: print("WARNING: MultiCompressor has quit, restarting.") multi_compressor.kill() # make sure it's dead multi_compressor = run_multicompressor() # if this still fails, propagate the exception (only retry once) multi_compressor.stdin.write(cmd) for (timeout, complaint) in config.timeouts(): ready_read, _, _ = select.select([multi_compressor.stdout, multi_compressor.stderr], [], [], timeout) if not ready_read: print(error_str(complaint)) if multi_compressor.stderr in ready_read: for line in multi_compressor.stderr: print(error_str("received error from MultiCompressor: " + line.strip())) if multi_compressor.stdout in ready_read: out = multi_compressor.stdout.readline().strip() prefix = 'BITS WRITTEN: ' if out.find(prefix) != 0: raise RuntimeError(error_str("unexpected output: '" + out + "'")) bits = int(out[len(prefix):]) return bits / 8 # compressed filesize in bytes multi_compressor.kill() multi_compressor = None return float('inf') except Exception: print(error_str("error executing task: " + traceback.format_exc())) return float('inf')