ibessonov commented on code in PR #5670: URL: https://github.com/apache/ignite-3/pull/5670#discussion_r2054574123
########## modules/metastorage/src/main/java/org/apache/ignite/internal/metastorage/server/ReadOperationForCompactionTracker.java: ########## @@ -48,56 +50,82 @@ public class ReadOperationForCompactionTracker { private final AtomicLong longOperationIdGenerator = new AtomicLong(); - /** Generates the next read operation ID. Thread-safe. */ - public long generateReadOperationId() { - return longOperationIdGenerator.getAndIncrement(); + /** + * Token to stop tracking the read operation. + * + * @see #track(long, LongSupplier, LongSupplier) + */ + @FunctionalInterface + public interface TrackingToken extends AutoCloseable { + @Override + void close(); } /** * Starts tracking the completion of a read operation on its lowest estimation for revision upper bound. * - * <p>Method is expected not to be called more than once for the same arguments.</p> - * * <p>Expected usage pattern:</p> * <pre><code> - * Object readOperationId = ...; * int operationRevision = ...; * - * tracker.track(readOperationId, operationRevision); - * - * try { + * try (var token = tracker.track(operationRevision, storage::revision, storage::getCompactionRevision)) { * doReadOperation(...); - * } finally { - * tracker.untrack(readOperationId, operationRevision); * } * </code></pre> * - * @see #untrack(Object, long) + * @see TrackingToken */ - public void track(Object readOperationId, long operationRevision) { - var key = new ReadOperationKey(readOperationId, operationRevision); + public TrackingToken track( + long operationRevision, LongSupplier latestRevision, LongSupplier compactedRevision + ) throws CompactedException { + long operationId = longOperationIdGenerator.getAndIncrement(); + + while (true) { + // "operationRevision" parameter is immutable, because we might need it on a next iteration. + // If it is asked to track the latest revision, we receive it right here from the corresponding supplier. + long currentOperationRevision = operationRevision == MetaStorageManager.LATEST_REVISION + ? latestRevision.getAsLong() + : operationRevision; + + // Value from compacted revision supplier can only grow. We only use it for upper bound checks, so it's safe to read it every + // time instead of caching it. It applies to all usages of the supplier. + if (currentOperationRevision <= compactedRevision.getAsLong()) { + // Latest revision can never be compacted. If for some reason it already is, we should retry until it is not. Review Comment: I'll rephrase that -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: notifications-unsubscr...@ignite.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org