def __init__(self, config=None): """Initialize and configure a PipelineServer. :Parameters: ---------- config : dict Python representation of the yaml configuration file. Example: pipelines: # sequence of piped operations for use on front door cam daytime_front_door_watch: - source: *src_front_door_cam ... - detect_objects: # run ai inference on the input data ... - save_detections: # save samples from the inference results ... """ self._config = config self._threaded_jobs = [] self._pipelines = [] if config: pipelines_config = config.get('pipelines', None) if pipelines_config: # get main data dir config and pass # on to pipelines to use data_dir = config.get('data_dir', None) if not data_dir: data_dir = './data' self._pipelines = get_pipelines(pipelines_config, data_dir=data_dir) for pp in self._pipelines: pj = ThreadedJob(pp) self._threaded_jobs.append(pj)
class PipelineServer(ManagedService): """ Thin wrapper around PipelineServer constructs. Allows controlled start and stop of the web app server in a separate process. Parameters ---------- config : yaml reference to the yaml configuration file """ def __init__(self, config): self.config = config self.pipeline_server_job = None self._restarting = threading.Event() def trigger_event(self, event: config_mgm.ConfigChangedEvent): """Trigger change event on pipelines not running. Pipelines already runnig are already notified by rective configurations """ if self.pipeline_server_job is None: return if self._restarting.is_set(): return self._restarting.set() self.stop() self.start() self._restarting.clear() def start(self, **kwargs): log.info('PipelineServer server job starting...') f = PipelineServerJob(self.config) self.pipeline_server_job = ThreadedJob(f) self.pipeline_server_job.start() log.info('Pipeline server job started') def healthcheck(self): return time.monotonic(), True def heal(self): """Heal the server. TODO: Keep an eye for potential scenarios that cause this server to become unresponsive. """ def stop(self): if self.pipeline_server_job: log.info('Pipeline server job stopping...') self.pipeline_server_job.stop() self.pipeline_server_job.join() self.pipeline_server_job = None log.info('Pipeline server job stopped.')
def reset(self, config=None): self._threaded_jobs = [] self._pipelines = [] if config is not None: self._config = config if self._config: pipelines_config = self._config.get("pipelines", None) if pipelines_config: # get main data dir config and pass # on to pipelines to use data_dir = self._config.get("data_dir", DEFAULT_DATA_DIR) self._pipelines = get_pipelines(pipelines_config, data_dir=data_dir) for pp in self._pipelines: pj = ThreadedJob(pp) self._threaded_jobs.append(pj)
def reset(self, config=None): self._threaded_jobs = [] self._pipelines = [] if config is not None: self._config = config if self._config: pipelines_config = self._config.get('pipelines', None) if pipelines_config: # get main data dir config and pass # on to pipelines to use data_dir = self._config.get('data_dir', None) if not data_dir: data_dir = './data' self._pipelines = get_pipelines(pipelines_config, data_dir=data_dir) for pp in self._pipelines: pj = ThreadedJob(pp) self._threaded_jobs.append(pj)
def __init__(self, config=None): """Initialize and configure. Parameters ---------- config : dict Python representation of the yaml configuration file. """ self._config = config self._threaded_jobs = [] self._pipelines = [] if config: pipelines_config = config.get('pipelines', None) if pipelines_config: self._pipelines = get_pipelines(pipelines_config) for pp in self._pipelines: pj = ThreadedJob(pp) self._threaded_jobs.append(pj)
class PipelineServer(ManagedService): """Thin wrapper around PipelineServer constructs. Allows controlled start and stop of the web app server in a separate process. Parameters ---------- config : yaml reference to the yaml configuration file """ def __init__(self, config): self.config = config self.pipeline_server_job = None def start(self, **kwargs): log.info("PipelineServer server job starting...") f = PipelineServerJob(self.config) self.pipeline_server_job = ThreadedJob(f) self.pipeline_server_job.start() log.info("Pipeline server job started") def healthcheck(self): return time.monotonic(), True def heal(self): """Heal the server. TODO: Keep an eye for potential scenarios that cause this server to become unresponsive. """ def stop(self): if self.pipeline_server_job: log.info("Pipeline server job stopping...") try: self.pipeline_server_job.stop() self.pipeline_server_job.join() except RuntimeError as err: log.warning("Failed stopping: %s" % err) self.pipeline_server_job = None log.info("Pipeline server job stopped.")
class FlaskServer(ManagedService): """ Thin wrapper around Flask constructs. Allows controlled start and stop of the web app server in a separate process. Parameters ---------- config : yaml reference to the yaml configuration file """ def __init__(self, config): self.config = config self.flask_job = None def start(self, **kwargs): log.info('Flask server job starting...') f = FlaskJob(self.config) self.flask_job = ThreadedJob(f) self.flask_job.start() log.info('Flask server job started') def healthcheck(self): # Note: Implement actual health check for Flask # See if the /healthcheck URL returns a 200 quickly return time.monotonic(), True def heal(self): """Heal the server. TODO: Keep an eye for potential scenarios that cause this server to become unresponsive. """ def stop(self): if self.flask_job: log.info('Flask server job stopping...') self.flask_job.stop() self.flask_job.join() log.info('Flask server job stopped.')
def start(self, **kwargs): log.info('Flask server job starting...') f = FlaskJob(self.config) self.flask_job = ThreadedJob(f) self.flask_job.start() log.info('Flask server job started')
def test_heal(): ms = MockManagedService() tj = ThreadedJob(job=ms) tj.heal() assert ms._heal_called
def test_threaded_job_init_ms(): ms = MockManagedService() tj = ThreadedJob(job=ms) assert tj.job == ms
def test_threaded_job_init_no_ms(): with pytest.raises(AssertionError): ThreadedJob(job=[])
def start(self, **kwargs): log.info("PipelineServer server job starting...") f = PipelineServerJob(self.config) self.pipeline_server_job = ThreadedJob(f) self.pipeline_server_job.start() log.info("Pipeline server job started")
def test_threaded_job_init_no_job(): with pytest.raises(AssertionError): tj = ThreadedJob(job=None)