work-tracing/app/scheduler.py
2025-05-16 17:55:30 +04:00

72 lines
2.9 KiB
Python

"""
APScheduler setup and configuration for background tasks.
"""
import functools
from flask_apscheduler import APScheduler
# Initialize scheduler globally
scheduler = APScheduler()
def job_wrapper(func, app_context, job_id):
"""
Wrapper to log job execution start and end.
"""
@functools.wraps(func)
def wrapper(*args, **kwargs):
app_context.logger.info(f"Job '{job_id}' starting...")
try:
result = func(*args, **kwargs)
app_context.logger.info(f"Job '{job_id}' completed successfully.")
return result
except Exception as e:
app_context.logger.error(f"Job '{job_id}' failed: {e}", exc_info=True)
# Optionally re-raise or handle as needed
raise
return wrapper
def init_scheduler(app):
"""
Initializes and starts the APScheduler with the Flask app.
Registers scheduled jobs.
"""
if not scheduler.running:
scheduler.init_app(app)
# Import jobs here to avoid circular dependencies if jobs use app context or db
from app.services.work_hours_service import calculate_and_store_real_work_hours
# Register the job to calculate real work hours
# Adjust interval as needed (e.g., every 10-15 minutes)
# Ensure job_id is unique if you add more jobs
if not app.config.get('TESTING', False): # Do not run scheduler during tests by default
# Check if job already exists to prevent duplicates during reloads in debug mode
if scheduler.get_job('calc_real_work_hours') is None:
# Create a partial function that includes the app context
# The original function expects the app object as its first argument
# Explicitly set force_recalculate=False for scheduler to avoid double-counting
wrapped_job_func = job_wrapper(
functools.partial(calculate_and_store_real_work_hours, app, force_recalculate=False), \
app, \
'calc_real_work_hours'\
)
scheduler.add_job(
id='calc_real_work_hours',
func=wrapped_job_func,
trigger='interval',
minutes=1, # Changed from 15 to 1 minute
replace_existing=True
)
app.logger.info("Scheduled job 'calc_real_work_hours' to run every 1 minute.")
else:
app.logger.info("Job 'calc_real_work_hours' already scheduled.")
try:
scheduler.start()
app.logger.info("APScheduler started.")
except Exception as e:
app.logger.error(f"Failed to start APScheduler: {e}", exc_info=True)
else:
app.logger.info("APScheduler not started in TEST mode.")
else:
app.logger.info("APScheduler already running.")