- backend/api/schedules.py +2 -2
- backend/celery_tasks/__init__.py +6 -1
- backend/celery_tasks/schedule_loader.py +25 -3
- start_app.py +2 -1
backend/api/schedules.py
CHANGED
|
@@ -136,7 +136,7 @@ def create_schedule():
|
|
| 136 |
try:
|
| 137 |
print("[INFO] Triggering immediate Celery Beat schedule update...")
|
| 138 |
# Execute the schedule loader task immediately to update Celery Beat
|
| 139 |
-
celery_result = load_schedules_task.
|
| 140 |
print(f"[INFO] Celery Beat update task queued: {celery_result.id}")
|
| 141 |
|
| 142 |
# Add the task ID to the response for tracking
|
|
@@ -229,7 +229,7 @@ def delete_schedule(schedule_id):
|
|
| 229 |
try:
|
| 230 |
print("[INFO] Triggering immediate Celery Beat schedule update after deletion...")
|
| 231 |
# Execute the schedule loader task immediately to update Celery Beat
|
| 232 |
-
celery_result = load_schedules_task.
|
| 233 |
print(f"[INFO] Celery Beat update task queued: {celery_result.id}")
|
| 234 |
|
| 235 |
# Add the task ID to the response for tracking
|
|
|
|
| 136 |
try:
|
| 137 |
print("[INFO] Triggering immediate Celery Beat schedule update...")
|
| 138 |
# Execute the schedule loader task immediately to update Celery Beat
|
| 139 |
+
celery_result = load_schedules_task.apply_async(queue='scheduler')
|
| 140 |
print(f"[INFO] Celery Beat update task queued: {celery_result.id}")
|
| 141 |
|
| 142 |
# Add the task ID to the response for tracking
|
|
|
|
| 229 |
try:
|
| 230 |
print("[INFO] Triggering immediate Celery Beat schedule update after deletion...")
|
| 231 |
# Execute the schedule loader task immediately to update Celery Beat
|
| 232 |
+
celery_result = load_schedules_task.apply_async(queue='scheduler')
|
| 233 |
print(f"[INFO] Celery Beat update task queued: {celery_result.id}")
|
| 234 |
|
| 235 |
# Add the task ID to the response for tracking
|
backend/celery_tasks/__init__.py
CHANGED
|
@@ -1 +1,6 @@
|
|
| 1 |
-
# Initialize the celery_tasks package
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Initialize the celery_tasks package
|
| 2 |
+
from . import content_tasks
|
| 3 |
+
from . import schedule_loader
|
| 4 |
+
|
| 5 |
+
# This ensures that the tasks are registered with Celery
|
| 6 |
+
__all__ = ['content_tasks', 'schedule_loader']
|
backend/celery_tasks/schedule_loader.py
CHANGED
|
@@ -58,7 +58,8 @@ def parse_schedule_time(schedule_time):
|
|
| 58 |
'day_of_week': '*'
|
| 59 |
}
|
| 60 |
|
| 61 |
-
|
|
|
|
| 62 |
"""
|
| 63 |
Celery task to load schedules from the database and create periodic tasks.
|
| 64 |
This task runs every 5 minutes to check for new or updated schedules.
|
|
@@ -69,6 +70,7 @@ def load_schedules_task():
|
|
| 69 |
|
| 70 |
# Get Supabase configuration
|
| 71 |
supabase_config = get_supabase_config()
|
|
|
|
| 72 |
|
| 73 |
# Initialize Supabase client
|
| 74 |
supabase_client = init_supabase(
|
|
@@ -77,6 +79,7 @@ def load_schedules_task():
|
|
| 77 |
)
|
| 78 |
|
| 79 |
# Fetch all schedules from Supabase
|
|
|
|
| 80 |
response = (
|
| 81 |
supabase_client
|
| 82 |
.table("Scheduling")
|
|
@@ -84,10 +87,22 @@ def load_schedules_task():
|
|
| 84 |
.execute()
|
| 85 |
)
|
| 86 |
|
|
|
|
|
|
|
|
|
|
| 87 |
schedules = response.data if response.data else []
|
| 88 |
print(f"[CELERY BEAT] Found {len(schedules)} schedules in database")
|
| 89 |
logger.info(f"Found {len(schedules)} schedules")
|
| 90 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
# Get current beat schedule
|
| 92 |
current_schedule = celery_app.conf.beat_schedule
|
| 93 |
|
|
@@ -103,18 +118,23 @@ def load_schedules_task():
|
|
| 103 |
schedule_time = schedule.get('schedule_time')
|
| 104 |
adjusted_time = schedule.get('adjusted_time')
|
| 105 |
|
|
|
|
|
|
|
| 106 |
if not schedule_time or not adjusted_time:
|
| 107 |
logger.warning(f"Invalid schedule format for schedule {schedule_id}")
|
|
|
|
| 108 |
continue
|
| 109 |
|
| 110 |
# Parse schedule times
|
| 111 |
content_gen_time = parse_schedule_time(adjusted_time)
|
| 112 |
publish_time = parse_schedule_time(schedule_time)
|
| 113 |
|
|
|
|
|
|
|
| 114 |
# Create content generation job (5 minutes before publishing)
|
| 115 |
gen_job_id = f"gen_{schedule_id}"
|
| 116 |
new_schedule[gen_job_id] = {
|
| 117 |
-
'task': 'celery_tasks.content_tasks.generate_content_task',
|
| 118 |
'schedule': crontab(
|
| 119 |
minute=content_gen_time['minute'],
|
| 120 |
hour=content_gen_time['hour'],
|
|
@@ -127,11 +147,12 @@ def load_schedules_task():
|
|
| 127 |
)
|
| 128 |
}
|
| 129 |
logger.info(f"Created content generation job: {gen_job_id}")
|
|
|
|
| 130 |
|
| 131 |
# Create publishing job
|
| 132 |
pub_job_id = f"pub_{schedule_id}"
|
| 133 |
new_schedule[pub_job_id] = {
|
| 134 |
-
'task': 'celery_tasks.content_tasks.publish_post_task',
|
| 135 |
'schedule': crontab(
|
| 136 |
minute=publish_time['minute'],
|
| 137 |
hour=publish_time['hour'],
|
|
@@ -143,6 +164,7 @@ def load_schedules_task():
|
|
| 143 |
)
|
| 144 |
}
|
| 145 |
logger.info(f"Created publishing job: {pub_job_id}")
|
|
|
|
| 146 |
|
| 147 |
except Exception as e:
|
| 148 |
logger.error(f"Error creating jobs for schedule {schedule.get('id')}: {str(e)}")
|
|
|
|
| 58 |
'day_of_week': '*'
|
| 59 |
}
|
| 60 |
|
| 61 |
+
@celery_app.task(bind=True)
|
| 62 |
+
def load_schedules_task(self):
|
| 63 |
"""
|
| 64 |
Celery task to load schedules from the database and create periodic tasks.
|
| 65 |
This task runs every 5 minutes to check for new or updated schedules.
|
|
|
|
| 70 |
|
| 71 |
# Get Supabase configuration
|
| 72 |
supabase_config = get_supabase_config()
|
| 73 |
+
print(f"[CELERY BEAT] Supabase config: URL={supabase_config['SUPABASE_URL'][:50]}...")
|
| 74 |
|
| 75 |
# Initialize Supabase client
|
| 76 |
supabase_client = init_supabase(
|
|
|
|
| 79 |
)
|
| 80 |
|
| 81 |
# Fetch all schedules from Supabase
|
| 82 |
+
print("[CELERY BEAT] Executing database query...")
|
| 83 |
response = (
|
| 84 |
supabase_client
|
| 85 |
.table("Scheduling")
|
|
|
|
| 87 |
.execute()
|
| 88 |
)
|
| 89 |
|
| 90 |
+
print(f"[CELERY BEAT] Database query response: {type(response)}")
|
| 91 |
+
print(f"[CELERY BEAT] Response data: {response.data if response.data else 'None'}")
|
| 92 |
+
|
| 93 |
schedules = response.data if response.data else []
|
| 94 |
print(f"[CELERY BEAT] Found {len(schedules)} schedules in database")
|
| 95 |
logger.info(f"Found {len(schedules)} schedules")
|
| 96 |
|
| 97 |
+
# Log details of each schedule for debugging
|
| 98 |
+
for i, schedule in enumerate(schedules):
|
| 99 |
+
print(f"[CELERY BEAT] Schedule {i}: {schedule}")
|
| 100 |
+
schedule_id = schedule.get('id')
|
| 101 |
+
schedule_time = schedule.get('schedule_time')
|
| 102 |
+
adjusted_time = schedule.get('adjusted_time')
|
| 103 |
+
social_network = schedule.get('Social_network', {})
|
| 104 |
+
print(f"[CELERY BEAT] Schedule {schedule_id} - schedule_time: {schedule_time}, adjusted_time: {adjusted_time}, social_network: {social_network}")
|
| 105 |
+
|
| 106 |
# Get current beat schedule
|
| 107 |
current_schedule = celery_app.conf.beat_schedule
|
| 108 |
|
|
|
|
| 118 |
schedule_time = schedule.get('schedule_time')
|
| 119 |
adjusted_time = schedule.get('adjusted_time')
|
| 120 |
|
| 121 |
+
print(f"[CELERY BEAT] Processing schedule {schedule_id}: schedule_time={schedule_time}, adjusted_time={adjusted_time}")
|
| 122 |
+
|
| 123 |
if not schedule_time or not adjusted_time:
|
| 124 |
logger.warning(f"Invalid schedule format for schedule {schedule_id}")
|
| 125 |
+
print(f"[CELERY BEAT] WARNING: Invalid schedule format for schedule {schedule_id}")
|
| 126 |
continue
|
| 127 |
|
| 128 |
# Parse schedule times
|
| 129 |
content_gen_time = parse_schedule_time(adjusted_time)
|
| 130 |
publish_time = parse_schedule_time(schedule_time)
|
| 131 |
|
| 132 |
+
print(f"[CELERY BEAT] Parsed times - Content gen: {content_gen_time}, Publish: {publish_time}")
|
| 133 |
+
|
| 134 |
# Create content generation job (5 minutes before publishing)
|
| 135 |
gen_job_id = f"gen_{schedule_id}"
|
| 136 |
new_schedule[gen_job_id] = {
|
| 137 |
+
'task': 'backend.celery_tasks.content_tasks.generate_content_task',
|
| 138 |
'schedule': crontab(
|
| 139 |
minute=content_gen_time['minute'],
|
| 140 |
hour=content_gen_time['hour'],
|
|
|
|
| 147 |
)
|
| 148 |
}
|
| 149 |
logger.info(f"Created content generation job: {gen_job_id}")
|
| 150 |
+
print(f"[CELERY BEAT] Created content generation job: {gen_job_id}")
|
| 151 |
|
| 152 |
# Create publishing job
|
| 153 |
pub_job_id = f"pub_{schedule_id}"
|
| 154 |
new_schedule[pub_job_id] = {
|
| 155 |
+
'task': 'backend.celery_tasks.content_tasks.publish_post_task',
|
| 156 |
'schedule': crontab(
|
| 157 |
minute=publish_time['minute'],
|
| 158 |
hour=publish_time['hour'],
|
|
|
|
| 164 |
)
|
| 165 |
}
|
| 166 |
logger.info(f"Created publishing job: {pub_job_id}")
|
| 167 |
+
print(f"[CELERY BEAT] Created publishing job: {pub_job_id}")
|
| 168 |
|
| 169 |
except Exception as e:
|
| 170 |
logger.error(f"Error creating jobs for schedule {schedule.get('id')}: {str(e)}")
|
start_app.py
CHANGED
|
@@ -46,7 +46,8 @@ def start_celery_components():
|
|
| 46 |
"--loglevel=debug",
|
| 47 |
"--pool=solo",
|
| 48 |
"--max-tasks-per-child=100",
|
| 49 |
-
"--events" # Enable task events for monitoring
|
|
|
|
| 50 |
]
|
| 51 |
|
| 52 |
# Start Celery beat
|
|
|
|
| 46 |
"--loglevel=debug",
|
| 47 |
"--pool=solo",
|
| 48 |
"--max-tasks-per-child=100",
|
| 49 |
+
"--events", # Enable task events for monitoring
|
| 50 |
+
"-Q", "content,publish,scheduler" # Listen to all queues
|
| 51 |
]
|
| 52 |
|
| 53 |
# Start Celery beat
|