def _check_session_timeout_routine(self):
        while True:
            if self._session_timeout > 0:
                # session timeout check is enable
                now = get_monotonic_time()
                timeout_sessions = []
                for session in self._sessions.values():
                    if now - session.last_activity > self._session_timeout:
                        timeout_sessions.append(session)
                for session in timeout_sessions:
                    self._sessions.pop(session.session_id,
                                       None)  # avoid future usage

                # kick out all timeout session
                for session in timeout_sessions:
                    try:
                        self._kick_timeout_sessions(session)
                    except Exception as e:
                        log.exception(
                            'Failed to kick out the timeout session "{}"'.
                            format(session.session_id))
                timeout_sessions.clear()
                delta_time = get_monotonic_time() - now
                if delta_time < TIMEOUT_CHECK_INTERVAL:
                    gevent.sleep(TIMEOUT_CHECK_INTERVAL - delta_time)
            else:
                # session timeout check is disable, just None loop
                gevent.sleep(TIMEOUT_CHECK_INTERVAL)
Exemple #2
0
    def pingpong(self):
        try:
            if self._ws_client is None:
                self._ws_client = WSClient(self.url,
                                           self._recv_msg_cbk,
                                           self._close_cbk,
                                           protocols=['janus-protocol'])
            ping_start_ts = get_monotonic_time()
            self.send_request(self._ws_client, create_janus_msg('ping'))
            ping_end_ts = get_monotonic_time()
            ping_latency = ping_end_ts - ping_start_ts
            if self._hwm_threshold and ping_latency > self._hwm_threshold:
                self.set_status(JANUS_SERVER_STATUS_HWM)
            else:
                self.set_status(JANUS_SERVER_STATUS_NORMAL)

        except Exception as e:
            if self._has_destroy:
                return
            log.warning('Poll janus server({}) failed: {}'.format(self.url, e))
            self.set_status(JANUS_SERVER_STATUS_ABNORMAL)
            if self._ws_client:
                try:
                    self._ws_client.close()
                except Exception:
                    pass
                self._ws_client = None
Exemple #3
0
 def send_message(self, message, timeout=30):
     """
     send message
     :param message: object which can be encoded by msg_encoder (by default json encoder)
     :param timeout: send timeout in second, if timeout, gevent.Timeout exception will be raised
     :return:
     """
     if self.server_terminated:
         raise Exception('Already closed: {0}'.format(self))
     if self._pingpong_trigger:
         self._last_active_ts = get_monotonic_time()
     with gevent.Timeout(seconds=timeout):
         self.send(self._msg_encoder.encode(message), binary=False)
Exemple #4
0
 def received_message(self, message):
     if self._pingpong_trigger:
         self._last_active_ts = get_monotonic_time()
     if message.is_text:
         # log.debug('Received message from {0}: {1}'.format(self, message))
         if self._recv_msg_cbk:
             try:
                 self._recv_msg_cbk(
                     self, self._msg_decoder.decode(str(message)),
                     self._on_recv_msg_cbk_greenlet_exception)
             except Exception:
                 log.exception(
                     'Failed to handle received msg on {0}'.format(self))
                 raise
Exemple #5
0
 def _pingpong_check_routine(self):
     while not self.server_terminated:
         gevent.sleep(1)
         if self.server_terminated:
             break
         now = get_monotonic_time()
         # check pingpong timeout
         if self._ping_ts:
             if now - self._ping_ts > self._pingpong_timeout:
                 log.debug(
                     'Close ws connection ({}) because of no pong'.format(
                         self))
                 self.close()
                 break
         # send ping if idle
         if self._last_active_ts and now - self._last_active_ts >= self._pingpong_trigger:
             try:
                 self.ping('')
                 self._last_active_ts = self._ping_ts = get_monotonic_time()
             except Exception as e:
                 log.error('Fail to send ping on {}: {}'.format(
                     self, str(e)))
                 self.close()
                 break
Exemple #6
0
    def opened(self):
        # patch socket.sendall to protect it with lock,
        # in order to prevent sending data from multiple greenlets concurrently
        lock = RLock()
        _sendall = self.sock.sendall

        def sendall(data):
            lock.acquire()
            try:
                _sendall(data)
            except Exception:
                raise
            finally:
                lock.release()

        self.sock.sendall = sendall

        # start check idle
        if self._pingpong_trigger:
            self._last_active_ts = get_monotonic_time()
            self._pingpong_check_greenlet = gevent.spawn(
                self._pingpong_check_routine)

        # create app
        try:
            if not self.environ.get('QUERY_STRING'):
                query = {}
            else:
                query = urllib.parse.parse_qs(self.environ['QUERY_STRING'],
                                              keep_blank_values=True)
            for key, value in query.items():
                query[key] = value[0]
            self._recv_msg_cbk = self.environ['app.recv_msg_cbk']
            self._closed_cbk = self.environ['app.closed_cbk']
            log.info('Created {0}'.format(self))
        except Exception:
            log.exception('Failed to create app for {0}'.format(self))
            raise
Exemple #7
0
    def check_idle(self):
        try:
            if self._has_destroy:
                return

            if self._server_status == JANUS_SERVER_STATUS_ABNORMAL:
                # server abnormal, pass idel check
                return

            if self._handle is None:
                # not connect server, connect first
                self.connect_server()

            handle = self._handle

            # 1. get room list
            reply_data, reply_jsep = _send_backend_message(
                handle, {'request': 'list'})
            room_list_info = reply_data.get('list', [])

            # 2. find out idle rooms and timeout rooms
            now = get_monotonic_time()
            idle_rooms = {}
            timeout_room_ids = []
            for room_info in room_list_info:
                room_id = int(room_info.get('room', 0))

                if room_id == 0:
                    continue  # pass invalid or in-service room
                elif not room_info.get('description', '').startswith(
                        self.des_filwter):
                    continue  # pass not januscloud-created room
                elif room_info.get('num_participants', 1) > 0:
                    continue  # not idle

                # this is a idle room
                idle_ts = self._idle_rooms.get(room_id, 0)
                if idle_ts == 0:
                    # new idle room
                    idle_rooms[room_id] = now
                elif now - idle_ts > self.destroy_timeout:
                    # timeout room
                    timeout_room_ids.append(room_id)
                else:
                    # old idle room
                    idle_rooms[room_id] = idle_ts
            self._idle_rooms = idle_rooms

            # 3. destroy the timeout rooms
            for room_id in timeout_room_ids:
                # auto destroy the idle room
                log.warning(
                    'Sweeper found the backend idle room {}, destroy it'.
                    format(room_id))
                handle.send_message({'request': 'destroy', 'room': room_id})

        except Exception as e:
            if self._handle:
                handle = self._handle
                self._handle = None
                handle.detach()
            # ignore all exception when check
            log.debug(
                'Videoroom sweeper check failed on server "{}" : {}. Retry in {} secs'
                .format(self.url, str(e), self.check_interval))
            pass
Exemple #8
0
 def ponged(self, pong):
     self._ping_ts = 0
     self._last_active_ts = get_monotonic_time()
 def activate(self):
     self.last_activity = get_monotonic_time()
 def __init__(self, session_id, transport=None):
     self.session_id = session_id
     self.ts = transport
     self._handles = {}
     self.last_activity = get_monotonic_time()
     self._has_destroyed = False