@@ -168,6 +168,8 @@ def format_local_time_filter(utc_dt, format_str='%Y-%m-%d %H:%M'):
168168
169169def schedule_all_repositories ():
170170 """Schedule all active repositories on startup"""
171+ from datetime import datetime # Import to ensure availability
172+
171173 try :
172174 # Clean up any stuck 'running' jobs from previous sessions
173175 stuck_jobs = BackupJob .query .filter_by (status = 'running' ).all ()
@@ -621,25 +623,32 @@ def favicon():
621623def schedule_backup_job (repository ):
622624 """Schedule a backup job for a repository"""
623625 if not repository .is_active :
626+ logger .info (f"Repository { repository .name } is inactive, not scheduling" )
624627 return
625628
626629 job_id = f'backup_{ repository .id } '
630+ logger .info (f"Attempting to schedule job { job_id } for repository { repository .name } " )
627631
628632 # Remove existing job if it exists - try multiple ways to ensure it's gone
629633 try :
630- if scheduler .get_job (job_id ):
634+ existing_job = scheduler .get_job (job_id )
635+ if existing_job :
631636 scheduler .remove_job (job_id )
632637 logger .info (f"Removed existing scheduled job: { job_id } " )
638+ else :
639+ logger .info (f"No existing job found for { job_id } " )
633640 except Exception as e :
634641 logger .warning (f"Could not remove existing job { job_id } : { e } " )
635642
636643 # Double-check that job is really gone
637644 if scheduler .get_job (job_id ):
638- logger .error (f"Job { job_id } still exists after removal attempt" )
645+ logger .error (f"Job { job_id } still exists after removal attempt, aborting schedule " )
639646 return
640647
641648 # Create a wrapper function that includes Flask app context
642649 def backup_with_context ():
650+ from datetime import datetime , timedelta # Import inside function for closure scope
651+
643652 with app .app_context ():
644653 try :
645654 # Refresh the repository object to ensure it's bound to the current session
@@ -754,24 +763,44 @@ def backup_with_context():
754763 max_instances = 1 # Only one instance of this specific job can run
755764 )
756765
757- logger .info (f"Scheduled backup job for { repository .name } with trigger: { trigger } " )
766+ logger .info (f"Successfully scheduled backup job for { repository .name } with trigger: { trigger } " )
758767
759768 # Verify the job was actually added
760769 added_job = scheduler .get_job (job_id )
761770 if added_job :
762771 logger .info (f"Job { job_id } successfully scheduled, next run: { added_job .next_run_time } " )
763772 else :
764- logger .error (f"Failed to schedule job { job_id } " )
773+ logger .error (f"Failed to schedule job { job_id } - job not found after creation " )
765774
766775# Initialize scheduler with existing repositories at startup
767776# This runs after all functions are defined
768- try :
769- with app .app_context ():
770- logger .info ("Starting scheduler initialization at app startup..." )
771- ensure_scheduler_initialized ()
772- logger .info ("Scheduler initialization at startup completed" )
773- except Exception as e :
774- logger .error (f"Failed to initialize scheduler at startup: { e } " )
777+ if not globals ().get ('_scheduler_startup_completed' , False ):
778+ try :
779+ with app .app_context ():
780+ logger .info ("Starting scheduler initialization at app startup..." )
781+
782+ # Log current scheduler state
783+ existing_jobs = scheduler .get_jobs ()
784+ logger .info (f"Scheduler has { len (existing_jobs )} existing jobs before initialization" )
785+
786+ ensure_scheduler_initialized ()
787+
788+ # Log final state
789+ final_jobs = scheduler .get_jobs ()
790+ backup_jobs = [job for job in final_jobs if job .id .startswith ('backup_' )]
791+ logger .info (f"Scheduler initialization completed. Total jobs: { len (final_jobs )} , Backup jobs: { len (backup_jobs )} " )
792+
793+ for job in backup_jobs :
794+ logger .info (f"Scheduled job: { job .id } -> next run: { job .next_run_time } " )
795+
796+ globals ()['_scheduler_startup_completed' ] = True
797+
798+ except Exception as e :
799+ logger .error (f"Failed to initialize scheduler at startup: { e } " )
800+ import traceback
801+ logger .error (f"Traceback: { traceback .format_exc ()} " )
802+ else :
803+ logger .info ("Scheduler startup initialization skipped - already completed" )
775804
776805if __name__ == '__main__' :
777806 app .run (host = '0.0.0.0' , port = 8080 , debug = False )
0 commit comments