admin管理员组

文章数量:1312816

While exploring Spring Modulith we were asking ourselves: "What is the idiomatic way to detect events that are retried over and over again without ever being completed?" In a real world scenario we would like to be somehow notified about such a condition.

Spring Modulith provides the Abstraction IncompleteEventPublications

public interface IncompleteEventPublications {
    void resubmitIncompletePublications(Predicate<EventPublication> filter);
    void resubmitIncompletePublicationsOlderThan(Duration duration);
}

which allows to resubmit events to be processed. However we fail to see how we can use this abstraction in a good way to detect events which are resubmitted over and over again (likely without ever being completed).

Of course we could abuse the Predicate to cause a side effect

@Scheduled(fixedDelayString = "5s")
void retryJobs() {
    incompleteEventPublications.resubmitIncompletePublications(event -> {
        var isOld = event.getPublicationDate().isBefore(Instant.now().minus(Duration.ofHours(3)));
        if (isOld) {
            incrementDeadLetterCounter();
        }
        return !isOld;
    });
}

but this is incredibly ugly and we do not consider it a 'good' solution.

Another way would be to use .springframework.modulith.events.core.EventPublicationRegistry from the spring-modulith-events-core package. Considering there is an -api package, it does feel like internal stuff and should probably not be used.

private final .springframework.modulith.events.core.EventPublicationRegistry registry;

@Scheduled(fixedDelayString = "1m")
void detectDeadLetters() {
    var deadLetterAmount = registry.findIncompletePublications().stream()
            .map(EventPublication::getPublicationDate)
            .filter(e -> e.isBefore(Instant.now().minus(Duration.ofHours(3))))
            .count();

    setGauge(deadLetterAmount);
}

Is there a better way?

本文标签: What is the idiomatic way to detect dead letter events in Spring ModulithStack Overflow