between death of a process and its actual termination lies poorly documented requirement -
            <purging process' io pipes and reading exit status>.
            this can be done either by os.wait() or process.wait()
            :return tuple (boolean: alive, int: return_code)

def _poll_process(self):
        """ between death of a process and its actual termination lies poorly documented requirement -
            <purging process' io pipes and reading exit status>.
            this can be done either by os.wait() or process.wait()
            :return tuple (boolean: alive, int: return_code) """
        try:
            self.logger.warning(self.cli_process.stderr.read())
            self.logger.info(self.cli_process.stdout.read())
            return_code = self.cli_process.wait(timeout=0.01)
            if return_code is None:
                # process is already terminated
                self.logger.info('Process {0} is terminated'.format(self.process_name))
            else:
                # process is terminated; possibly by OS
                self.logger.info('Process {0} got terminated. Cleaning up'.format(self.process_name))
            self.cli_process = None
            return False, return_code
        except TimeoutExpired:
            # process is alive and OK
            return True, None
        except Exception:
            self.logger.error('Exception on polling: {0}'.format(self.process_name), exc_info=True)
            return False, 999