mirror of
https://github.com/flibusta-apps/book_library_server.git
synced 2025-12-06 07:05:36 +01:00
Use sets for random
This commit is contained in:
@@ -4,6 +4,8 @@ from concurrent.futures import ThreadPoolExecutor
|
|||||||
from random import choice
|
from random import choice
|
||||||
from typing import Optional, Generic, TypeVar, TypedDict, Union
|
from typing import Optional, Generic, TypeVar, TypedDict, Union
|
||||||
|
|
||||||
|
from fastapi import BackgroundTasks
|
||||||
|
|
||||||
import aioredis
|
import aioredis
|
||||||
from databases import Database
|
from databases import Database
|
||||||
from fastapi_pagination.api import resolve_params
|
from fastapi_pagination.api import resolve_params
|
||||||
@@ -282,17 +284,19 @@ class GetRandomService(Generic[MODEL]):
|
|||||||
return [obj["id"] for obj in objects]
|
return [obj["id"] for obj in objects]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def _get_objects_from_cache(
|
async def _get_random_object_from_cache(
|
||||||
cls, allowed_langs: frozenset[str], redis: aioredis.Redis
|
cls, allowed_langs: frozenset[str], redis: aioredis.Redis
|
||||||
) -> Optional[list[int]]:
|
) -> Optional[int]:
|
||||||
try:
|
try:
|
||||||
key = cls.get_cache_key(allowed_langs)
|
key = cls.get_cache_key(allowed_langs)
|
||||||
data = await redis.get(key)
|
active_key = f"{key}_active"
|
||||||
|
|
||||||
if data is None:
|
if not await redis.exists(active_key):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return orjson.loads(data)
|
data: bytes = await redis.srandmember(key)
|
||||||
|
|
||||||
|
return int(data.decode())
|
||||||
except aioredis.RedisError as e:
|
except aioredis.RedisError as e:
|
||||||
print(e)
|
print(e)
|
||||||
return None
|
return None
|
||||||
@@ -303,31 +307,32 @@ class GetRandomService(Generic[MODEL]):
|
|||||||
) -> bool:
|
) -> bool:
|
||||||
try:
|
try:
|
||||||
key = cls.get_cache_key(allowed_langs)
|
key = cls.get_cache_key(allowed_langs)
|
||||||
await redis.set(key, orjson.dumps(object_ids), ex=cls.CACHE_TTL)
|
active_key = f"{key}_active"
|
||||||
|
|
||||||
|
await redis.set(active_key, 1, ex=cls.CACHE_TTL)
|
||||||
|
await redis.delete(key)
|
||||||
|
await redis.sadd(key, *object_ids)
|
||||||
return True
|
return True
|
||||||
except aioredis.RedisError as e:
|
except aioredis.RedisError as e:
|
||||||
print(e)
|
print(e)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def get_objects(
|
async def get_random_id(
|
||||||
cls, allowed_langs: frozenset[str], redis: aioredis.Redis
|
cls,
|
||||||
) -> list[int]:
|
allowed_langs: frozenset[str],
|
||||||
cached_object_ids = await cls._get_objects_from_cache(allowed_langs, redis)
|
redis: aioredis.Redis,
|
||||||
|
background_tasks: BackgroundTasks,
|
||||||
|
) -> int:
|
||||||
|
cached_object_id = await cls._get_random_object_from_cache(allowed_langs, redis)
|
||||||
|
|
||||||
if cached_object_ids is not None:
|
if cached_object_id is not None:
|
||||||
return cached_object_ids
|
return cached_object_id
|
||||||
|
|
||||||
object_ids = await cls._get_objects_from_db(allowed_langs)
|
object_ids = await cls._get_objects_from_db(allowed_langs)
|
||||||
await cls._cache_object_ids(object_ids, allowed_langs, redis)
|
|
||||||
|
|
||||||
return object_ids
|
background_tasks.add_task(cls._cache_object_ids, allowed_langs, redis)
|
||||||
|
|
||||||
@classmethod
|
|
||||||
async def get_random_id(
|
|
||||||
cls, allowed_langs: frozenset[str], redis: aioredis.Redis
|
|
||||||
) -> int:
|
|
||||||
object_ids = await cls.get_objects(allowed_langs, redis)
|
|
||||||
return choice(object_ids)
|
return choice(object_ids)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from fastapi import APIRouter, Depends, Request, HTTPException, status
|
from fastapi import APIRouter, BackgroundTasks, Depends, Request, HTTPException, status
|
||||||
|
|
||||||
from fastapi_pagination import Params
|
from fastapi_pagination import Params
|
||||||
from fastapi_pagination.ext.ormar import paginate
|
from fastapi_pagination.ext.ormar import paginate
|
||||||
@@ -55,10 +55,12 @@ async def create_author(data: CreateAuthor):
|
|||||||
|
|
||||||
@author_router.get("/random", response_model=Author)
|
@author_router.get("/random", response_model=Author)
|
||||||
async def get_random_author(
|
async def get_random_author(
|
||||||
request: Request, allowed_langs: frozenset[str] = Depends(get_allowed_langs)
|
request: Request,
|
||||||
|
background_tasks: BackgroundTasks,
|
||||||
|
allowed_langs: frozenset[str] = Depends(get_allowed_langs),
|
||||||
):
|
):
|
||||||
author_id = await GetRandomAuthorService.get_random_id(
|
author_id = await GetRandomAuthorService.get_random_id(
|
||||||
allowed_langs, request.app.state.redis
|
allowed_langs, request.app.state.redis, background_tasks
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, Request, HTTPException, status
|
from fastapi import APIRouter, BackgroundTasks, Depends, Request, HTTPException, status
|
||||||
|
|
||||||
from fastapi_pagination import Params
|
from fastapi_pagination import Params
|
||||||
|
|
||||||
@@ -57,10 +57,12 @@ async def create_book(data: Union[CreateBook, CreateRemoteBook]):
|
|||||||
|
|
||||||
@book_router.get("/random", response_model=BookDetail)
|
@book_router.get("/random", response_model=BookDetail)
|
||||||
async def get_random_book(
|
async def get_random_book(
|
||||||
request: Request, allowed_langs: frozenset[str] = Depends(get_allowed_langs)
|
request: Request,
|
||||||
|
background_tasks: BackgroundTasks,
|
||||||
|
allowed_langs: frozenset[str] = Depends(get_allowed_langs),
|
||||||
):
|
):
|
||||||
book_id = await GetRandomBookService.get_random_id(
|
book_id = await GetRandomBookService.get_random_id(
|
||||||
allowed_langs, request.app.state.redis
|
allowed_langs, request.app.state.redis, background_tasks
|
||||||
)
|
)
|
||||||
|
|
||||||
book = (
|
book = (
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from fastapi import APIRouter, Depends, Request
|
from fastapi import APIRouter, BackgroundTasks, Depends, Request
|
||||||
|
|
||||||
from fastapi_pagination import Params
|
from fastapi_pagination import Params
|
||||||
from fastapi_pagination.ext.ormar import paginate
|
from fastapi_pagination.ext.ormar import paginate
|
||||||
@@ -29,10 +29,13 @@ async def get_sequences():
|
|||||||
@sequence_router.get("/random", response_model=Sequence)
|
@sequence_router.get("/random", response_model=Sequence)
|
||||||
async def get_random_sequence(
|
async def get_random_sequence(
|
||||||
request: Request,
|
request: Request,
|
||||||
|
background_tasks: BackgroundTasks,
|
||||||
allowed_langs: frozenset[str] = Depends(get_allowed_langs),
|
allowed_langs: frozenset[str] = Depends(get_allowed_langs),
|
||||||
):
|
):
|
||||||
sequence_id = await GetRandomSequenceService.get_random_id(
|
sequence_id = await GetRandomSequenceService.get_random_id(
|
||||||
allowed_langs, request.app.state.redis
|
allowed_langs,
|
||||||
|
request.app.state.redis,
|
||||||
|
background_tasks,
|
||||||
)
|
)
|
||||||
|
|
||||||
return await SequenceDB.objects.get(id=sequence_id)
|
return await SequenceDB.objects.get(id=sequence_id)
|
||||||
|
|||||||
Reference in New Issue
Block a user