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

net.openhft.chronicle.queue.ExcerptTailer Maven / Gradle / Ivy

There is a newer version: 5.27ea0
Show newest version
/*
 * Copyright 2016-2020 chronicle.software
 *
 *       https://chronicle.software
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.openhft.chronicle.queue;

import net.openhft.chronicle.core.annotation.SingleThreaded;
import net.openhft.chronicle.core.io.IORuntimeException;
import net.openhft.chronicle.wire.DocumentContext;
import net.openhft.chronicle.wire.MarshallableIn;
import net.openhft.chronicle.wire.ReadMarshallable;
import net.openhft.chronicle.wire.SourceContext;
import org.jetbrains.annotations.NotNull;

/**
 * The component that facilitates sequentially reading data from a {@link ChronicleQueue}.
 *
 * 

NOTE: Tailers are NOT thread-safe, sharing a Tailer between threads will lead to errors and unpredictable behaviour. */ @SingleThreaded public interface ExcerptTailer extends ExcerptCommon, MarshallableIn, SourceContext { /** * Returns the {@link DocumentContext } for this ExcerptTailer. *

* This is equivalent to {@link ExcerptTailer#readDocument(ReadMarshallable)} but without the use of a * lambda expression. *

* This method is the ExcerptTailer equivalent of {@link net.openhft.chronicle.wire.WireIn#readingDocument()} * * @return the document context */ @Override @NotNull default DocumentContext readingDocument() { return readingDocument(false); } /** * Returns the {@link DocumentContext } for this ExcerptTailer. *

* This is equivalent to {@link ExcerptTailer#readDocument(ReadMarshallable)} but without the use of a * lambda expression. *

* This method is the ExcerptTailer equivalent of {@link net.openhft.chronicle.wire.WireIn#readingDocument()} * * @param includeMetaData if the DocumentContext shall be metadata aware. * @return the document context */ @NotNull DocumentContext readingDocument(boolean includeMetaData); /** * Returns the current index of this Tailer. *

* If this method is invoked within a {@code try (tailer.readingDocument(){ }} block, returns the index of * the current reading document. Otherwise, returns the next index to read. *

* The index includes the cycle and the sequence number within that cycle. * * @return the current index of this Tailer */ @Override long index(); default long lastReadIndex() { return -1; } /** * Returns the current cycle for this Tailer. *

* Usually, each cycle will have its own unique data file to store excerpts. * * @return Returns the current cycle for this Tailer */ int cycle(); /** * Tries to move the index for this Tailer to the provided {@code index}. *

* The index contains both the cycle number and sequence number within the cycle. *

* In order for the operation to succeed, the roll file, corresponding to * the cycle number in the index, must be present and the roll file must * contain the sequence number contained in the index. *

* If the index is not a valid index, the operation is undefined. * * @param index to move to. * @return if this is a valid index. */ boolean moveToIndex(long index); /** * Tries to move to the start of a cycle for this Tailer to the provided {@code cycle}. *

* In order for the operation to succeed, the roll file, corresponding to * the cycle number, must be present. *

* If the cycle is not a valid cycle, the operation is undefined. * * @param cycle to move to. * @return if this is a valid cycle. */ boolean moveToCycle(int cycle); /** * Moves the index for this Tailer to the first existing excerpt in the queue. * * @return this ExcerptTailer */ @NotNull ExcerptTailer toStart(); /** * Moves the index for this Tailer to the end of the queue. *

* If the direction() == FORWARD, this will be the index position corresponding to one more * than the last entry. Otherwise, the index will be the last excerpt. *

* This is not atomic with the appenders, in other words if a cycle has been added in the * current millisecond, toEnd() may not see it, This is because for performance reasons, the * queue.lastCycle() is cached, as finding the last cycle is expensive, it requires asking the * directory for the Files.list() so, this cache is only refreshed if the call toEnd() is in a * new millisecond. Hence, a whole milliseconds with of data could be added to the * chronicle-queue that toEnd() won’t see. For appenders that are using the same queue * instance ( and with then same JVM ), they can be informed that the last cycle has * changed, this will yield better results, but atomicity can still not be guaranteed. * * @return this ExcerptTailer */ @NotNull ExcerptTailer toEnd(); /** * Sets the {@code striding} property of this Tailer. *

* When striding is enabled AND direction is BACKWARD, skip to the entries easiest to find, doesn't need to be every entry. * * @param striding skip to the indexStride if that is easy, doesn't always happen. * @return this ExcerptTailer */ ExcerptTailer striding(boolean striding); /** * Returns the striding property of this Tailer. * * @return the striding property of this Tailer * @see #striding(boolean) */ boolean striding(); /** * Sets the direction of this ExcerptTailer. *

* The direction determines the direction of movement upon reading an excerpt. * * @param direction which is either of NONE, FORWARD, BACKWARD * @return this ExcerptTailer * @throws NullPointerException if the provided {@code direction} is {@code null} */ @NotNull ExcerptTailer direction(@NotNull TailerDirection direction); /** * Returns the direction of this ExcerptTailer. *

* The direction determines the direction of movement upon reading an excerpt. * * @return the direction of this ExcerptTailer */ TailerDirection direction(); /** * Winds this ExcerptTailer to after the last entry which wrote an entry to the queue. * * @param queue which was written to. * @return this ExcerptTailer * @throws IORuntimeException if the provided {@code queue} couldn't be wound to the last index. * @throws NullPointerException if the provided {@code queue} is {@code null} */ @NotNull default ExcerptTailer afterLastWritten(ChronicleQueue queue) { return afterWrittenMessageAtIndex(queue, Long.MIN_VALUE); } /** * Sets the Read After Replica Acknowledged property of this Tailer to the * provided {@code readAfterReplicaAcknowledged}. *

* Enterprise Queue only: if replication enabled, setting this to {@code true} on a source queue ensures that * this tailer will not read until at least one of the sinks has acknowledged receipt of the excerpt. * This will block forever if no sinks acknowledge receipt. * * @param readAfterReplicaAcknowledged enable */ default void readAfterReplicaAcknowledged(boolean readAfterReplicaAcknowledged) { } /** * Allows you to control the number of in flight messages that are allowed when setting {@code acknowledgedIndexReplicatedCheck}, By default, this is set to: *

* By providing a custom implementation of {@code acknowledgedIndexReplicatedCheck} you can control the number of in-flight messages that are allowed before the message is available to be read by the tailer. * And in addition, then acknowledgedIndexReplicatedCheck will be set to true. *

* below is the default implementation: *

     * boolean acknowledgedIndexReplicatedCheck(long index, long lastSequenceAck) {
     *      return index == lastSequenceAck;
     * }
     * 
*

* With this default implementation it will ensure tailer will not be able to read a message until it has been acknowledged that it has been full replicated. *

* However, if you wish to tolerate a number of in-flight or pending messages before the message., * You can set this to a different implementation. For example, if you wish to tolerate one unacknowledged message, set {@code tolerateNumberOfUnAckedMessages} to 1, as shown below: *

     * boolean acknowledgedIndexReplicatedCheck(long index, long lastSequenceAck) {
     *     int tolerateNumberOfUnAckedMessages = 1;
     *     return index <= lastSequenceAck + tolerateNumberOfUnAckedMessages;
     * }
     * 
*

* This feature is exclusive to Enterprise Queue and is disabled when accessing a queue file role. * Specifically, it's unavailable when the in-flight message originated from a cycle other than the current one. * For more information about cycles, see RollCycles and {@link RollCycle#toCycle(long)}. * * @param acknowledgedIndexReplicatedCheck as a custom implementation of {@code acknowledgedIndexReplicatedCheck} */ default void acknowledgedIndexReplicatedCheck(AcknowledgedIndexReplicatedCheck acknowledgedIndexReplicatedCheck) { throw new UnsupportedOperationException("This method is not supported by this implementation"); } /** * Returns the Read After Replica Acknowledged property of this Tailer. *

* Enterprise Queue only: if replication enabled, setting this to {@code true} on a source queue ensures that * this tailer will not read until at least one of the sinks has acknowledged receipt of the excerpt. * This will block forever if no sinks acknowledge receipt. * * @return the Read After Replica Acknowledged property of this Tailer */ default boolean readAfterReplicaAcknowledged() { return false; } /** * Returns a number of excerpts in a cycle. May use a fast path to return the cycle length cached in indexing, * which is updated last during append operation so may be possible that a single entry is available for reading * but not acknowledged by this method yet. *

* Calling this method may move ExcerptTailer to the specified cycle and release its store. * * @return the approximate number of excerpts in a cycle. * @deprecated Use {@link #excerptsInCycle(int)} instead */ @Deprecated(/* To be removed in x.27 */) default long approximateExcerptsInCycle(int cycle) { return excerptsInCycle(cycle); } /** * Returns an exact number of excerpts in a cycle available for reading. This may be a computationally * expensive operation. *

* Calling this method may move ExcerptTailer to the specified cycle and release its store. * * @return the exact number of excerpts in a cycle. * @deprecated Use {@link #excerptsInCycle(int)} instead */ @Deprecated(/* To be removed in x.27 */) default long exactExcerptsInCycle(int cycle) { return excerptsInCycle(cycle); } /** * Return the exact number of excerpts in a cycle available for reading. *

* Calling this method may move ExcerptTailer to the specified cycle and release its store. * * @return the exact number of excerpts in a cycle. */ default long excerptsInCycle(int cycle) { try (ExcerptTailer tailer = queue().createTailer()) { return tailer.excerptsInCycle(cycle); } } /** * Returns the {@link TailerState} of this Tailer. * * @return the {@link TailerState} of this Tailer */ @NotNull TailerState state(); /** * Winds this ExcerptTailer to the specified {@code index} of the provided {@code queue} and reads the history message, * then moves {@code this} tailer to the message index in the history message. * * @param queue The queue which was written to, and may contain a history message at the specified {@code index}. * Must not be null. * @param index The index to read the history message in the {@code queue}. * @return This ExcerptTailer instance. * @throws IORuntimeException if the provided {@code queue} couldn't be wound to the last index. * @throws NullPointerException if the provided {@code queue} is null. */ default @NotNull ExcerptTailer afterWrittenMessageAtIndex(@NotNull ChronicleQueue queue, long index) { throw new UnsupportedOperationException("todo"); } interface AcknowledgedIndexReplicatedCheck { /** * @param index the index of the next message for the tailer to read * @param lastSequenceAck the last index that has been acknowledged as replicated * @return true if you are ok for the tailer to read the message at {@code index} *

* NOTE: this callback is not called during a roll, * as all messages must be acknowledged before they are seen during this period. */ boolean acknowledgedIndexReplicatedCheck(long index, long lastSequenceAck); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy