72 lines
2.9 KiB
Python
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.") |