feat(app): add main application entrypoint and service coordinator
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import signal
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
|
||||
from db.database import init_db, close_db_pool
|
||||
from db.repository import Repository
|
||||
from core.metrics import start_metrics_server
|
||||
from core.llm import LLMClient
|
||||
from services.ai_processor import AIProcessor
|
||||
from services.collector import CollectorService
|
||||
from services.admin_bot import AdminBotService
|
||||
from services.publisher import PublisherService
|
||||
|
||||
# Load environment variables
|
||||
load_dotenv()
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s"
|
||||
)
|
||||
logger = logging.getLogger("copykar.main")
|
||||
|
||||
async def main():
|
||||
logger.info("Starting Copykar System...")
|
||||
|
||||
# 1. Start Prometheus metrics server
|
||||
metrics_port = int(os.getenv("METRICS_PORT", "8000"))
|
||||
start_metrics_server(metrics_port)
|
||||
|
||||
# 2. Initialize Database schema
|
||||
await init_db()
|
||||
logger.info("Database schema initialized.")
|
||||
|
||||
repo = Repository()
|
||||
llm = LLMClient()
|
||||
|
||||
# 3. Create Services
|
||||
admin_bot = AdminBotService(repo=repo)
|
||||
ai_processor = AIProcessor(repo=repo, llm=llm)
|
||||
|
||||
# Wrap AI processor to automatically push reviewed posts to admin review channel
|
||||
original_process_post = ai_processor.process_post
|
||||
async def process_and_notify(post_id: int):
|
||||
post = await original_process_post(post_id)
|
||||
if post:
|
||||
await admin_bot.send_review_post(post.id)
|
||||
return post
|
||||
ai_processor.process_post = process_and_notify
|
||||
|
||||
collector = CollectorService(repo=repo, ai_processor=ai_processor)
|
||||
publisher = PublisherService(repo=repo)
|
||||
|
||||
# 4. Start all services
|
||||
await admin_bot.start()
|
||||
await collector.start()
|
||||
await publisher.start()
|
||||
|
||||
logger.info("All Copykar services are active and running.")
|
||||
|
||||
# Graceful shutdown event
|
||||
stop_event = asyncio.Event()
|
||||
|
||||
loop = asyncio.get_running_loop()
|
||||
for sig in (signal.SIGINT, signal.SIGTERM):
|
||||
try:
|
||||
loop.add_signal_handler(sig, stop_event.set)
|
||||
except NotImplementedError:
|
||||
pass # Windows or specific platforms
|
||||
|
||||
try:
|
||||
await stop_event.wait()
|
||||
except (asyncio.CancelledError, KeyboardInterrupt):
|
||||
pass
|
||||
finally:
|
||||
logger.info("Shutting down Copykar services...")
|
||||
await collector.stop()
|
||||
await publisher.stop()
|
||||
await admin_bot.stop()
|
||||
await close_db_pool()
|
||||
logger.info("Copykar cleanly shut down.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user