Service Runner Finder and complete task chain completed
This commit is contained in:
@@ -1,74 +1,108 @@
|
||||
import uvloop
|
||||
import asyncio
|
||||
import sys
|
||||
import signal
|
||||
import time
|
||||
import arrow
|
||||
|
||||
from pydantic import BaseModel
|
||||
from datetime import datetime
|
||||
from Depends.prisma_client import prisma_client, disconnect_prisma
|
||||
|
||||
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
|
||||
from Depends.prisma_client import PrismaService
|
||||
from Depends.service_handler import IbanFinderService
|
||||
from Depends.config import ConfigServices, Status, FinderIban, RedisTaskObject
|
||||
|
||||
|
||||
# sys.stdout.reconfigure(line_buffering=True) # alternatif: python -u veya PYTHONUNBUFFERED=1
|
||||
class IbanRecord(BaseModel):
|
||||
id: int
|
||||
uu_id: str
|
||||
iban: str
|
||||
build_id: int
|
||||
build_uu_id: str
|
||||
expiry_starts: datetime
|
||||
expiry_ends: datetime
|
||||
|
||||
|
||||
async def tick():
|
||||
start = time.time()
|
||||
print(f"[{datetime.now()}] Attempting database query...")
|
||||
async with prisma_client() as db:
|
||||
rows = await db.account_records.find_many(
|
||||
take=5, skip=0, order=[{"bank_date": "desc"}]
|
||||
)
|
||||
print(f"[{datetime.now()}] Query completed in {time.time()-start:.2f}s")
|
||||
|
||||
for i, r in enumerate(rows):
|
||||
# Dilersen burada formatı değiştir
|
||||
print(f" Row: {i} | id={r.id} bank_date={r.bank_date} currency_value={r.currency_value}")
|
||||
print("-" * 80)
|
||||
class DecisionBookRecord(BaseModel):
|
||||
id: int
|
||||
uu_id: str
|
||||
build_id: int
|
||||
build_uu_id: str
|
||||
expiry_starts: datetime
|
||||
expiry_ends: datetime
|
||||
|
||||
|
||||
async def service():
|
||||
print(f"[{datetime.now()}] IBAN Finder service starting")
|
||||
try:
|
||||
iteration = 0
|
||||
while True:
|
||||
iteration += 1
|
||||
print(f"\n[{datetime.now()}] Loop iteration {iteration}")
|
||||
try:
|
||||
await tick()
|
||||
except Exception as e:
|
||||
print(f"[{datetime.now()}] Error in service tick: {e}")
|
||||
await asyncio.sleep(1) # bloklamayan bekleme
|
||||
finally:
|
||||
# Her durumda DB'yi temiz kapat
|
||||
await disconnect_prisma()
|
||||
print(f"[{datetime.now()}] Cleaning up database connection...")
|
||||
def check_task_belong_to_this_service(task: RedisTaskObject):
|
||||
if not task.service == ConfigServices.SERVICE_PREFIX_MAIL_PARSER:
|
||||
return False
|
||||
if not task.completed:
|
||||
return False
|
||||
if not task.data:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
async def _graceful_shutdown(sig: signal.Signals):
|
||||
print(f"\n[{datetime.now()}] Shutting down due to signal: {sig.name}")
|
||||
# Burada istersen tüm pending task'leri iptal edebilirsin:
|
||||
# for t in asyncio.all_tasks():
|
||||
# if t is not asyncio.current_task():
|
||||
# t.cancel()
|
||||
await disconnect_prisma()
|
||||
def extract_build_iban_from_task(task: RedisTaskObject, finder_iban: FinderIban, write_object: dict) -> tuple[bool, dict]:
|
||||
bank_date = arrow.get(finder_iban.bank_date).datetime
|
||||
iban_record_db = prisma_service.find_first(
|
||||
table="build_ibans",
|
||||
query={
|
||||
"active": True, "deleted": False, "is_confirmed": True, "iban": finder_iban.iban,
|
||||
"expiry_starts": {"lte": bank_date}, "expiry_ends": {"gte": bank_date},
|
||||
},
|
||||
select={"id": None, "uu_id": None, "iban": None, "build_id": None, "build_uu_id": None, "expiry_starts": None, "expiry_ends": None}
|
||||
)
|
||||
if iban_record_db:
|
||||
iban_record = IbanRecord(**iban_record_db)
|
||||
write_object["build_id"] = iban_record.build_id
|
||||
write_object["build_uu_id"] = iban_record.build_uu_id
|
||||
return True, write_object
|
||||
return False, write_object
|
||||
|
||||
|
||||
def _install_signal_handlers(loop: asyncio.AbstractEventLoop):
|
||||
# Linux/Unix: SIGINT (Ctrl+C) ve SIGTERM (docker stop) için kibar kapanış
|
||||
for s in (signal.SIGINT, signal.SIGTERM):
|
||||
loop.add_signal_handler(s, lambda s=s: asyncio.create_task(_graceful_shutdown(s)))
|
||||
def extract_decision_book_from_task(write_object: dict) -> tuple[bool, dict]:
|
||||
bank_date = arrow.get(write_object["bank_date"]).datetime
|
||||
decision_book_record_db = prisma_service.find_first(
|
||||
table="build_decision_book",
|
||||
query={
|
||||
"active": True, "deleted": False, "is_confirmed": True, "build_id": write_object["build_id"],
|
||||
"expiry_starts": {"lte": bank_date}, "expiry_ends": {"gte": bank_date},
|
||||
},
|
||||
select={"id": None, "uu_id": None, "build_id": None, "build_uu_id": None, "expiry_starts": None, "expiry_ends": None}
|
||||
)
|
||||
if decision_book_record_db:
|
||||
decision_book_record = DecisionBookRecord(**decision_book_record_db)
|
||||
write_object["build_decision_book_id"] = decision_book_record.id
|
||||
write_object["build_decision_book_uu_id"] = decision_book_record.uu_id
|
||||
return True, write_object
|
||||
return False, write_object
|
||||
|
||||
|
||||
async def main():
|
||||
loop = asyncio.get_running_loop()
|
||||
try:
|
||||
_install_signal_handlers(loop)
|
||||
except NotImplementedError:
|
||||
# (Gerekirse Windows vs., ama sen Linux/Docker kullanıyorsun)
|
||||
pass
|
||||
await service()
|
||||
|
||||
if __name__ == "__main__":
|
||||
# uvloop policy zaten yukarıda set edildi; burada normal asyncio.run kullanıyoruz
|
||||
asyncio.run(main())
|
||||
|
||||
prisma_service = PrismaService()
|
||||
iban_finder_service = IbanFinderService()
|
||||
print("Find Build Iban service started")
|
||||
try:
|
||||
print("Find Build Iban service started sleeping for 5 seconds")
|
||||
while True:
|
||||
time.sleep(5)
|
||||
tasks = iban_finder_service.fetch_all_tasks()
|
||||
for task in tasks:
|
||||
if not check_task_belong_to_this_service(task):
|
||||
continue
|
||||
if list(task.data.FinderIban):
|
||||
finder_iban_list = []
|
||||
for finder_iban in list(task.data.FinderIban):
|
||||
write_object = finder_iban.dict()
|
||||
is_build_found, is_decision_book_found = False, False
|
||||
is_build_found, write_object = extract_build_iban_from_task(task, finder_iban, write_object)
|
||||
if is_build_found:
|
||||
is_decision_book_found, write_object = extract_decision_book_from_task(write_object)
|
||||
if is_build_found or is_decision_book_found:
|
||||
finder_iban_list.append(write_object)
|
||||
if finder_iban_list:
|
||||
iban_finder_service.update_service_data(task.task, ConfigServices.SERVICE_PREFIX_FINDER_COMMENT, finder_iban_list)
|
||||
iban_finder_service.change_service(task.task, ConfigServices.SERVICE_PREFIX_FINDER_IBAN, Status.COMPLETED, True)
|
||||
continue
|
||||
iban_finder_service.change_service(task.task, ConfigServices.SERVICE_PREFIX_FINDER_IBAN, Status.FAILED, True)
|
||||
except Exception as e:
|
||||
raise
|
||||
finally:
|
||||
prisma_service.disconnect()
|
||||
|
||||
@@ -7,6 +7,7 @@ PRISMA_BINARY_PATH="/root/.cache/prisma-python/binaries"
|
||||
|
||||
if [ ! -x "$VENV_PATH/bin/python" ]; then
|
||||
python -m venv "$VENV_PATH"
|
||||
"$VENV_PATH/bin/pip" install pip --upgrade
|
||||
"$VENV_PATH/bin/pip" install --no-cache-dir -r "$REQUIREMENTS_PATH"
|
||||
"$VENV_PATH/bin/prisma" generate --schema "$SCHEMA_PATH"
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user