def __init__(self, dao, keepalive_timeout=60): self._dao = dao self._keepalive_timeout = keepalive_timeout self._record_config_mngr = None self._agent_client = RecordAgentClient() gevent.spawn(self._check_greenlet)
class RecordAgentManager(object): def __init__(self, dao, keepalive_timeout=60): self._dao = dao self._keepalive_timeout = keepalive_timeout self._record_config_mngr = None self._agent_client = RecordAgentClient() gevent.spawn(self._check_greenlet) def set_record_config_mngr(self, record_config_mngr): self._record_config_mngr = record_config_mngr def get_agent(self, agent_id): agent = self._dao.get_by_agent_id(agent_id) if not agent: raise IVRError('Unknown record agent {0}'.format(agent_id)) return agent def get_agent_list(self, filter_name=None, filter_value=''): return self._dao.get_list(filter_name=filter_name, filter_value=filter_value) def add_agent(self, *args, **kwargs): agent = RecordAgent(*args, **kwargs) self._dao.add(agent) def update_agent_by_id(self, agent_id, **kwargs): agent = self.get_agent(agent_id) for k, v in kwargs: setattr(agent, k, v) self._dao.update(agent) def update_agent(self, agent): self._dao.update(agent) def _keepalive_sessions(self, agent_id, session_id_list): keepalive_time = datetime.datetime.now() for session_id in session_id_list: try: self._record_config_mngr.record_session_keepalive(session_id, keepalive_time=keepalive_time) except RecordSessionNotFoundError: log.exception('Try to stop unknown record session {0}'.format(session_id)) self.stop_record(agent_id, session_id) except Exception: log.exception('Failed to keeepalive record sesion {0}'.format(session_id)) def keepalive(self, agent_id, endpoint, load, session_id_list): agent = self._dao.get_by_agent_id(agent_id) if agent is None: log.info('New agent {0} online'.format(agent)) agent = RecordAgent(agent_id, endpoint, load=load, last_keepalive=datetime.datetime.now()) self._dao.add(agent) else: log.info('keepalive {0}'.format(agent)) agent.endpoint = endpoint agent.load = load agent.last_keepalive = datetime.datetime.now() self._dao.update(agent) if session_id_list: gevent.spawn(self._keepalive_sessions, agent_id, session_id_list) def pick(self): agent_list = self.get_agent_list() for agent in agent_list: if agent.is_available(): return agent raise IVCNoAvailableRecordAgentError() def start_record(self, agent, project_name, camera_id, record_session_id, stream_url, upload_cbk_url): try: succeed, load = self._agent_client.start_record( agent.endpoint, record_session_id, project_name, camera_id, stream_url, upload_cbk_url) except Exception: log.exception('Failed to request start record session {0} to {1}'.format(record_session_id, agent)) agent.load = Load.ERROR self._dao.update(agent) raise else: agent.load = load self._dao.update(agent) if not succeed: raise IVRError('Failed to start record session {0} on {1}'.format(record_session_id, agent)) def stop_record(self, agent_id, record_session_id): agent = self.get_agent(agent_id) try: succeed, load = self._agent_client.stop_record( agent.endpoint, record_session_id) except Exception: log.exception('Failed to request stop record session {0} to {1}'.format(record_session_id, agent)) agent.load = Load.ERROR self._dao.update(agent) else: agent.load = load self._dao.update(agent) if not succeed: raise IVRError('Failed to stop record session {0} on {1}'.format(record_session_id, agent)) def _check_greenlet(self): while True: try: agent_list = self.get_agent_list() for agent in agent_list: if not agent.is_offline() and agent.is_timeout(self._keepalive_timeout): # found timeout agent # TODO handle all ongoing record task on this agent agent.load = Load.OFFLINE self.update_agent(agent) except Exception: log.exception('Failed to check offline record agent') finally: gevent.sleep(30)