
io.paradoxical.cassieq.workers.DefaultMessageConsumer Maven / Gradle / Ivy
The newest version!
package io.paradoxical.cassieq.workers;
import com.godaddy.logging.Logger;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import io.paradoxical.cassieq.dataAccess.exceptions.ExistingMonotonFoundException;
import io.paradoxical.cassieq.dataAccess.interfaces.MessageRepository;
import io.paradoxical.cassieq.factories.DataContextFactory;
import io.paradoxical.cassieq.factories.MessageRepoFactory;
import io.paradoxical.cassieq.model.Message;
import io.paradoxical.cassieq.model.QueueDefinition;
import io.paradoxical.cassieq.workers.reader.ConsumableMessage;
import io.paradoxical.cassieq.workers.reader.InvisStrategy;
import java.util.Optional;
import static com.godaddy.logging.LoggerFactory.getLogger;
public class DefaultMessageConsumer implements MessageConsumer {
private final MessagePublisher messagePublisher;
private final DataContextFactory dataContextFactory;
private Logger logger = getLogger(DefaultMessageConsumer.class);
private final QueueDefinition queueDefinition;
private final MessageRepository messageRepository;
private final InvisStrategy invisStrategy;
@Inject
public DefaultMessageConsumer(
MessageRepoFactory messageRepoFactory,
MessagePublisher messagePublisher,
InvisStrategy.Factory invisStrategyFactory,
DataContextFactory dataContextFactory,
@Assisted QueueDefinition definition) {
this.messagePublisher = messagePublisher;
this.dataContextFactory = dataContextFactory;
messageRepository = messageRepoFactory.forQueue(definition);
invisStrategy = invisStrategyFactory.forQueue(definition);
this.queueDefinition = definition;
logger = logger.with("q", definition.getQueueName()).with("version", definition.getVersion());
}
/**
* Consumes with business logic
*
* @param consumableMessage
* @return
*/
@Override
public Optional tryConsume(ConsumableMessage consumableMessage) {
if (!messageConsumable(consumableMessage.getMessage())) {
return Optional.empty();
}
final Optional consumeMessage = messageRepository.rawConsumeMessage(consumableMessage.getMessage(), consumableMessage.getInvisibility());
if (consumeMessage.isPresent()) {
invisStrategy.trackConsumedMessage(consumableMessage.toBuilder().message(consumeMessage.get()).build());
}
return consumeMessage;
}
/**
* Determines if the message is allowed to be consumed
*
* @param message
* @return
*/
private boolean messageConsumable(final Message message) {
if (message.getDeliveryCount() >= queueDefinition.getMaxDeliveryCount()) {
logger.with("tag", message.getTag())
.with("already-delivered-count", message.getDeliveryCount())
.with("max-delivery-count", queueDefinition.getMaxDeliveryCount())
.warn("Message exceeded delivery count, acking and moving on");
if (queueDefinition.getDlqName().isPresent()) {
final Optional dlqDefinitionOptional = dataContextFactory.forAccount(queueDefinition.getAccountName())
.getActiveQueue(queueDefinition.getDlqName().get());
if (dlqDefinitionOptional.isPresent()) {
final QueueDefinition dlqDefinition = dlqDefinitionOptional.get();
// publish this message to the DLQ
try {
messagePublisher.put(dlqDefinition, message.getBlob(), 0L);
}
catch (ExistingMonotonFoundException e) {
logger.error(e, "Error republishing message to dlq!");
}
}
}
if (ackMessage(message)) {
logger.with("tag", message.getTag()).success("Acked dead message");
}
return false;
}
return true;
}
private boolean ackMessage(final Message message) {
return messageRepository.ackMessage(message);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy