refac
This commit is contained in:
1 parent
3132f11e55
commit
021c4c7a2e
1 file changed
+38
-41
@@ -5,7 +5,6 @@ import logging
|
|||||||
import random
|
import random
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
from typing import Dict
|
|
||||||
|
|
||||||
import pycrdt as Y
|
import pycrdt as Y
|
||||||
import socketio
|
import socketio
|
||||||
@@ -16,7 +15,6 @@ from open_webui.env import (
|
|||||||
ENABLE_WEBSOCKET_SUPPORT,
|
ENABLE_WEBSOCKET_SUPPORT,
|
||||||
GLOBAL_LOG_LEVEL,
|
GLOBAL_LOG_LEVEL,
|
||||||
REDIS_KEY_PREFIX,
|
REDIS_KEY_PREFIX,
|
||||||
VERSION,
|
|
||||||
WEBSOCKET_EVENT_CALLER_TIMEOUT,
|
WEBSOCKET_EVENT_CALLER_TIMEOUT,
|
||||||
WEBSOCKET_MANAGER,
|
WEBSOCKET_MANAGER,
|
||||||
WEBSOCKET_REDIS_CLUSTER,
|
WEBSOCKET_REDIS_CLUSTER,
|
||||||
@@ -44,7 +42,6 @@ from open_webui.utils.redis import (
|
|||||||
get_redis_connection,
|
get_redis_connection,
|
||||||
get_sentinels_from_env,
|
get_sentinels_from_env,
|
||||||
)
|
)
|
||||||
from redis import asyncio as aioredis
|
|
||||||
|
|
||||||
logging.basicConfig(stream=sys.stdout, level=GLOBAL_LOG_LEVEL)
|
logging.basicConfig(stream=sys.stdout, level=GLOBAL_LOG_LEVEL)
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@@ -58,6 +55,11 @@ REDIS = None
|
|||||||
SOCKETIO_CORS_ORIGINS = '*' if CORS_ALLOW_ORIGIN == ['*'] else CORS_ALLOW_ORIGIN
|
SOCKETIO_CORS_ORIGINS = '*' if CORS_ALLOW_ORIGIN == ['*'] else CORS_ALLOW_ORIGIN
|
||||||
|
|
||||||
|
|
||||||
|
def get_room_sid_map(manager, namespace: str, room: str):
|
||||||
|
"""Return this process's Socket.IO sid map for a room, without copying it."""
|
||||||
|
return manager.rooms.get(namespace, {}).get(room)
|
||||||
|
|
||||||
|
|
||||||
class LocalFilteredRedisManager(socketio.AsyncRedisManager):
|
class LocalFilteredRedisManager(socketio.AsyncRedisManager):
|
||||||
"""AsyncRedisManager that drops pub/sub emits with no local recipients.
|
"""AsyncRedisManager that drops pub/sub emits with no local recipients.
|
||||||
|
|
||||||
@@ -76,7 +78,7 @@ class LocalFilteredRedisManager(socketio.AsyncRedisManager):
|
|||||||
room = message.get('room')
|
room = message.get('room')
|
||||||
if isinstance(room, str):
|
if isinstance(room, str):
|
||||||
namespace = message.get('namespace') or '/'
|
namespace = message.get('namespace') or '/'
|
||||||
if next(self.get_participants(namespace, room), None) is None:
|
if not get_room_sid_map(self, namespace, room):
|
||||||
return
|
return
|
||||||
await super()._handle_emit(message)
|
await super()._handle_emit(message)
|
||||||
|
|
||||||
@@ -229,17 +231,19 @@ async def periodic_usage_pool_cleanup():
|
|||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
if not renew_func():
|
if not renew_func():
|
||||||
log.error(f'Unable to renew cleanup lock. Exiting usage pool cleanup.')
|
log.error('Unable to renew cleanup lock. Exiting usage pool cleanup.')
|
||||||
raise Exception('Unable to renew usage pool cleanup lock.')
|
raise Exception('Unable to renew usage pool cleanup lock.')
|
||||||
|
|
||||||
now = int(time.time())
|
now = int(time.time())
|
||||||
send_usage = False
|
|
||||||
for model_id, connections in list(USAGE_POOL.items()):
|
for model_id, connections in list(USAGE_POOL.items()):
|
||||||
# Creating a list of sids to remove if they have timed out
|
# Creating a list of sids to remove if they have timed out
|
||||||
expired_sids = [
|
expired_sids = [
|
||||||
sid for sid, details in connections.items() if now - details['updated_at'] > TIMEOUT_DURATION
|
sid for sid, details in connections.items() if now - details['updated_at'] > TIMEOUT_DURATION
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if connections and not expired_sids:
|
||||||
|
continue
|
||||||
|
|
||||||
for sid in expired_sids:
|
for sid in expired_sids:
|
||||||
del connections[sid]
|
del connections[sid]
|
||||||
|
|
||||||
@@ -248,8 +252,6 @@ async def periodic_usage_pool_cleanup():
|
|||||||
del USAGE_POOL[model_id]
|
del USAGE_POOL[model_id]
|
||||||
else:
|
else:
|
||||||
USAGE_POOL[model_id] = connections
|
USAGE_POOL[model_id] = connections
|
||||||
|
|
||||||
send_usage = True
|
|
||||||
await asyncio.sleep(TIMEOUT_DURATION)
|
await asyncio.sleep(TIMEOUT_DURATION)
|
||||||
finally:
|
finally:
|
||||||
release_func()
|
release_func()
|
||||||
@@ -276,11 +278,8 @@ def get_user_id_from_session_pool(sid):
|
|||||||
|
|
||||||
def get_session_ids_from_room(room):
|
def get_session_ids_from_room(room):
|
||||||
"""Get all session IDs from a specific room."""
|
"""Get all session IDs from a specific room."""
|
||||||
active_session_ids = sio.manager.get_participants(
|
members = get_room_sid_map(sio.manager, '/', room)
|
||||||
namespace='/',
|
return list(members) if members else []
|
||||||
room=room,
|
|
||||||
)
|
|
||||||
return [session_id[0] for session_id in active_session_ids]
|
|
||||||
|
|
||||||
|
|
||||||
def get_user_ids_from_room(room):
|
def get_user_ids_from_room(room):
|
||||||
@@ -404,33 +403,38 @@ async def user_join(sid, data):
|
|||||||
if token_data is None or 'id' not in token_data or not await is_valid_token(token_data, redis):
|
if token_data is None or 'id' not in token_data or not await is_valid_token(token_data, redis):
|
||||||
return
|
return
|
||||||
|
|
||||||
user = await Users.get_user_by_id(token_data['id'])
|
existing = SESSION_POOL.get(sid)
|
||||||
if not user:
|
if existing and existing.get('id') == token_data['id']:
|
||||||
return
|
SESSION_POOL[sid] = {**existing, 'last_seen_at': int(time.time())}
|
||||||
|
user_id, user_name, user_role = existing['id'], existing['name'], existing['role']
|
||||||
|
else:
|
||||||
|
user = await Users.get_user_by_id(token_data['id'])
|
||||||
|
if not user:
|
||||||
|
return
|
||||||
|
|
||||||
SESSION_POOL[sid] = {
|
SESSION_POOL[sid] = {
|
||||||
**user.model_dump(
|
**user.model_dump(
|
||||||
exclude=[
|
exclude=[
|
||||||
'profile_image_url',
|
'profile_image_url',
|
||||||
'profile_banner_image_url',
|
'profile_banner_image_url',
|
||||||
'date_of_birth',
|
'date_of_birth',
|
||||||
'bio',
|
'bio',
|
||||||
'gender',
|
'gender',
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
'last_seen_at': int(time.time()),
|
'last_seen_at': int(time.time()),
|
||||||
}
|
}
|
||||||
|
await sio.enter_room(sid, f'user:{user.id}')
|
||||||
await sio.enter_room(sid, f'user:{user.id}')
|
user_id, user_name, user_role = user.id, user.name, user.role
|
||||||
|
|
||||||
# Join all the channels only if user has channels permission
|
# Join all the channels only if user has channels permission
|
||||||
if user.role == 'admin' or await has_permission(user.id, 'features.channels'):
|
if user_role == 'admin' or await has_permission(user_id, 'features.channels'):
|
||||||
channels = await Channels.get_channels_by_user_id(user.id)
|
channels = await Channels.get_channels_by_user_id(user_id)
|
||||||
log.debug(f'{channels=}')
|
log.debug(f'{channels=}')
|
||||||
for channel in channels:
|
for channel in channels:
|
||||||
await sio.enter_room(sid, f'channel:{channel.id}')
|
await sio.enter_room(sid, f'channel:{channel.id}')
|
||||||
|
|
||||||
return {'id': user.id, 'name': user.name}
|
return {'id': user_id, 'name': user_name}
|
||||||
|
|
||||||
|
|
||||||
@sio.on('heartbeat')
|
@sio.on('heartbeat')
|
||||||
@@ -510,13 +514,7 @@ async def join_note(sid, data):
|
|||||||
@sio.on('events:channel')
|
@sio.on('events:channel')
|
||||||
async def channel_events(sid, data):
|
async def channel_events(sid, data):
|
||||||
room = f'channel:{data["channel_id"]}'
|
room = f'channel:{data["channel_id"]}'
|
||||||
participants = sio.manager.get_participants(
|
if sid not in (get_room_sid_map(sio.manager, '/', room) or {}):
|
||||||
namespace='/',
|
|
||||||
room=room,
|
|
||||||
)
|
|
||||||
|
|
||||||
sids = [sid for sid, _ in participants]
|
|
||||||
if sid not in sids:
|
|
||||||
return
|
return
|
||||||
|
|
||||||
event_data = data['data']
|
event_data = data['data']
|
||||||
@@ -859,7 +857,6 @@ async def yjs_awareness_update(sid, data):
|
|||||||
@sio.event
|
@sio.event
|
||||||
async def disconnect(sid, reason=None):
|
async def disconnect(sid, reason=None):
|
||||||
if sid in SESSION_POOL:
|
if sid in SESSION_POOL:
|
||||||
user = SESSION_POOL[sid]
|
|
||||||
del SESSION_POOL[sid]
|
del SESSION_POOL[sid]
|
||||||
|
|
||||||
# Clean up USAGE_POOL entries for this session
|
# Clean up USAGE_POOL entries for this session
|
||||||
|
|||||||
Reference in new issue
Block a user