moved
This commit is contained in:
109
email-worker/domain_poller.py
Normal file
109
email-worker/domain_poller.py
Normal file
@@ -0,0 +1,109 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Domain queue poller
|
||||
"""
|
||||
|
||||
import json
|
||||
import time
|
||||
import threading
|
||||
import traceback
|
||||
|
||||
from logger import log
|
||||
from aws import SQSHandler
|
||||
from worker import MessageProcessor
|
||||
from metrics.prometheus import MetricsCollector
|
||||
|
||||
|
||||
class DomainPoller:
|
||||
"""Polls SQS queue for a single domain"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
domain: str,
|
||||
queue_url: str,
|
||||
message_processor: MessageProcessor,
|
||||
sqs: SQSHandler,
|
||||
metrics: MetricsCollector,
|
||||
stop_event: threading.Event,
|
||||
stats_dict: dict,
|
||||
stats_lock: threading.Lock
|
||||
):
|
||||
self.domain = domain
|
||||
self.queue_url = queue_url
|
||||
self.processor = message_processor
|
||||
self.sqs = sqs
|
||||
self.metrics = metrics
|
||||
self.stop_event = stop_event
|
||||
self.stats_dict = stats_dict
|
||||
self.stats_lock = stats_lock
|
||||
self.worker_name = f"worker-{domain}"
|
||||
self.messages_processed = 0
|
||||
|
||||
def poll(self):
|
||||
"""Main polling loop"""
|
||||
log(f"🚀 Starting poller for {self.domain}", 'INFO', self.worker_name)
|
||||
|
||||
while not self.stop_event.is_set():
|
||||
try:
|
||||
# Receive messages from queue
|
||||
messages = self.sqs.receive_messages(self.queue_url)
|
||||
|
||||
# Update queue size metric
|
||||
if self.metrics:
|
||||
queue_size = self.sqs.get_queue_size(self.queue_url)
|
||||
self.metrics.set_queue_size(self.domain, queue_size)
|
||||
|
||||
if not messages:
|
||||
continue
|
||||
|
||||
log(f"✉ Received {len(messages)} message(s)", 'INFO', self.worker_name)
|
||||
|
||||
for message in messages:
|
||||
if self.stop_event.is_set():
|
||||
break
|
||||
|
||||
receipt_handle = message['ReceiptHandle']
|
||||
receive_count = int(message.get('Attributes', {}).get('ApproximateReceiveCount', 1))
|
||||
|
||||
if self.metrics:
|
||||
self.metrics.increment_in_flight()
|
||||
start_time = time.time()
|
||||
|
||||
try:
|
||||
success = self.processor.process_message(self.domain, message, receive_count)
|
||||
|
||||
if success:
|
||||
self.sqs.delete_message(self.queue_url, receipt_handle)
|
||||
self.messages_processed += 1
|
||||
|
||||
# Update shared stats
|
||||
with self.stats_lock:
|
||||
self.stats_dict[self.domain] = self.messages_processed
|
||||
else:
|
||||
log(
|
||||
f"⚠ Retry queued (attempt {receive_count}/3)",
|
||||
'WARNING',
|
||||
self.worker_name
|
||||
)
|
||||
|
||||
except json.JSONDecodeError as e:
|
||||
log(f"✗ Invalid message format: {e}", 'ERROR', self.worker_name)
|
||||
self.sqs.delete_message(self.queue_url, receipt_handle)
|
||||
|
||||
except Exception as e:
|
||||
log(f"✗ Error processing message: {e}", 'ERROR', self.worker_name)
|
||||
traceback.print_exc()
|
||||
|
||||
finally:
|
||||
if self.metrics:
|
||||
self.metrics.decrement_in_flight()
|
||||
self.metrics.observe_processing_time(
|
||||
self.domain,
|
||||
time.time() - start_time
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
log(f"✗ Error polling: {e}", 'ERROR', self.worker_name)
|
||||
time.sleep(5)
|
||||
|
||||
log(f"👋 Stopped (processed: {self.messages_processed})", 'INFO', self.worker_name)
|
||||
Reference in New Issue
Block a user