Esempio n. 1
0
def delete_connection_from_rooms(connection_id, user, rooms):
    user_has_left = False
    for room_id in rooms:
        room = get_room(room_id)
        if room:
            user_in_room = [u for u in room['users'] if u['id'] == user['id']]
            if len(user_in_room) > 0:
                user_in_room = user_in_room[0]
                if connection_id in user_in_room['connections']:
                    # remove connection from user
                    user_in_room['connections'].remove(connection_id)
                    if len(user_in_room['connections']) == 0:
                        # remove user from room
                        room['users'] = [
                            u for u in room['users'] if u['id'] != user['id']
                        ]
                        if len(room['users']) == 0:
                            # delete room
                            # fix rooms are also deleted, should be fine
                            # since chat history stays
                            redis_client.delete(room_id)
                            return
                        else:
                            user_has_left = True

                    redis_client.set(room_id, json.dumps(room))
                    if user_has_left:
                        # broadcast user left
                        broadcast_user_left(room_id, user)
Esempio n. 2
0
def revoke_token(token):
    """
    Only revoke one given token, not all tokens of user
    """
    user = get_user(token)
    if not user:
        return False

    redis_client.delete(token)
    remove_token_from_user(user['id'], token)
    return True
Esempio n. 3
0
def kill_ghost_connections():
    # TODO: mock scan_iter() when not using redis
    # low priority, when it's single instance without redis
    # ghost connections are rare
    for key in redis_client.scan_iter("room*"):
        data = redis_client.get(key)
        if data:
            # value might already be deleted by another
            # ghost buster thread
            room = json.loads(data)

            now = time.time()
            user_ids_to_be_removed = []
            for user in room['users']:
                connection_ids_to_be_removed = []

                for connection in user['connections']:
                    time_elapse = now - connection['heartbeat']

                    if time_elapse > HEARTBEAT_TIMOUT:
                        connection_id = connection['id']
                        logger.info(
                            f'[{key}] ghost connection {connection_id} will be removed'
                        )
                        connection_ids_to_be_removed.append(connection_id)

                user['connections'] = [
                    c for c in user['connections']
                    if c['id'] not in connection_ids_to_be_removed
                ]
                if (len(user['connections']) == 0):
                    user_id = user['id']
                    logger.info(f'ghost user {user_id} will be removed')
                    user_ids_to_be_removed.append(user_id)

            room['users'] = [
                u for u in room['users']
                if u['id'] not in user_ids_to_be_removed
            ]

            if len(room['users']) == 0:
                logger.info(f'ghost room {key} will be removed')
                redis_client.delete(key)
            else:
                if len(connection_ids_to_be_removed) > 0:
                    upsert_room(room)
Esempio n. 4
0
def clean_dead_connections(room_id, user_id, dead_connections):
    # Remove connection/user from room data
    # Remove connection from connections map
    # TODO: enforce how many connections a user can have, similar to MAX_USER_CONNECTION
    # but not per room, it's for total
    if len(dead_connections) > 0:
        print(f'[{room_id}] found dead connections: {len(dead_connections)}')

        room = get_room(room_id)
        users = room['users']
        user_in_room = [u for u in users if u['id'] == user_id]
        if len(user_in_room) > 0:
            user = user_in_room[0]
            user['connections'] = [connection_id for connection_id in user['connections']
                                   if connection_id not in dead_connections]
            if len(user['connections']) == 0:
                room['users'] = [u for u in users if u['id'] != user_id]
                # TODO: broadcast user left
            redis_client.set(room_id, json.dumps(room))

        for connection_id in dead_connections:
            # TODO: bulk delete
            redis_client.delete(connection_id)
Esempio n. 5
0
def delete_connection_from_rooms(connection, room_ids):
    user = connection.user
    connection_id = connection.id
    if user:
        user_has_left = False
        for room_id in room_ids:
            room = get_room(room_id)
            if room:
                user_in_room = [u for u in room['users']
                                if u['id'] == user['id']]
                if len(user_in_room) > 0:
                    user_in_room = user_in_room[0]
                    connection_in_room = [
                        c for c in user_in_room['connections'] if c['id'] == connection_id]
                    if len(connection_in_room) > 0:
                        connection_in_room = connection_in_room[0]
                        # remove connection from user
                        user_in_room['connections'] = [
                            c for c in user_in_room['connections'] if c['id'] != connection_id]

                        if len(user_in_room['connections']) == 0:
                            # remove user from room
                            room['users'] = [u for u in room['users']
                                             if u['id'] != user['id']]
                            if len(room['users']) == 0:
                                # delete room
                                # fix rooms are also deleted, should be fine
                                # since chat history stays
                                redis_client.delete(room_id)
                                return
                            else:
                                user_has_left = True

                        upsert_room(room)
                        if user_has_left:
                            # broadcast user left
                            broadcast_user_left(connection_id, room_id, user)
Esempio n. 6
0
def _delete_connection_from_connections(connection_id):
    data = redis_client.get(connection_id)
    if data:
        connection = json.loads(data)
        redis_client.delete(connection_id)
        return connection