def test_should_not_block_on_many_writes_if_no_input_being_received_by_the_process( self): process = Process("./tests/models/output-once.sh") process.start() for _ in range(100000): process.write({'aaa': 'bbb'})
def test_should_read_and_write(self): process = Process("./tests/models/output-echo.sh") process.start() time.sleep(1) assert process.read() is None for value in ['value1', 'value2', 'value3']: process.write({'key': value}) while process.read() != {'key': value}: time.sleep(0.1) process.stop()
def test_should_terminate_process_on_broken_input_pipe(self): process = Process("./tests/models/break-pipe.sh") process.start() # so the process has some time to break the pipe time.sleep(1) for _ in range(10): process.write({'aaa': 'bbb'}) time.sleep(5) assert process.running is False
class Model: logger = logging.getLogger() def __init__(self, command: str, parameters: Parameters): assert isinstance(command, str) assert isinstance(parameters, Parameters) self._command = command self._arguments = f"--id {parameters.id}" self._arguments += f" --flipper {parameters.flipper}" if parameters.flipper is not None else "" self._arguments += f" --flapper {parameters.flapper}" if parameters.flapper is not None else "" self._arguments += f" --flopper {parameters.flopper}" if parameters.flopper is not None else "" self._last_output = None self.logger.info( f"Instantiated model using process '{self._command} {self._arguments}'" ) self._process = Process(f"{self._command} {self._arguments}") self._process.start() def _ensure_process_running(self): if not self._process.running: self.logger.warning( f"Process '{self._command} {self._arguments}' is down, restarting it" ) self._process.start() def send_status(self, input: Status): assert isinstance(input, Status) self._ensure_process_running() record = { "id": str(input.id), "bid": str(input.bid), "lot": str(input.lot), "beg": str(input.beg), "guy": str(input.guy), "era": int(input.era), "tic": int(input.tic), "end": int(input.end), "price": str(input.price) if input.price is not None else None, } if input.tab: record['tab'] = str(input.tab) if input.flipper: record['flipper'] = str(input.flipper) if input.flapper: record['flapper'] = str(input.flapper) if input.flopper: record['flopper'] = str(input.flopper) self._process.write(record) def get_stance(self) -> Optional[Stance]: self._ensure_process_running() while True: data = self._process.read() if data is not None: self._last_output = Stance(price=Wad.from_number( data['price']), gas_price=int(data['gasPrice']) if 'gasPrice' in data else None) else: break return self._last_output def terminate(self): self.logger.info( f"Terminating model using process '{self._command} {self._arguments}'" ) self._process.stop()
class Model: logger = logging.getLogger() def __init__(self, command: str, parameters: Parameters): assert isinstance(command, str) assert isinstance(parameters, Parameters) self._command = command self._arguments = f"--id {parameters.id}" self._arguments += f" --collateral_auction_house {parameters.collateral_auction_house}" if parameters.collateral_auction_house is not None else "" self._arguments += f" --surplus_auction_house {parameters.surplus_auction_house}" if parameters.surplus_auction_house is not None else "" self._arguments += f" --debt_auction_house {parameters.debt_auction_house}" if parameters.debt_auction_house is not None else "" self._arguments += f" --staked_token_auction_house {parameters.staked_token_auction_house}" if parameters.staked_token_auction_house is not None else "" self._last_output = None self.logger.info( f"Instantiated model using process '{self._command} {self._arguments}'" ) self._process = Process(f"{self._command} {self._arguments}") self._process.start() def _ensure_process_running(self): if not self._process.running: self.logger.warning( f"Process '{self._command} {self._arguments}' is down, restarting it" ) self._process.start() def send_status(self, input: Status): assert isinstance(input, Status) self._ensure_process_running() record = input.to_dict() self._process.write(record) def get_stance(self) -> Optional[Stance]: self._ensure_process_running() while True: data = self._process.read() if data is not None: self._last_output = Stance(price=Wad.from_number(data['price']) if 'price' in data else None, gas_price=int(data['gasPrice']) if 'gasPrice' in data else None) else: break return self._last_output def terminate(self): self.logger.info( f"Terminating model using process '{self._command} {self._arguments}'" ) self._process.stop()