Fix heath check (database + theads error)
This commit is contained in:
parent
50439b84bb
commit
b3246baf31
|
@ -114,7 +114,7 @@ class DependencyContainer:
|
||||||
checks["database"] = await db_service.health_check()
|
checks["database"] = await db_service.health_check()
|
||||||
except Exception:
|
except Exception:
|
||||||
checks["database"] = False
|
checks["database"] = False
|
||||||
return checks
|
|
||||||
try:
|
try:
|
||||||
write_queue = self.get_write_queue()
|
write_queue = self.get_write_queue()
|
||||||
checks["write_queue"] = (
|
checks["write_queue"] = (
|
||||||
|
|
|
@ -12,10 +12,6 @@ class ArticleStatus(Enum):
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ArticleDTO:
|
class ArticleDTO:
|
||||||
"""
|
|
||||||
DTO для Article без зависимостей от SQLModel.
|
|
||||||
Используется в runtime коде для передачи данных между слоями.
|
|
||||||
"""
|
|
||||||
url: str
|
url: str
|
||||||
title: str
|
title: str
|
||||||
raw_text: str
|
raw_text: str
|
||||||
|
|
|
@ -19,7 +19,6 @@ class DatabaseService:
|
||||||
|
|
||||||
self.logger.info("Создание схемы базы данных", db_path=self.config.db_path)
|
self.logger.info("Создание схемы базы данных", db_path=self.config.db_path)
|
||||||
|
|
||||||
# Создаём таблицы напрямую через DDL без SQLAlchemy
|
|
||||||
async with aiosqlite.connect(self.config.db_path) as conn:
|
async with aiosqlite.connect(self.config.db_path) as conn:
|
||||||
await conn.execute("""
|
await conn.execute("""
|
||||||
CREATE TABLE IF NOT EXISTS articles (
|
CREATE TABLE IF NOT EXISTS articles (
|
||||||
|
@ -67,18 +66,14 @@ class DatabaseService:
|
||||||
|
|
||||||
async def get_connection(self) -> aiosqlite.Connection:
|
async def get_connection(self) -> aiosqlite.Connection:
|
||||||
self.logger.info("Открытие соединения с базой данных")
|
self.logger.info("Открытие соединения с базой данных")
|
||||||
return await aiosqlite.connect(
|
return aiosqlite.connect(
|
||||||
self.config.db_path,
|
self.config.db_path,
|
||||||
timeout=30.0,
|
timeout=30.0,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def health_check(self) -> bool:
|
async def health_check(self) -> bool:
|
||||||
try:
|
try:
|
||||||
self.logger.info("Начинаем health_check...")
|
async with await self.get_connection() as connection:
|
||||||
self.logger.info("Создаём соединение напрямую...")
|
|
||||||
|
|
||||||
# Создаём соединение напрямую, не переиспользуя объект
|
|
||||||
async with aiosqlite.connect(self.config.db_path, timeout=30.0) as connection:
|
|
||||||
self.logger.info("Вошли в async context manager")
|
self.logger.info("Вошли в async context manager")
|
||||||
self.logger.info("Выполняем SELECT 1...")
|
self.logger.info("Выполняем SELECT 1...")
|
||||||
await connection.execute("SELECT 1")
|
await connection.execute("SELECT 1")
|
||||||
|
|
|
@ -70,9 +70,8 @@ class SimplifyService:
|
||||||
page_info = await self.ruwiki_adapter.fetch_page_cleaned(command.url)
|
page_info = await self.ruwiki_adapter.fetch_page_cleaned(command.url)
|
||||||
article = await self._create_or_update_article(command, page_info)
|
article = await self._create_or_update_article(command, page_info)
|
||||||
|
|
||||||
# Отмечаем статью как обрабатываемую
|
|
||||||
from src.models.article_dto import ArticleStatus
|
from src.models.article_dto import ArticleStatus
|
||||||
article.status = ArticleStatus.PENDING # В новой схеме используем PENDING для обработки
|
article.status = ArticleStatus.PENDING
|
||||||
await self.repository.update_article(article)
|
await self.repository.update_article(article)
|
||||||
|
|
||||||
simplified_text, input_tokens, output_tokens = await self._simplify_article_text(
|
simplified_text, input_tokens, output_tokens = await self._simplify_article_text(
|
||||||
|
@ -113,9 +112,9 @@ class SimplifyService:
|
||||||
title=existing_article.title,
|
title=existing_article.title,
|
||||||
raw_text=existing_article.raw_text,
|
raw_text=existing_article.raw_text,
|
||||||
simplified_text=existing_article.simplified_text,
|
simplified_text=existing_article.simplified_text,
|
||||||
token_count_raw=0, # ArticleDTO не хранит token counts
|
token_count_raw=0,
|
||||||
token_count_simplified=0, # ArticleDTO не хранит token counts
|
token_count_simplified=0,
|
||||||
processing_time_seconds=0, # ArticleDTO не хранит processing time
|
processing_time_seconds=0,
|
||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -136,7 +135,7 @@ class SimplifyService:
|
||||||
from src.models.article_dto import ArticleStatus
|
from src.models.article_dto import ArticleStatus
|
||||||
article.title = page_info.title
|
article.title = page_info.title
|
||||||
article.raw_text = page_info.content
|
article.raw_text = page_info.content
|
||||||
article.status = ArticleStatus.PENDING # Эквивалент mark_processing
|
article.status = ArticleStatus.PENDING
|
||||||
await self.repository.update_article(article)
|
await self.repository.update_article(article)
|
||||||
|
|
||||||
return article
|
return article
|
||||||
|
|
|
@ -155,7 +155,6 @@ class AsyncWriteQueue:
|
||||||
msg = "Неполные данные в успешном результате"
|
msg = "Неполные данные в успешном результате"
|
||||||
raise ValueError(msg)
|
raise ValueError(msg)
|
||||||
|
|
||||||
# Обновляем поля напрямую, так как у ArticleDTO нет методов mark_*
|
|
||||||
from src.models.article_dto import ArticleStatus
|
from src.models.article_dto import ArticleStatus
|
||||||
article.simplified_text = result.simplified_text
|
article.simplified_text = result.simplified_text
|
||||||
article.status = ArticleStatus.SIMPLIFIED
|
article.status = ArticleStatus.SIMPLIFIED
|
||||||
|
|
|
@ -121,7 +121,6 @@ class TestRuWikiAdapter:
|
||||||
adapter.extract_title_from_url("https://ru.wikipedia.org/invalid")
|
adapter.extract_title_from_url("https://ru.wikipedia.org/invalid")
|
||||||
|
|
||||||
def test_clean_wikitext(self, test_config, sample_wikitext):
|
def test_clean_wikitext(self, test_config, sample_wikitext):
|
||||||
"""Тест очистки wiki-текста."""
|
|
||||||
adapter = RuWikiAdapter(test_config)
|
adapter = RuWikiAdapter(test_config)
|
||||||
|
|
||||||
cleaned = adapter._clean_wikitext(sample_wikitext)
|
cleaned = adapter._clean_wikitext(sample_wikitext)
|
||||||
|
@ -160,7 +159,6 @@ class TestRuWikiAdapter:
|
||||||
class TestLLMProviderAdapter:
|
class TestLLMProviderAdapter:
|
||||||
|
|
||||||
def test_count_tokens(self, test_config):
|
def test_count_tokens(self, test_config):
|
||||||
"""Тест подсчёта токенов."""
|
|
||||||
adapter = LLMProviderAdapter(test_config)
|
adapter = LLMProviderAdapter(test_config)
|
||||||
|
|
||||||
count = adapter.count_tokens("Hello world")
|
count = adapter.count_tokens("Hello world")
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
"""Тесты для сервисов."""
|
|
||||||
|
|
||||||
import tempfile
|
import tempfile
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from unittest.mock import AsyncMock, MagicMock
|
from unittest.mock import AsyncMock, MagicMock
|
||||||
|
|
Loading…
Reference in New Issue