Beispiel #1
0
 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)
Beispiel #2
0
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)