44from dataclasses import dataclass
55from datetime import datetime
66from typing import Any , Dict , List , Optional
7+ from app .backend .factory import backend
78
89from apscheduler .schedulers .asyncio import AsyncIOScheduler
910
@@ -122,6 +123,7 @@ def _get_job_interval(self, job_type, metadata: JobMetadata) -> int:
122123
123124 async def _execute_job_via_executor (self , job_type : str ) -> None :
124125 """Execute a job through the enhanced executor system with proper concurrency control."""
126+ logger .info (f"🚀 Scheduled execution triggered for job type: { job_type } " )
125127 try :
126128 from app .backend .models import QueueMessage , QueueMessageType
127129
@@ -130,13 +132,38 @@ async def _execute_job_via_executor(self, job_type: str) -> None:
130132
131133 # Convert job_type string to JobType enum
132134 job_type_enum = JobType .get_or_create (job_type )
135+ logger .debug (f"Converted job type '{ job_type } ' to enum: { job_type_enum } " )
136+
137+ logger .debug (f"🔍 Checking if { job_type } has work to do..." )
133138
134139 # Get job metadata to check if it should run
135140 metadata = JobRegistry .get_metadata (job_type_enum )
136141 if not metadata :
137142 logger .error (f"No metadata found for job type: { job_type } " )
138143 return
139144
145+ # For jobs that process messages, check if there are pending messages first
146+ # This prevents unnecessary job executions when there's no work
147+ if job_type in ["tweet" , "discord" , "stx_transfer" ]:
148+ from app .backend .models import QueueMessageFilter
149+
150+ pending_messages = backend .list_queue_messages (
151+ filters = QueueMessageFilter (
152+ type = QueueMessageType .get_or_create (job_type ),
153+ is_processed = False ,
154+ )
155+ )
156+
157+ if not pending_messages :
158+ logger .debug (
159+ f"⏭️ Skipping { job_type } execution - no pending messages"
160+ )
161+ return
162+
163+ logger .debug (
164+ f"📝 Found { len (pending_messages )} pending { job_type } messages"
165+ )
166+
140167 # Create a synthetic queue message for scheduled execution
141168 # This allows the job to go through the proper executor pipeline with concurrency control
142169 synthetic_message = QueueMessage (
@@ -147,21 +174,22 @@ async def _execute_job_via_executor(self, job_type: str) -> None:
147174 "triggered_at" : str (datetime .now ()),
148175 },
149176 dao_id = None ,
150- tweet_id = None ,
151- conversation_id = None ,
177+ wallet_id = None ,
152178 is_processed = False ,
153179 result = None ,
154180 created_at = datetime .now (),
155- updated_at = datetime .now (),
156181 )
157182
158183 # Enqueue the synthetic message with the job's priority
184+ logger .debug (
185+ f"Enqueuing job { job_type } to executor with priority { metadata .priority } "
186+ )
159187 job_id = await self ._executor .priority_queue .enqueue (
160188 synthetic_message , metadata .priority
161189 )
162190
163- logger .debug (
164- f"Enqueued scheduled job { job_type } with ID { job_id } (priority: { metadata .priority } )"
191+ logger .info (
192+ f"✅ Enqueued scheduled job ' { job_type } ' with ID { job_id } (priority: { metadata .priority } )"
165193 )
166194
167195 except Exception as e :
0 commit comments