updated prisma service async runner
This commit is contained in:
@@ -0,0 +1 @@
|
||||
3.12
|
||||
@@ -0,0 +1,22 @@
|
||||
FROM python:3.12-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy only the dependency files first to leverage Docker cache
|
||||
COPY ServicesRunner/AccountRecordServices/Reader/Banks/IsBank/pyproject.toml .
|
||||
|
||||
# Install dependencies
|
||||
RUN pip install --no-cache-dir --upgrade pip && pip install --no-cache-dir .
|
||||
|
||||
# Copy only the necessary directories
|
||||
COPY ServicesRunner/AccountRecordServices/Reader/Banks /app/ServicesRunner/AccountRecordServices/Reader/Banks
|
||||
COPY ServicesRunner/Depends /app/ServicesRunner/Depends
|
||||
|
||||
# Set the Python path to include the root directory and ServicesRunner
|
||||
ENV PYTHONPATH=/app:/app/ServicesRunner
|
||||
|
||||
# Set working directory to the IsBank service directory
|
||||
WORKDIR /app/ServicesRunner/AccountRecordServices/Reader/Banks/IsBank
|
||||
|
||||
# Run the application
|
||||
CMD ["python", "app.py"]
|
||||
176
ServicesRunner/AccountRecordServices/Reader/Banks/IsBank/app.py
Normal file
176
ServicesRunner/AccountRecordServices/Reader/Banks/IsBank/app.py
Normal file
@@ -0,0 +1,176 @@
|
||||
import sys
|
||||
import socket
|
||||
import logging
|
||||
from time import sleep
|
||||
from config import IsBankConfig
|
||||
from Depends.mail_handler import EmailReaderService, EmailServiceRunner
|
||||
from Depends.service_handler import MailReaderService
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
handlers=[logging.StreamHandler(sys.stdout), logging.FileHandler('isbank_email_service.log')]
|
||||
)
|
||||
logger = logging.getLogger('IsBank_Email_Service')
|
||||
|
||||
|
||||
# Main application code
|
||||
def main():
|
||||
"""Main entry point for the IsBank email service"""
|
||||
try:
|
||||
redis_handler = MailReaderService()
|
||||
email_service = EmailReaderService(IsBankConfig())
|
||||
email_service.login_and_connect()
|
||||
runner = EmailServiceRunner(redis_handler=redis_handler, email_service=email_service)
|
||||
runner.fetch_and_set_mails()
|
||||
runner.drop()
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Error in main function: {str(e)}")
|
||||
return False
|
||||
|
||||
|
||||
def initialize_service():
|
||||
"""Initialize the service with proper error handling"""
|
||||
try:
|
||||
# Create singleton instances directly
|
||||
logger.info("Creating Redis handler singleton")
|
||||
redis_handler = MailReaderService()
|
||||
|
||||
logger.info("Creating EmailReaderService")
|
||||
email_service = EmailReaderService(IsBankConfig())
|
||||
|
||||
# Initialize email service and connect
|
||||
logger.info("Connecting to email service")
|
||||
email_service.login_and_connect()
|
||||
|
||||
# Create email service runner with the singletons
|
||||
logger.info("Creating EmailServiceRunner")
|
||||
runner = EmailServiceRunner(redis_handler=redis_handler, email_service=email_service)
|
||||
|
||||
if runner:
|
||||
logger.info("Email service runner initialized successfully")
|
||||
return runner
|
||||
else:
|
||||
logger.error("Failed to initialize email service runner")
|
||||
# Sleep before retry to avoid rapid failure loops
|
||||
sleep(5)
|
||||
return initialize_service()
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Service initialization failed: {str(e)}")
|
||||
# Sleep before retry to avoid rapid failure loops
|
||||
sleep(5)
|
||||
return initialize_service()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
logger.info("Starting IsBank Email Service")
|
||||
print(f"Starting Service Mail Reader.")
|
||||
|
||||
# Initialize service
|
||||
runner = initialize_service()
|
||||
|
||||
# Configurable parameters
|
||||
normal_sleep_time = 10 # seconds between normal operations
|
||||
error_sleep_time = 30 # seconds to wait after an error before retrying
|
||||
max_consecutive_errors = 5 # maximum number of consecutive errors before longer pause
|
||||
extended_error_sleep = 120 # seconds to wait after hitting max consecutive errors
|
||||
consecutive_errors = 0
|
||||
|
||||
# Main service loop
|
||||
while True:
|
||||
try:
|
||||
# Main processing
|
||||
runner.fetch_and_set_mails()
|
||||
|
||||
# Reset error counter on success
|
||||
if consecutive_errors > 0:
|
||||
logger.info(f"Service recovered after {consecutive_errors} consecutive errors")
|
||||
consecutive_errors = 0
|
||||
|
||||
# Normal operation sleep
|
||||
sleep(normal_sleep_time)
|
||||
|
||||
except MailReaderService.REDIS_EXCEPTIONS as e:
|
||||
# Redis-specific errors
|
||||
consecutive_errors += 1
|
||||
logger.error(f"Redis error (attempt {consecutive_errors}): {str(e)}")
|
||||
|
||||
# Use centralized reconnection handler from RedisHandler
|
||||
redis_handler, need_extended_sleep = MailReaderService.handle_reconnection(
|
||||
consecutive_errors=consecutive_errors, max_consecutive_errors=max_consecutive_errors
|
||||
)
|
||||
|
||||
if redis_handler:
|
||||
# Update runner's redis handler with the new instance
|
||||
runner.redis_handler = redis_handler
|
||||
runner.redis_connected = False # Will trigger reconnection on next cycle
|
||||
|
||||
# Sleep based on error count
|
||||
if need_extended_sleep:
|
||||
sleep(extended_error_sleep)
|
||||
else:
|
||||
sleep(error_sleep_time)
|
||||
|
||||
except socket.error as e:
|
||||
# Email connection errors
|
||||
consecutive_errors += 1
|
||||
logger.error(f"Email connection error (attempt {consecutive_errors}): {str(e)}")
|
||||
|
||||
# Try to re-establish email connection
|
||||
try:
|
||||
logger.info("Attempting to re-establish email connection...")
|
||||
# Create new email service directly
|
||||
email_service = EmailReaderService(IsBankConfig())
|
||||
email_service.login_and_connect()
|
||||
|
||||
# Create new runner with existing Redis handler and new email service
|
||||
redis_handler = runner.redis_handler # Preserve existing Redis handler
|
||||
runner = EmailServiceRunner(redis_handler=redis_handler, email_service=email_service)
|
||||
logger.info("Successfully re-established email connection")
|
||||
except Exception as email_retry_error:
|
||||
logger.error(f"Failed to re-establish email connection: {str(email_retry_error)}")
|
||||
|
||||
# Determine sleep time based on consecutive errors
|
||||
if consecutive_errors >= max_consecutive_errors:
|
||||
logger.warning(f"Hit {max_consecutive_errors} consecutive email errors, taking longer pause")
|
||||
sleep(extended_error_sleep)
|
||||
else:
|
||||
sleep(error_sleep_time)
|
||||
|
||||
except Exception as e:
|
||||
# Any other unexpected errors
|
||||
consecutive_errors += 1
|
||||
logger.error(f"Unexpected error (attempt {consecutive_errors}): {str(e)}")
|
||||
|
||||
# For any other error, try to reinitialize everything after some delay
|
||||
if consecutive_errors >= max_consecutive_errors:
|
||||
logger.warning(f"Hit {max_consecutive_errors} consecutive errors, reinitializing service")
|
||||
try:
|
||||
# Try to clean up existing connections
|
||||
try:
|
||||
runner.drop()
|
||||
except Exception as cleanup_error:
|
||||
logger.warning(f"Error during cleanup: {str(cleanup_error)}")
|
||||
|
||||
# Reinitialize the service directly
|
||||
redis_handler = MailReaderService()
|
||||
email_service = EmailReaderService(IsBankConfig())
|
||||
email_service.login_and_connect()
|
||||
runner = EmailServiceRunner(redis_handler=redis_handler, email_service=email_service)
|
||||
|
||||
if runner:
|
||||
logger.info("Successfully reinitialized email service runner")
|
||||
consecutive_errors = 0 # Reset counter after reinitialization
|
||||
else:
|
||||
logger.error("Failed to reinitialize email service runner")
|
||||
except Exception as reinit_error:
|
||||
logger.error(f"Service reinitialization failed: {str(reinit_error)}")
|
||||
|
||||
sleep(extended_error_sleep)
|
||||
else:
|
||||
# For fewer consecutive errors, just retry the current runner
|
||||
print(f"Error: {str(e)}")
|
||||
sleep(error_sleep_time)
|
||||
@@ -0,0 +1,16 @@
|
||||
import os
|
||||
from Depends.config import ConfigServices
|
||||
|
||||
class IsBankConfig:
|
||||
|
||||
MAILBOX: str = os.getenv("MAILBOX", "bilgilendirme@ileti.isbank.com.tr")
|
||||
AUTHORIZE_IBAN: str = os.getenv("AUTHORIZE_IBAN", "4245-0093333")
|
||||
NO_ATTACHMENT_FOLDER: str = "NoAttachment"
|
||||
COMPLETED_FOLDER: str = "Completed"
|
||||
TASK_DATA_PREFIX: str = ConfigServices.MAIN_TASK_PREFIX
|
||||
TASK_MAILID_INDEX_PREFIX: str = ConfigServices.TASK_MAILID_INDEX_PREFIX
|
||||
TASK_UUID_INDEX_PREFIX: str = ConfigServices.TASK_UUID_INDEX_PREFIX
|
||||
TASK_SEEN_PREFIX: str = ConfigServices.TASK_SEEN_PREFIX
|
||||
SERVICE_PREFIX: str = ConfigServices.SERVICE_PREFIX_MAIL_READER
|
||||
NEXT_SERVICE_PREFIX: str = ConfigServices.SERVICE_PREFIX_MAIL_PARSER
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
[project]
|
||||
name = "isbank-email-reader"
|
||||
version = "0.1.0"
|
||||
description = "IsBank Email Reader Service"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = [
|
||||
"arrow>=1.3.0",
|
||||
"redis>=6.4.0",
|
||||
"pydantic>=2.0.0",
|
||||
"pydantic-settings>=2.0.0",
|
||||
"email-validator>=2.0.0",
|
||||
]
|
||||
@@ -0,0 +1,4 @@
|
||||
Uses
|
||||
|
||||
- MainRedisHandler
|
||||
- MailHandler
|
||||
@@ -0,0 +1,9 @@
|
||||
[project]
|
||||
name = "reader"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = [
|
||||
"redis>=6.4.0",
|
||||
]
|
||||
23
ServicesRunner/AccountRecordServices/Reader/uv.lock
generated
Normal file
23
ServicesRunner/AccountRecordServices/Reader/uv.lock
generated
Normal file
@@ -0,0 +1,23 @@
|
||||
version = 1
|
||||
revision = 3
|
||||
requires-python = ">=3.12"
|
||||
|
||||
[[package]]
|
||||
name = "reader"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "redis" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [{ name = "redis", specifier = ">=6.4.0" }]
|
||||
|
||||
[[package]]
|
||||
name = "redis"
|
||||
version = "6.4.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/0d/d6/e8b92798a5bd67d659d51a18170e91c16ac3b59738d91894651ee255ed49/redis-6.4.0.tar.gz", hash = "sha256:b01bc7282b8444e28ec36b261df5375183bb47a07eb9c603f284e89cbc5ef010", size = 4647399, upload-time = "2025-08-07T08:10:11.441Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e8/02/89e2ed7e85db6c93dfa9e8f691c5087df4e3551ab39081a4d7c6d1f90e05/redis-6.4.0-py3-none-any.whl", hash = "sha256:f0544fa9604264e9464cdf4814e7d4830f74b165d52f2a330a760a88dd248b7f", size = 279847, upload-time = "2025-08-07T08:10:09.84Z" },
|
||||
]
|
||||
Reference in New Issue
Block a user