Fixes with queuing
This commit is contained in:
@@ -35,8 +35,8 @@ class UserConsumer:
|
||||
Args:
|
||||
message_dict: Dictionary containing the message data
|
||||
"""
|
||||
try:
|
||||
# Reconstruct the UserMessage object
|
||||
# Reconstruct the UserMessage object — let exceptions propagate so the
|
||||
# consumer's callback_wrapper can decide whether to ack, nack+discard, or requeue.
|
||||
message = UserMessage.from_dict(message_dict)
|
||||
|
||||
if message.event_type == UserEventType.CREATE:
|
||||
@@ -48,22 +48,18 @@ class UserConsumer:
|
||||
else:
|
||||
logger.warning(f"Unknown event type: {message.event_type}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error processing user message: {e}", exc_info=True)
|
||||
# Rollback en caso de error en el procesamiento del mensaje
|
||||
self.repo.db.rollback()
|
||||
raise
|
||||
|
||||
def _handle_create_user(self, message: UserMessage):
|
||||
"""Handle user create event"""
|
||||
try:
|
||||
logger.info(f"Creating user: {message.email}")
|
||||
|
||||
# Parse datetime strings
|
||||
if not message.fecha_nacimiento:
|
||||
raise ValueError(f"Missing fecha_nacimiento in CREATE message for email {message.email}")
|
||||
if not message.fecha_creacion:
|
||||
raise ValueError(f"Missing fecha_creacion in CREATE message for email {message.email}")
|
||||
|
||||
fecha_nacimiento = datetime.fromisoformat(message.fecha_nacimiento)
|
||||
fecha_creacion = datetime.fromisoformat(message.fecha_creacion)
|
||||
|
||||
# Create User domain object
|
||||
user = User(
|
||||
user_id=0, # Will be auto-generated by DB
|
||||
nombre=message.nombre,
|
||||
@@ -78,27 +74,18 @@ class UserConsumer:
|
||||
biografia=message.biografia
|
||||
)
|
||||
|
||||
# Save to repository with transaction handling
|
||||
saved_user = self.repo.save(user)
|
||||
logger.info(f"User created successfully: {saved_user.user_id} - {saved_user.email}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error creating user: {e}", exc_info=True)
|
||||
self.repo.db.rollback()
|
||||
raise
|
||||
|
||||
def _handle_update_user(self, message: UserMessage):
|
||||
"""Handle user update event"""
|
||||
try:
|
||||
logger.info(f"Updating user: {message.user_id}")
|
||||
|
||||
# Find the user
|
||||
user = self.repo.find_by_id(message.user_id)
|
||||
if not user:
|
||||
logger.warning(f"User not found: {message.user_id}")
|
||||
return
|
||||
|
||||
# Update fields if provided
|
||||
if message.nombre:
|
||||
user.nombre = message.nombre
|
||||
if message.apellido:
|
||||
@@ -108,18 +95,11 @@ class UserConsumer:
|
||||
if message.biografia is not None:
|
||||
user.biografia = message.biografia
|
||||
|
||||
# Save to repository with transaction handling
|
||||
updated_user = self.repo.update(user)
|
||||
self.repo.update(user)
|
||||
logger.info(f"User updated successfully: {message.user_id}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error updating user: {e}", exc_info=True)
|
||||
self.repo.db.rollback()
|
||||
raise
|
||||
|
||||
def _handle_delete_user(self, message: UserMessage):
|
||||
"""Handle user delete event"""
|
||||
try:
|
||||
logger.info(f"Deleting user: {message.user_id}")
|
||||
|
||||
success = self.repo.delete(message.user_id)
|
||||
@@ -128,11 +108,6 @@ class UserConsumer:
|
||||
else:
|
||||
logger.warning(f"Failed to delete user: {message.user_id}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error deleting user: {e}", exc_info=True)
|
||||
self.repo.db.rollback()
|
||||
raise
|
||||
|
||||
def start(self):
|
||||
"""Start consuming messages"""
|
||||
logger.info("Starting User Consumer...")
|
||||
@@ -145,7 +120,6 @@ class UserConsumer:
|
||||
logger.error(f"Consumer error: {e}", exc_info=True)
|
||||
raise
|
||||
finally:
|
||||
# Asegurar cierre de sesión
|
||||
if self.repo.db:
|
||||
try:
|
||||
self.repo.db.close()
|
||||
|
||||
@@ -23,6 +23,7 @@ class RabbitMQConsumer:
|
||||
)
|
||||
channel = connection.channel()
|
||||
channel.queue_declare(queue=self.queue_name, durable=True)
|
||||
channel.basic_qos(prefetch_count=1)
|
||||
|
||||
def callback_wrapper(ch, method, properties, body):
|
||||
try:
|
||||
@@ -34,13 +35,13 @@ class RabbitMQConsumer:
|
||||
|
||||
ch.basic_ack(delivery_tag=method.delivery_tag)
|
||||
|
||||
except IntegrityError as e:
|
||||
# Error de negocio: no tiene sentido reintentar
|
||||
logger.warning(f"Business error, discarding message: {e}")
|
||||
except (IntegrityError, ValueError, TypeError, KeyError) as e:
|
||||
# Errores de negocio/datos: no tiene sentido reintentar
|
||||
logger.warning(f"Business/data error, discarding message: {e}")
|
||||
ch.basic_nack(delivery_tag=method.delivery_tag, requeue=False)
|
||||
|
||||
except Exception as e:
|
||||
# Error transitorio (red, DB caída): sí puede resolverse solo
|
||||
# Error transitorio (red, DB caída): puede resolverse solo
|
||||
logger.error(f"Transient error processing message: {e}")
|
||||
ch.basic_nack(delivery_tag=method.delivery_tag, requeue=True)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user