This commit is contained in:
parent
208de158bc
commit
c5ee827230
8
cache/cache.py
vendored
8
cache/cache.py
vendored
|
@ -1,13 +1,15 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
import json
|
import json
|
||||||
from typing import List
|
from typing import List
|
||||||
from sqlalchemy import select, join, and_
|
|
||||||
|
from sqlalchemy import and_, join, select
|
||||||
|
|
||||||
from orm.author import Author, AuthorFollower
|
from orm.author import Author, AuthorFollower
|
||||||
from orm.topic import Topic, TopicFollower
|
|
||||||
from orm.shout import Shout, ShoutAuthor, ShoutTopic
|
from orm.shout import Shout, ShoutAuthor, ShoutTopic
|
||||||
|
from orm.topic import Topic, TopicFollower
|
||||||
from services.db import local_session
|
from services.db import local_session
|
||||||
from utils.encoders import CustomJSONEncoder
|
|
||||||
from services.redis import redis
|
from services.redis import redis
|
||||||
|
from utils.encoders import CustomJSONEncoder
|
||||||
from utils.logger import root_logger as logger
|
from utils.logger import root_logger as logger
|
||||||
|
|
||||||
DEFAULT_FOLLOWS = {
|
DEFAULT_FOLLOWS = {
|
||||||
|
|
10
cache/precache.py
vendored
10
cache/precache.py
vendored
|
@ -1,15 +1,17 @@
|
||||||
import json
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import json
|
||||||
|
|
||||||
from sqlalchemy import and_, join, select
|
from sqlalchemy import and_, join, select
|
||||||
|
|
||||||
|
from cache.cache import cache_author, cache_topic
|
||||||
from orm.author import Author, AuthorFollower
|
from orm.author import Author, AuthorFollower
|
||||||
from orm.shout import Shout, ShoutAuthor, ShoutTopic, ShoutReactionsFollower
|
from orm.shout import Shout, ShoutAuthor, ShoutReactionsFollower, ShoutTopic
|
||||||
from orm.topic import Topic, TopicFollower
|
from orm.topic import Topic, TopicFollower
|
||||||
from resolvers.stat import get_with_stat
|
from resolvers.stat import get_with_stat
|
||||||
from cache.cache import cache_author, cache_topic
|
|
||||||
from services.db import local_session
|
from services.db import local_session
|
||||||
|
from services.redis import redis
|
||||||
from utils.encoders import CustomJSONEncoder
|
from utils.encoders import CustomJSONEncoder
|
||||||
from utils.logger import root_logger as logger
|
from utils.logger import root_logger as logger
|
||||||
from services.redis import redis
|
|
||||||
|
|
||||||
|
|
||||||
# Предварительное кеширование подписчиков автора
|
# Предварительное кеширование подписчиков автора
|
||||||
|
|
3
main.py
3
main.py
|
@ -13,7 +13,6 @@ from services.exception import ExceptionHandlerMiddleware
|
||||||
from services.redis import redis
|
from services.redis import redis
|
||||||
from services.schema import resolvers
|
from services.schema import resolvers
|
||||||
from services.search import search_service
|
from services.search import search_service
|
||||||
from services.sentry import start_sentry
|
|
||||||
from services.viewed import ViewedStorage
|
from services.viewed import ViewedStorage
|
||||||
from services.webhook import WebhookEndpoint
|
from services.webhook import WebhookEndpoint
|
||||||
from settings import DEV_SERVER_PID_FILE_NAME, MODE
|
from settings import DEV_SERVER_PID_FILE_NAME, MODE
|
||||||
|
@ -42,7 +41,7 @@ app = Starlette(
|
||||||
precache_data,
|
precache_data,
|
||||||
ViewedStorage.init,
|
ViewedStorage.init,
|
||||||
search_service.info,
|
search_service.info,
|
||||||
start_sentry,
|
# start_sentry,
|
||||||
start,
|
start,
|
||||||
revalidation_manager.start,
|
revalidation_manager.start,
|
||||||
],
|
],
|
||||||
|
|
|
@ -3,11 +3,6 @@ import time
|
||||||
|
|
||||||
from sqlalchemy import desc, select, text
|
from sqlalchemy import desc, select, text
|
||||||
|
|
||||||
from orm.author import Author
|
|
||||||
from orm.shout import ShoutAuthor, ShoutTopic
|
|
||||||
from orm.topic import Topic
|
|
||||||
from resolvers.stat import get_with_stat
|
|
||||||
from services.auth import login_required
|
|
||||||
from cache.cache import (
|
from cache.cache import (
|
||||||
cache_author,
|
cache_author,
|
||||||
get_cached_author,
|
get_cached_author,
|
||||||
|
@ -16,9 +11,14 @@ from cache.cache import (
|
||||||
get_cached_follower_authors,
|
get_cached_follower_authors,
|
||||||
get_cached_follower_topics,
|
get_cached_follower_topics,
|
||||||
)
|
)
|
||||||
|
from orm.author import Author
|
||||||
|
from orm.shout import ShoutAuthor, ShoutTopic
|
||||||
|
from orm.topic import Topic
|
||||||
|
from resolvers.stat import get_with_stat
|
||||||
|
from services.auth import login_required
|
||||||
from services.db import local_session
|
from services.db import local_session
|
||||||
from utils.logger import root_logger as logger
|
|
||||||
from services.schema import mutation, query
|
from services.schema import mutation, query
|
||||||
|
from utils.logger import root_logger as logger
|
||||||
|
|
||||||
|
|
||||||
@mutation.field("update_author")
|
@mutation.field("update_author")
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import time
|
import time
|
||||||
from sqlalchemy import and_, case, desc, func, select, asc
|
|
||||||
|
from sqlalchemy import and_, asc, case, desc, func, select
|
||||||
from sqlalchemy.orm import aliased
|
from sqlalchemy.orm import aliased
|
||||||
|
|
||||||
from orm.author import Author
|
from orm.author import Author
|
||||||
|
@ -11,9 +12,9 @@ from resolvers.follower import follow
|
||||||
from resolvers.stat import update_author_stat
|
from resolvers.stat import update_author_stat
|
||||||
from services.auth import add_user_role, login_required
|
from services.auth import add_user_role, login_required
|
||||||
from services.db import local_session
|
from services.db import local_session
|
||||||
from utils.logger import root_logger as logger
|
|
||||||
from services.notify import notify_reaction
|
from services.notify import notify_reaction
|
||||||
from services.schema import mutation, query
|
from services.schema import mutation, query
|
||||||
|
from utils.logger import root_logger as logger
|
||||||
|
|
||||||
|
|
||||||
def query_reactions():
|
def query_reactions():
|
||||||
|
|
|
@ -280,35 +280,39 @@ async def get_shout(_, info, slug: str):
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
with local_session() as session:
|
with local_session() as session:
|
||||||
q, aliased_reaction = query_shouts(slug)
|
# Отключение автосохранения
|
||||||
results = session.execute(q).first()
|
with session.no_autoflush:
|
||||||
if results:
|
q, aliased_reaction = query_shouts(slug)
|
||||||
[
|
results = session.execute(q).first()
|
||||||
shout,
|
if results:
|
||||||
commented_stat,
|
[
|
||||||
followers_stat,
|
shout,
|
||||||
rating_stat,
|
commented_stat,
|
||||||
last_reaction_at,
|
followers_stat,
|
||||||
authors,
|
rating_stat,
|
||||||
topics,
|
last_reaction_at,
|
||||||
main_topic_slug,
|
authors,
|
||||||
] = results
|
topics,
|
||||||
|
main_topic_slug,
|
||||||
|
] = results
|
||||||
|
|
||||||
shout.stat = {
|
shout.stat = {
|
||||||
"viewed": ViewedStorage.get_shout(shout.id),
|
"viewed": ViewedStorage.get_shout(shout.id),
|
||||||
"commented": commented_stat,
|
"commented": commented_stat,
|
||||||
"rating": rating_stat,
|
"rating": rating_stat,
|
||||||
"last_reacted_at": last_reaction_at,
|
"last_reacted_at": last_reaction_at,
|
||||||
}
|
}
|
||||||
# Используем класс модели Author для преобразования строк в объекты
|
|
||||||
shout.authors = parse_aggregated_string(authors, Author)
|
|
||||||
# Используем класс модели Topic для преобразования строк в объекты
|
|
||||||
shout.topics = parse_aggregated_string(topics, Topic)
|
|
||||||
|
|
||||||
# Добавляем основной топик, если он существует
|
# Преобразование строк в объекты Author без их создания
|
||||||
shout.main_topic = main_topic_slug
|
shout.authors = parse_aggregated_string(authors, Author)
|
||||||
|
|
||||||
return shout
|
# Преобразование строк в объекты Topic без их создания
|
||||||
|
shout.topics = parse_aggregated_string(topics, Topic)
|
||||||
|
|
||||||
|
# Добавляем основной топик, если он существует
|
||||||
|
shout.main_topic = main_topic_slug
|
||||||
|
|
||||||
|
return shout
|
||||||
except Exception as _exc:
|
except Exception as _exc:
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,11 @@ import asyncio
|
||||||
from sqlalchemy import and_, distinct, func, join, select
|
from sqlalchemy import and_, distinct, func, join, select
|
||||||
from sqlalchemy.orm import aliased
|
from sqlalchemy.orm import aliased
|
||||||
|
|
||||||
|
from cache.cache import cache_author
|
||||||
from orm.author import Author, AuthorFollower
|
from orm.author import Author, AuthorFollower
|
||||||
from orm.reaction import Reaction, ReactionKind
|
from orm.reaction import Reaction, ReactionKind
|
||||||
from orm.shout import Shout, ShoutAuthor, ShoutTopic
|
from orm.shout import Shout, ShoutAuthor, ShoutTopic
|
||||||
from orm.topic import Topic, TopicFollower
|
from orm.topic import Topic, TopicFollower
|
||||||
from cache.cache import cache_author
|
|
||||||
from services.db import local_session
|
from services.db import local_session
|
||||||
from utils.logger import root_logger as logger
|
from utils.logger import root_logger as logger
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,19 @@
|
||||||
from sqlalchemy import distinct, func, select
|
from sqlalchemy import distinct, func, select
|
||||||
|
|
||||||
|
from cache.cache import (
|
||||||
|
get_cached_topic_authors,
|
||||||
|
get_cached_topic_by_slug,
|
||||||
|
get_cached_topic_followers,
|
||||||
|
)
|
||||||
|
from cache.memorycache import cache_region
|
||||||
from orm.author import Author
|
from orm.author import Author
|
||||||
from orm.shout import ShoutTopic
|
from orm.shout import ShoutTopic
|
||||||
from orm.topic import Topic
|
from orm.topic import Topic
|
||||||
from resolvers.stat import get_with_stat
|
from resolvers.stat import get_with_stat
|
||||||
from services.auth import login_required
|
from services.auth import login_required
|
||||||
from cache.cache import get_cached_topic_authors, get_cached_topic_by_slug, get_cached_topic_followers
|
|
||||||
from services.db import local_session
|
from services.db import local_session
|
||||||
from utils.logger import root_logger as logger
|
|
||||||
from cache.memorycache import cache_region
|
|
||||||
from services.schema import mutation, query
|
from services.schema import mutation, query
|
||||||
|
from utils.logger import root_logger as logger
|
||||||
|
|
||||||
|
|
||||||
# Запрос на получение всех тем
|
# Запрос на получение всех тем
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from granian.constants import Interfaces
|
from granian.constants import Interfaces
|
||||||
|
from granian.log import LogLevels
|
||||||
from granian.server import Granian
|
from granian.server import Granian
|
||||||
|
|
||||||
from settings import PORT
|
from settings import PORT
|
||||||
|
@ -21,8 +22,9 @@ if __name__ == "__main__":
|
||||||
"main:app",
|
"main:app",
|
||||||
address="0.0.0.0", # noqa S104
|
address="0.0.0.0", # noqa S104
|
||||||
port=PORT,
|
port=PORT,
|
||||||
|
interface=Interfaces.ASGI,
|
||||||
threads=4,
|
threads=4,
|
||||||
websockets=False,
|
websockets=False,
|
||||||
interface=Interfaces.ASGI,
|
log_level=LogLevels.debug,
|
||||||
)
|
)
|
||||||
granian_instance.serve()
|
granian_instance.serve()
|
||||||
|
|
|
@ -1,19 +1,15 @@
|
||||||
import json
|
import json
|
||||||
import math
|
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
import warnings
|
import warnings
|
||||||
|
import math
|
||||||
from typing import Any, Callable, Dict, TypeVar
|
from typing import Any, Callable, Dict, TypeVar
|
||||||
|
|
||||||
from sqlalchemy import JSON, Column, Engine, Integer, create_engine, event, exc, inspect
|
from sqlalchemy import JSON, Column, Engine, Integer, create_engine, event, exc, inspect
|
||||||
from sqlalchemy.ext.declarative import declarative_base
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
from sqlalchemy.orm import Session, configure_mappers
|
from sqlalchemy.orm import Session, configure_mappers
|
||||||
from sqlalchemy.sql.schema import Table
|
from sqlalchemy.sql.schema import Table
|
||||||
|
|
||||||
from settings import DB_URL
|
|
||||||
from utils.logger import root_logger as logger
|
from utils.logger import root_logger as logger
|
||||||
|
from settings import DB_URL
|
||||||
# from sqlalchemy_searchable import make_searchable
|
|
||||||
|
|
||||||
|
|
||||||
# Подключение к базе данных SQLAlchemy
|
# Подключение к базе данных SQLAlchemy
|
||||||
|
@ -96,23 +92,44 @@ warnings.showwarning = warning_with_traceback
|
||||||
warnings.simplefilter("always", exc.SAWarning)
|
warnings.simplefilter("always", exc.SAWarning)
|
||||||
|
|
||||||
|
|
||||||
@event.listens_for(Engine, "before_cursor_execute")
|
# Функция для извлечения SQL-запроса из контекста
|
||||||
def before_cursor_execute(conn, cursor, statement, parameters, context, executemany):
|
def get_statement_from_context(context):
|
||||||
conn.query_start_time = time.time()
|
query = None
|
||||||
conn.last_statement = None
|
|
||||||
|
|
||||||
|
|
||||||
@event.listens_for(Engine, "after_cursor_execute")
|
|
||||||
def after_cursor_execute(conn, cursor, statement, parameters, context, executemany):
|
|
||||||
compiled_statement = context.compiled.string
|
compiled_statement = context.compiled.string
|
||||||
compiled_parameters = context.compiled.params
|
compiled_parameters = context.compiled.params
|
||||||
if compiled_statement:
|
if compiled_statement:
|
||||||
elapsed = time.time() - conn.query_start_time
|
if compiled_parameters:
|
||||||
if compiled_parameters is not None:
|
try:
|
||||||
query = compiled_statement.format(*compiled_parameters)
|
# Безопасное форматирование параметров
|
||||||
|
query = compiled_statement % compiled_parameters
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error formatting query: {e}")
|
||||||
else:
|
else:
|
||||||
query = compiled_statement # or handle this case in a way that makes sense for your application
|
query = compiled_statement
|
||||||
|
if query:
|
||||||
|
query = query.replace("\n", " ").replace(" ", " ").strip()
|
||||||
|
return query
|
||||||
|
|
||||||
if elapsed > 1 and conn.last_statement != query:
|
|
||||||
conn.last_statement = query
|
# Обработчик события перед выполнением запроса
|
||||||
logger.debug(f"\n{query}\n{'*' * math.floor(elapsed)} {elapsed:.3f} s\n")
|
@event.listens_for(Engine, "before_cursor_execute")
|
||||||
|
def before_cursor_execute(conn, cursor, statement, parameters, context, executemany):
|
||||||
|
conn.query_start_time = time.time()
|
||||||
|
conn.cursor_id = id(cursor) # Отслеживание конкретного курсора
|
||||||
|
|
||||||
|
|
||||||
|
# Обработчик события после выполнения запроса
|
||||||
|
@event.listens_for(Engine, "after_cursor_execute")
|
||||||
|
def after_cursor_execute(conn, cursor, statement, parameters, context, executemany):
|
||||||
|
if hasattr(conn, "cursor_id") and conn.cursor_id == id(cursor):
|
||||||
|
query = get_statement_from_context(context)
|
||||||
|
if query:
|
||||||
|
elapsed = time.time() - conn.query_start_time
|
||||||
|
if elapsed > 1:
|
||||||
|
query_end = query[-16:]
|
||||||
|
query = query.split(query_end)[0] + query_end
|
||||||
|
logger.debug(query)
|
||||||
|
elapsed_n = math.floor(elapsed)
|
||||||
|
logger.debug('*' * elapsed_n)
|
||||||
|
logger.debug(f"{elapsed_n:.3f} s")
|
||||||
|
del conn.cursor_id # Удаление идентификатора курсора после выполнения
|
||||||
|
|
|
@ -63,8 +63,9 @@ stream.setFormatter(formatter)
|
||||||
|
|
||||||
# Set up the root logger with the same formatting
|
# Set up the root logger with the same formatting
|
||||||
root_logger = logging.getLogger()
|
root_logger = logging.getLogger()
|
||||||
root_logger.setLevel(logging.DEBUG)
|
if not root_logger.hasHandlers():
|
||||||
root_logger.addHandler(stream)
|
root_logger.setLevel(logging.DEBUG)
|
||||||
|
root_logger.addHandler(stream)
|
||||||
|
|
||||||
ignore_logs = ["_trace", "httpx", "_client", "_trace.atrace", "aiohttp", "_client", "base"]
|
ignore_logs = ["_trace", "httpx", "_client", "_trace.atrace", "aiohttp", "_client", "base"]
|
||||||
for lgr in ignore_logs:
|
for lgr in ignore_logs:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user