All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.otto.synapse.channel.StopCondition Maven / Gradle / Ivy

Go to download

A library used at otto.de to implement Spring Boot based event-sourcing microservices.

The newest version!
package de.otto.synapse.channel;

import de.otto.synapse.message.DefaultHeaderAttr;

import java.time.Clock;
import java.time.Duration;
import java.time.Instant;
import java.util.function.Predicate;

import static com.google.common.base.Predicates.alwaysFalse;

/**
 * Conditions used in {@link de.otto.synapse.endpoint.receiver.MessageReceiverEndpoint receiver endpoints} to
 * specify under which circumstances message consumption should stop.
 *
 */
public final class StopCondition {

    /**
     * Do not stop message consumption until the application is shutting down.
     *
     * @return stop condition always returning false;
     */
    public static Predicate shutdown() {
        return alwaysFalse();
    }

    /**
     * Returns a stop condition that is true after the given timestamp.
     *
     * @param timestamp the point in time after which the predicate will return true.
     *
     * @return stop condition
     */
    public static Predicate timestamp(final Instant timestamp) {
        return timestamp(timestamp, Clock.systemDefaultZone());
    }

    /**
     * Returns a stop condition that is true after the given timestamp.
     *
     * @param timestamp the point in time after which the predicate will return true.
     * @param clock the clock used to get the current time
     *
     * @return stop condition
     */
    public static Predicate timestamp(final Instant timestamp, final Clock clock) {
        return (_x) -> clock.instant().isAfter(timestamp);
    }

    /**
     * Returns a stop condition that is true if at least one message contained in the {@code ShardResponse} has arrived
     * after creating the predicate.
     *
     * @return stop condition
     */
    public static Predicate arrivalTimestampAfterNow() {
        return arrivalTimestampAfterNow(Clock.systemDefaultZone());
    }

    /**
     * Returns a stop condition that is true if at least one message contained in the {@code ShardResponse} has arrived
     * after creating the predicate.
     *
     * @param clock the clock used to get the current time
     *
     * @return stop condition
     */
    public static Predicate arrivalTimestampAfterNow(final Clock clock) {
        final Instant now = clock.instant();
        return (response) -> response
                .getMessages()
                .stream()
                .anyMatch(m -> m.getHeader().getAsInstant(DefaultHeaderAttr.MSG_ARRIVAL_TS, Instant.MIN).isAfter(now));
    }

    /**
     * Returns a stop condition that is true if the end-of-channel is reached.
     * 

* It is assumed that end-of-channel is reached if {@link ShardResponse#getDurationBehind()} is * {@link Duration#ZERO}, even if {@link ShardResponse#getMessages()} is not empty. *

*

* Note that using this predicate as a stop condition for sharded message logs, the message consumption * will stop after all shards have reached the end of the channels at least once. *

* * @return stop condition */ public static Predicate endOfChannel() { return (response) -> response.getDurationBehind().equals(Duration.ZERO); } /** * Returns a stop condition that is true if the {@link ShardResponse} does not contain any messages. *

* An empty {@code ShardResponse} does not necessarily indicate that the end-of-channel is reached. * Especially in case of Kinesis message logs it is possible that multiple {@code ShardResponses} contain * no messages, while the {@link ShardResponse#getDurationBehind()} is greater {@code ZERO}. *

*

* You might want to combine this predicate with {@link #endOfChannel()} like this: *

*

     *     StopCondition.endOfChannel().and(StopCondition.emptyResponse());
     * 
*

* Note that using this predicate as a stop condition for sharded message logs, the message consumption * will stop after all shards have reached the end of the channels at least once. *

* * @return stop condition */ public static Predicate emptyResponse() { return (response) -> response.getMessages().isEmpty(); } private StopCondition() {} }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy