Search in sources :

Example 1 with WriterMark

use of io.pravega.controller.store.stream.records.WriterMark in project pravega by pravega.

the class ControllerMetadataJsonSerializerTest method testWriterMark.

@Test
public void testWriterMark() {
    Map<Long, Long> map = new HashMap<>();
    map.put(0L, 0L);
    map.put(1L, 0L);
    map.put(2L, 0L);
    WriterMark record = new WriterMark(100L, ImmutableMap.copyOf(map), true);
    testRecordSerialization(record, WriterMark.class);
}
Also used : WriterMark(io.pravega.controller.store.stream.records.WriterMark) HashMap(java.util.HashMap) Test(org.junit.Test)

Example 2 with WriterMark

use of io.pravega.controller.store.stream.records.WriterMark in project pravega by pravega.

the class PeriodicWatermarking method filterWritersAndComputeWatermark.

private CompletionStage<Void> filterWritersAndComputeWatermark(String scope, String streamName, OperationContext context, WatermarkClient watermarkClient, Map<String, WriterMark> writers, StreamConfiguration config) {
    // 1. filter writers that are active.
    List<Entry<String, WriterMark>> activeWriters = new ArrayList<>();
    List<Entry<String, WriterMark>> inactiveWriters = new ArrayList<>();
    AtomicBoolean allActiveAreParticipating = new AtomicBoolean(true);
    writers.entrySet().forEach(x -> {
        if (watermarkClient.isWriterActive(x, config.getTimestampAggregationTimeout())) {
            activeWriters.add(x);
            if (!watermarkClient.isWriterParticipating(x.getValue().getTimestamp())) {
                allActiveAreParticipating.set(false);
            }
        } else {
            inactiveWriters.add(x);
        }
    });
    // Stop all inactive writers that have been shutdown.
    CompletableFuture<List<Void>> removeInactiveWriters = Futures.allOfWithResults(inactiveWriters.stream().map(x -> Futures.exceptionallyExpecting(streamMetadataStore.removeWriter(scope, streamName, x.getKey(), x.getValue(), context, executor).thenAccept(v -> watermarkClient.untrackWriterInactivity(x.getKey())), e -> Exceptions.unwrap(e) instanceof StoreException.WriteConflictException, null)).collect(Collectors.toList()));
    if (activeWriters.isEmpty()) {
        // periodic processing will resume.
        return removeInactiveWriters.thenCompose(v -> bucketStore.removeStreamFromBucketStore(BucketStore.ServiceType.WatermarkingService, scope, streamName, executor));
    }
    CompletableFuture<Watermark> watermarkFuture;
    if (!allActiveAreParticipating.get()) {
        // there are active writers that have not reported their marks. We should wait
        // until they either report or become inactive. So we will complete this iteration without
        // emitting any watermark (null) and in subsequent iterations if these writers have made progress
        // we will emit watermark or evict writers from watermark computation.
        watermarkFuture = CompletableFuture.completedFuture(null);
    } else {
        // compute new mark
        watermarkFuture = computeWatermark(scope, streamName, context, activeWriters, watermarkClient.getPreviousWatermark());
    }
    // we will compute watermark and remove inactive writers concurrently
    return CompletableFuture.allOf(removeInactiveWriters, watermarkFuture.thenAccept(watermarkClient::completeIteration));
}
Also used : LoadingCache(com.google.common.cache.LoadingCache) StreamSegmentRecord(io.pravega.controller.store.stream.records.StreamSegmentRecord) LoggerFactory(org.slf4j.LoggerFactory) StreamConfiguration(io.pravega.client.stream.StreamConfiguration) ParametersAreNonnullByDefault(javax.annotation.ParametersAreNonnullByDefault) TagLogger(io.pravega.common.tracing.TagLogger) StoreException(io.pravega.controller.store.stream.StoreException) Stream(io.pravega.client.stream.Stream) Map(java.util.Map) SegmentWithRange(io.pravega.shared.watermarks.SegmentWithRange) Synchronized(lombok.Synchronized) WatermarkSerializer(io.pravega.client.watermark.WatermarkSerializer) ImmutableMap(com.google.common.collect.ImmutableMap) NoSuchSegmentException(io.pravega.client.segment.impl.NoSuchSegmentException) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) RequestTracker(io.pravega.common.tracing.RequestTracker) Collectors(java.util.stream.Collectors) CacheLoader(com.google.common.cache.CacheLoader) List(java.util.List) CompletionStage(java.util.concurrent.CompletionStage) Entry(java.util.Map.Entry) CacheBuilder(com.google.common.cache.CacheBuilder) StreamMetadataStore(io.pravega.controller.store.stream.StreamMetadataStore) Futures(io.pravega.common.concurrent.Futures) OperationContext(io.pravega.controller.store.stream.OperationContext) Exceptions(io.pravega.common.Exceptions) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) BucketStore(io.pravega.controller.store.stream.BucketStore) Lists(com.google.common.collect.Lists) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) RevisionedStreamClient(io.pravega.client.state.RevisionedStreamClient) SynchronizerConfig(io.pravega.client.state.SynchronizerConfig) LongSummaryStatistics(java.util.LongSummaryStatistics) NameUtils(io.pravega.shared.NameUtils) WriterMark(io.pravega.controller.store.stream.records.WriterMark) Watermark(io.pravega.shared.watermarks.Watermark) TimeUnit(java.util.concurrent.TimeUnit) EpochRecord(io.pravega.controller.store.stream.records.EpochRecord) SynchronizerClientFactory(io.pravega.client.SynchronizerClientFactory) Closeable(java.io.Closeable) Revision(io.pravega.client.state.Revision) RemovalListener(com.google.common.cache.RemovalListener) VisibleForTesting(com.google.common.annotations.VisibleForTesting) RandomFactory(io.pravega.common.hash.RandomFactory) Comparator(java.util.Comparator) Collections(java.util.Collections) ClientConfig(io.pravega.client.ClientConfig) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Entry(java.util.Map.Entry) ArrayList(java.util.ArrayList) List(java.util.List) ArrayList(java.util.ArrayList) Watermark(io.pravega.shared.watermarks.Watermark)

Example 3 with WriterMark

use of io.pravega.controller.store.stream.records.WriterMark in project pravega by pravega.

the class PravegaTablesStream method updateWriterMarkRecord.

@Override
CompletableFuture<Void> updateWriterMarkRecord(String writer, long timestamp, ImmutableMap<Long, Long> position, boolean isAlive, Version version, OperationContext context) {
    Preconditions.checkNotNull(context, "operation context cannot be null");
    WriterMark mark = new WriterMark(timestamp, position, isAlive);
    return Futures.toVoid(getWritersTable(context).thenCompose(table -> storeHelper.updateEntry(table, writer, mark, WriterMark::toBytes, version, context.getRequestId())));
}
Also used : DATA_NOT_EMPTY_PREDICATE(io.pravega.controller.store.stream.AbstractStreamMetadataStore.DATA_NOT_EMPTY_PREDICATE) BiFunction(java.util.function.BiFunction) LoggerFactory(org.slf4j.LoggerFactory) NameUtils.getQualifiedTableName(io.pravega.shared.NameUtils.getQualifiedTableName) COMPLETED_TRANSACTIONS_BATCHES_TABLE(io.pravega.shared.NameUtils.COMPLETED_TRANSACTIONS_BATCHES_TABLE) StreamConfiguration(io.pravega.client.stream.StreamConfiguration) ByteBuffer(java.nio.ByteBuffer) TagLogger(io.pravega.common.tracing.TagLogger) VersionedMetadata(io.pravega.controller.store.VersionedMetadata) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SEPARATOR(io.pravega.shared.NameUtils.SEPARATOR) Map(java.util.Map) CONFIGURATION_KEY(io.pravega.shared.NameUtils.CONFIGURATION_KEY) EpochTransitionRecord(io.pravega.controller.store.stream.records.EpochTransitionRecord) Subscribers(io.pravega.controller.store.stream.records.Subscribers) StreamTruncationRecord(io.pravega.controller.store.stream.records.StreamTruncationRecord) ImmutableMap(com.google.common.collect.ImmutableMap) Predicate(java.util.function.Predicate) BYTES_TO_UUID_FUNCTION(io.pravega.controller.store.PravegaTablesStoreHelper.BYTES_TO_UUID_FUNCTION) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) WRITERS_POSITIONS_TABLE(io.pravega.shared.NameUtils.WRITERS_POSITIONS_TABLE) CompletionException(java.util.concurrent.CompletionException) ActiveTxnRecord(io.pravega.controller.store.stream.records.ActiveTxnRecord) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) Objects(java.util.Objects) List(java.util.List) BYTES_TO_INTEGER_FUNCTION(io.pravega.controller.store.PravegaTablesStoreHelper.BYTES_TO_INTEGER_FUNCTION) Optional(java.util.Optional) HistoryTimeSeries(io.pravega.controller.store.stream.records.HistoryTimeSeries) Futures(io.pravega.common.concurrent.Futures) LONG_TO_BYTES_FUNCTION(io.pravega.controller.store.PravegaTablesStoreHelper.LONG_TO_BYTES_FUNCTION) EPOCH_TRANSITION_KEY(io.pravega.shared.NameUtils.EPOCH_TRANSITION_KEY) CompletedTxnRecord(io.pravega.controller.store.stream.records.CompletedTxnRecord) CommittingTransactionsRecord(io.pravega.controller.store.stream.records.CommittingTransactionsRecord) RETENTION_SET_KEY(io.pravega.shared.NameUtils.RETENTION_SET_KEY) Exceptions(io.pravega.common.Exceptions) EPOCH_RECORD_KEY_FORMAT(io.pravega.shared.NameUtils.EPOCH_RECORD_KEY_FORMAT) WAITING_REQUEST_PROCESSOR_PATH(io.pravega.shared.NameUtils.WAITING_REQUEST_PROCESSOR_PATH) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) DATA_NOT_FOUND_PREDICATE(io.pravega.controller.store.stream.PravegaTablesStreamMetadataStore.DATA_NOT_FOUND_PREDICATE) COMMITTING_TRANSACTIONS_RECORD_KEY(io.pravega.shared.NameUtils.COMMITTING_TRANSACTIONS_RECORD_KEY) RetentionSet(io.pravega.controller.store.stream.records.RetentionSet) SUBSCRIBER_KEY_PREFIX(io.pravega.shared.NameUtils.SUBSCRIBER_KEY_PREFIX) AtomicReference(java.util.concurrent.atomic.AtomicReference) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) CURRENT_EPOCH_KEY(io.pravega.shared.NameUtils.CURRENT_EPOCH_KEY) Strings(com.google.common.base.Strings) HISTORY_TIMESERIES_CHUNK_FORMAT(io.pravega.shared.NameUtils.HISTORY_TIMESERIES_CHUNK_FORMAT) TRANSACTIONS_IN_EPOCH_TABLE_FORMAT(io.pravega.shared.NameUtils.TRANSACTIONS_IN_EPOCH_TABLE_FORMAT) StateRecord(io.pravega.controller.store.stream.records.StateRecord) BYTES_TO_LONG_FUNCTION(io.pravega.controller.store.PravegaTablesStoreHelper.BYTES_TO_LONG_FUNCTION) SEGMENT_MARKER_PATH_FORMAT(io.pravega.shared.NameUtils.SEGMENT_MARKER_PATH_FORMAT) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) StreamSubscriber(io.pravega.controller.store.stream.records.StreamSubscriber) SEGMENTS_SEALED_SIZE_MAP_SHARD_FORMAT(io.pravega.shared.NameUtils.SEGMENTS_SEALED_SIZE_MAP_SHARD_FORMAT) INTEGER_TO_BYTES_FUNCTION(io.pravega.controller.store.PravegaTablesStoreHelper.INTEGER_TO_BYTES_FUNCTION) SealedSegmentsMapShard(io.pravega.controller.store.stream.records.SealedSegmentsMapShard) METADATA_TABLE(io.pravega.shared.NameUtils.METADATA_TABLE) STATE_KEY(io.pravega.shared.NameUtils.STATE_KEY) EPOCHS_WITH_TRANSACTIONS_TABLE(io.pravega.shared.NameUtils.EPOCHS_WITH_TRANSACTIONS_TABLE) WriterMark(io.pravega.controller.store.stream.records.WriterMark) StreamCutRecord(io.pravega.controller.store.stream.records.StreamCutRecord) TRUNCATION_KEY(io.pravega.shared.NameUtils.TRUNCATION_KEY) INTERNAL_SCOPE_NAME(io.pravega.shared.NameUtils.INTERNAL_SCOPE_NAME) StreamConfigurationRecord(io.pravega.controller.store.stream.records.StreamConfigurationRecord) AbstractMap(java.util.AbstractMap) EpochRecord(io.pravega.controller.store.stream.records.EpochRecord) Version(io.pravega.controller.store.Version) COMPLETED_TRANSACTIONS_BATCH_TABLE_FORMAT(io.pravega.shared.NameUtils.COMPLETED_TRANSACTIONS_BATCH_TABLE_FORMAT) PravegaTablesStoreHelper(io.pravega.controller.store.PravegaTablesStoreHelper) CREATION_TIME_KEY(io.pravega.shared.NameUtils.CREATION_TIME_KEY) SUBSCRIBER_SET_KEY(io.pravega.shared.NameUtils.SUBSCRIBER_SET_KEY) Preconditions(com.google.common.base.Preconditions) VisibleForTesting(com.google.common.annotations.VisibleForTesting) RETENTION_STREAM_CUT_RECORD_KEY_FORMAT(io.pravega.shared.NameUtils.RETENTION_STREAM_CUT_RECORD_KEY_FORMAT) Collections(java.util.Collections) SEGMENT_SEALED_EPOCH_KEY_FORMAT(io.pravega.shared.NameUtils.SEGMENT_SEALED_EPOCH_KEY_FORMAT) WriterMark(io.pravega.controller.store.stream.records.WriterMark)

Example 4 with WriterMark

use of io.pravega.controller.store.stream.records.WriterMark in project pravega by pravega.

the class PravegaTablesStream method createWriterMarkRecord.

@Override
CompletableFuture<Void> createWriterMarkRecord(String writer, long timestamp, ImmutableMap<Long, Long> position, OperationContext context) {
    Preconditions.checkNotNull(context, "operation context cannot be null");
    WriterMark mark = new WriterMark(timestamp, position);
    return Futures.toVoid(getWritersTable(context).thenCompose(table -> storeHelper.addNewEntry(table, writer, mark, WriterMark::toBytes, context.getRequestId())));
}
Also used : DATA_NOT_EMPTY_PREDICATE(io.pravega.controller.store.stream.AbstractStreamMetadataStore.DATA_NOT_EMPTY_PREDICATE) BiFunction(java.util.function.BiFunction) LoggerFactory(org.slf4j.LoggerFactory) NameUtils.getQualifiedTableName(io.pravega.shared.NameUtils.getQualifiedTableName) COMPLETED_TRANSACTIONS_BATCHES_TABLE(io.pravega.shared.NameUtils.COMPLETED_TRANSACTIONS_BATCHES_TABLE) StreamConfiguration(io.pravega.client.stream.StreamConfiguration) ByteBuffer(java.nio.ByteBuffer) TagLogger(io.pravega.common.tracing.TagLogger) VersionedMetadata(io.pravega.controller.store.VersionedMetadata) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SEPARATOR(io.pravega.shared.NameUtils.SEPARATOR) Map(java.util.Map) CONFIGURATION_KEY(io.pravega.shared.NameUtils.CONFIGURATION_KEY) EpochTransitionRecord(io.pravega.controller.store.stream.records.EpochTransitionRecord) Subscribers(io.pravega.controller.store.stream.records.Subscribers) StreamTruncationRecord(io.pravega.controller.store.stream.records.StreamTruncationRecord) ImmutableMap(com.google.common.collect.ImmutableMap) Predicate(java.util.function.Predicate) BYTES_TO_UUID_FUNCTION(io.pravega.controller.store.PravegaTablesStoreHelper.BYTES_TO_UUID_FUNCTION) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) WRITERS_POSITIONS_TABLE(io.pravega.shared.NameUtils.WRITERS_POSITIONS_TABLE) CompletionException(java.util.concurrent.CompletionException) ActiveTxnRecord(io.pravega.controller.store.stream.records.ActiveTxnRecord) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) Objects(java.util.Objects) List(java.util.List) BYTES_TO_INTEGER_FUNCTION(io.pravega.controller.store.PravegaTablesStoreHelper.BYTES_TO_INTEGER_FUNCTION) Optional(java.util.Optional) HistoryTimeSeries(io.pravega.controller.store.stream.records.HistoryTimeSeries) Futures(io.pravega.common.concurrent.Futures) LONG_TO_BYTES_FUNCTION(io.pravega.controller.store.PravegaTablesStoreHelper.LONG_TO_BYTES_FUNCTION) EPOCH_TRANSITION_KEY(io.pravega.shared.NameUtils.EPOCH_TRANSITION_KEY) CompletedTxnRecord(io.pravega.controller.store.stream.records.CompletedTxnRecord) CommittingTransactionsRecord(io.pravega.controller.store.stream.records.CommittingTransactionsRecord) RETENTION_SET_KEY(io.pravega.shared.NameUtils.RETENTION_SET_KEY) Exceptions(io.pravega.common.Exceptions) EPOCH_RECORD_KEY_FORMAT(io.pravega.shared.NameUtils.EPOCH_RECORD_KEY_FORMAT) WAITING_REQUEST_PROCESSOR_PATH(io.pravega.shared.NameUtils.WAITING_REQUEST_PROCESSOR_PATH) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) DATA_NOT_FOUND_PREDICATE(io.pravega.controller.store.stream.PravegaTablesStreamMetadataStore.DATA_NOT_FOUND_PREDICATE) COMMITTING_TRANSACTIONS_RECORD_KEY(io.pravega.shared.NameUtils.COMMITTING_TRANSACTIONS_RECORD_KEY) RetentionSet(io.pravega.controller.store.stream.records.RetentionSet) SUBSCRIBER_KEY_PREFIX(io.pravega.shared.NameUtils.SUBSCRIBER_KEY_PREFIX) AtomicReference(java.util.concurrent.atomic.AtomicReference) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) CURRENT_EPOCH_KEY(io.pravega.shared.NameUtils.CURRENT_EPOCH_KEY) Strings(com.google.common.base.Strings) HISTORY_TIMESERIES_CHUNK_FORMAT(io.pravega.shared.NameUtils.HISTORY_TIMESERIES_CHUNK_FORMAT) TRANSACTIONS_IN_EPOCH_TABLE_FORMAT(io.pravega.shared.NameUtils.TRANSACTIONS_IN_EPOCH_TABLE_FORMAT) StateRecord(io.pravega.controller.store.stream.records.StateRecord) BYTES_TO_LONG_FUNCTION(io.pravega.controller.store.PravegaTablesStoreHelper.BYTES_TO_LONG_FUNCTION) SEGMENT_MARKER_PATH_FORMAT(io.pravega.shared.NameUtils.SEGMENT_MARKER_PATH_FORMAT) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) StreamSubscriber(io.pravega.controller.store.stream.records.StreamSubscriber) SEGMENTS_SEALED_SIZE_MAP_SHARD_FORMAT(io.pravega.shared.NameUtils.SEGMENTS_SEALED_SIZE_MAP_SHARD_FORMAT) INTEGER_TO_BYTES_FUNCTION(io.pravega.controller.store.PravegaTablesStoreHelper.INTEGER_TO_BYTES_FUNCTION) SealedSegmentsMapShard(io.pravega.controller.store.stream.records.SealedSegmentsMapShard) METADATA_TABLE(io.pravega.shared.NameUtils.METADATA_TABLE) STATE_KEY(io.pravega.shared.NameUtils.STATE_KEY) EPOCHS_WITH_TRANSACTIONS_TABLE(io.pravega.shared.NameUtils.EPOCHS_WITH_TRANSACTIONS_TABLE) WriterMark(io.pravega.controller.store.stream.records.WriterMark) StreamCutRecord(io.pravega.controller.store.stream.records.StreamCutRecord) TRUNCATION_KEY(io.pravega.shared.NameUtils.TRUNCATION_KEY) INTERNAL_SCOPE_NAME(io.pravega.shared.NameUtils.INTERNAL_SCOPE_NAME) StreamConfigurationRecord(io.pravega.controller.store.stream.records.StreamConfigurationRecord) AbstractMap(java.util.AbstractMap) EpochRecord(io.pravega.controller.store.stream.records.EpochRecord) Version(io.pravega.controller.store.Version) COMPLETED_TRANSACTIONS_BATCH_TABLE_FORMAT(io.pravega.shared.NameUtils.COMPLETED_TRANSACTIONS_BATCH_TABLE_FORMAT) PravegaTablesStoreHelper(io.pravega.controller.store.PravegaTablesStoreHelper) CREATION_TIME_KEY(io.pravega.shared.NameUtils.CREATION_TIME_KEY) SUBSCRIBER_SET_KEY(io.pravega.shared.NameUtils.SUBSCRIBER_SET_KEY) Preconditions(com.google.common.base.Preconditions) VisibleForTesting(com.google.common.annotations.VisibleForTesting) RETENTION_STREAM_CUT_RECORD_KEY_FORMAT(io.pravega.shared.NameUtils.RETENTION_STREAM_CUT_RECORD_KEY_FORMAT) Collections(java.util.Collections) SEGMENT_SEALED_EPOCH_KEY_FORMAT(io.pravega.shared.NameUtils.SEGMENT_SEALED_EPOCH_KEY_FORMAT) WriterMark(io.pravega.controller.store.stream.records.WriterMark)

Example 5 with WriterMark

use of io.pravega.controller.store.stream.records.WriterMark in project pravega by pravega.

the class WatermarkWorkflowTest method testWatermarkClient.

@Test(timeout = 10000L)
public void testWatermarkClient() {
    Stream stream = new StreamImpl("scope", "stream");
    SynchronizerClientFactory clientFactory = spy(SynchronizerClientFactory.class);
    @Cleanup MockRevisionedStreamClient revisionedClient = new MockRevisionedStreamClient();
    doAnswer(x -> revisionedClient).when(clientFactory).createRevisionedStreamClient(anyString(), any(), any());
    @Cleanup PeriodicWatermarking.WatermarkClient client = new PeriodicWatermarking.WatermarkClient(stream, clientFactory);
    // iteration 1 ==> null -> w1
    client.reinitialize();
    // There is no watermark in the stream. All values should be null and all writers active and participating.
    assertEquals(revisionedClient.getMark(), MockRevision.EMPTY);
    assertTrue(revisionedClient.watermarks.isEmpty());
    assertEquals(client.getPreviousWatermark(), Watermark.EMPTY);
    Map.Entry<String, WriterMark> entry0 = new AbstractMap.SimpleEntry<>("writerId", new WriterMark(0L, ImmutableMap.of()));
    Map.Entry<String, WriterMark> entry1 = new AbstractMap.SimpleEntry<>("writerId", new WriterMark(1L, ImmutableMap.of()));
    Map.Entry<String, WriterMark> entry2 = new AbstractMap.SimpleEntry<>("writerId", new WriterMark(2L, ImmutableMap.of()));
    Map.Entry<String, WriterMark> entry3 = new AbstractMap.SimpleEntry<>("writerId", new WriterMark(3L, ImmutableMap.of()));
    Map.Entry<String, WriterMark> entry4 = new AbstractMap.SimpleEntry<>("writerId", new WriterMark(4L, ImmutableMap.of()));
    Map.Entry<String, WriterMark> entry5 = new AbstractMap.SimpleEntry<>("writerId", new WriterMark(5L, ImmutableMap.of()));
    assertTrue(client.isWriterActive(entry0, 0L));
    assertTrue(client.isWriterParticipating(0L));
    Watermark first = new Watermark(1L, 2L, ImmutableMap.of());
    client.completeIteration(first);
    // iteration 2 : do not emit ==> w1 -> w1
    client.reinitialize();
    // There is one watermark. All writers should be active and writers greater than last watermark should be participating
    assertEquals(revisionedClient.getMark(), MockRevision.EMPTY);
    assertEquals(revisionedClient.watermarks.size(), 1);
    assertEquals(client.getPreviousWatermark(), first);
    assertTrue(client.isWriterActive(entry2, 0L));
    assertFalse(client.isWriterActive(entry1, 0L));
    assertTrue(client.isWriterTracked(entry1.getKey()));
    assertFalse(client.isWriterParticipating(1L));
    assertTrue(client.isWriterParticipating(2L));
    // dont emit a watermark. Everything stays same as before.
    client.completeIteration(null);
    // iteration 3 : emit ==> w1 -> w1 w2
    client.reinitialize();
    // There is one watermark. All writers should be active and writers greater than last watermark should be participating
    assertEquals(revisionedClient.getMark(), MockRevision.EMPTY);
    assertEquals(revisionedClient.watermarks.size(), 1);
    assertEquals(client.getPreviousWatermark(), first);
    assertTrue(client.isWriterActive(entry2, 0L));
    assertFalse(client.isWriterParticipating(1L));
    assertTrue(client.isWriterParticipating(2L));
    // emit second watermark
    Watermark second = new Watermark(2L, 3L, ImmutableMap.of());
    client.completeIteration(second);
    // iteration 4: do not emit ==> w1 w2 -> w1 w2
    client.reinitialize();
    assertEquals(revisionedClient.getMark(), revisionedClient.watermarks.get(0).getKey());
    assertEquals(2, revisionedClient.watermarks.size());
    assertEquals(client.getPreviousWatermark(), second);
    assertFalse(client.isWriterActive(entry2, 0L));
    assertTrue(client.isWriterTracked(entry2.getKey()));
    assertTrue(client.isWriterActive(entry3, 0L));
    assertFalse(client.isWriterParticipating(2L));
    assertTrue(client.isWriterParticipating(3L));
    assertTrue(client.isWriterActive(entry0, 1000L));
    assertTrue(client.isWriterTracked(entry0.getKey()));
    // dont emit a watermark but complete this iteration.
    client.completeIteration(null);
    // iteration 6: emit ==> w1 w2 -> w1 w2 w3
    client.reinitialize();
    assertEquals(revisionedClient.getMark(), revisionedClient.watermarks.get(0).getKey());
    assertEquals(2, revisionedClient.watermarks.size());
    assertEquals(client.getPreviousWatermark(), second);
    assertTrue(client.isWriterActive(entry3, 0L));
    assertFalse(client.isWriterTracked(entry3.getKey()));
    assertFalse(client.isWriterParticipating(2L));
    assertTrue(client.isWriterParticipating(3L));
    // emit third watermark
    Watermark third = new Watermark(3L, 4L, ImmutableMap.of());
    client.completeIteration(third);
    // iteration 7: do not emit ==> w1 w2 w3 -> w1 w2 w3
    client.reinitialize();
    // active writers should be ahead of first watermark. participating writers should be ahead of second watermark
    assertEquals(revisionedClient.getMark(), revisionedClient.watermarks.get(1).getKey());
    assertEquals(3, revisionedClient.watermarks.size());
    assertEquals(client.getPreviousWatermark(), third);
    assertFalse(client.isWriterActive(entry3, 0L));
    assertTrue(client.isWriterActive(entry4, 0L));
    assertFalse(client.isWriterParticipating(3L));
    assertTrue(client.isWriterParticipating(4L));
    client.completeIteration(null);
    // iteration 8 : emit ==> w2 w3 -> w2 w3 w4
    client.reinitialize();
    assertEquals(revisionedClient.getMark(), revisionedClient.watermarks.get(1).getKey());
    // window = w2 w3
    assertEquals(revisionedClient.watermarks.size(), 3);
    assertEquals(client.getPreviousWatermark(), third);
    assertFalse(client.isWriterActive(entry3, 0L));
    assertTrue(client.isWriterActive(entry4, 0L));
    assertFalse(client.isWriterParticipating(3L));
    assertTrue(client.isWriterParticipating(4L));
    // emit fourth watermark
    Watermark fourth = new Watermark(4L, 5L, ImmutableMap.of());
    client.completeIteration(fourth);
    // iteration 9: do not emit ==> w1 w2 w3 w4 -> w1 w2 w3 w4.. check writer timeout
    client.reinitialize();
    assertEquals(revisionedClient.getMark(), revisionedClient.watermarks.get(2).getKey());
    assertEquals(revisionedClient.watermarks.size(), 4);
    assertEquals(client.getPreviousWatermark(), fourth);
    assertFalse(client.isWriterActive(entry3, 0L));
    assertTrue(client.isWriterTracked(entry4.getKey()));
    assertFalse(client.isWriterParticipating(4L));
    assertTrue(client.isWriterParticipating(5L));
    // verify that writer is active if we specify a higher timeout
    assertTrue(client.isWriterActive(entry1, 1000L));
    assertTrue(client.isWriterTracked(entry1.getKey()));
    // now that the writer is being tracked
    assertFalse(Futures.delayedTask(() -> client.isWriterActive(entry1, 1L), Duration.ofSeconds(1), executor).join());
    assertTrue(client.isWriterTracked(entry1.getKey()));
    // dont emit a watermark but complete this iteration. This should shrink the window again.
    client.completeIteration(null);
    // iteration 10
    client.reinitialize();
    assertEquals(revisionedClient.getMark(), revisionedClient.watermarks.get(2).getKey());
    assertEquals(revisionedClient.watermarks.size(), 4);
    assertEquals(client.getPreviousWatermark(), fourth);
    assertFalse(client.isWriterActive(entry4, 0L));
    assertTrue(client.isWriterActive(entry5, 0L));
    assertFalse(client.isWriterParticipating(4L));
    assertTrue(client.isWriterParticipating(5L));
}
Also used : WriterMark(io.pravega.controller.store.stream.records.WriterMark) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) Cleanup(lombok.Cleanup) SynchronizerClientFactory(io.pravega.client.SynchronizerClientFactory) StreamImpl(io.pravega.client.stream.impl.StreamImpl) Stream(io.pravega.client.stream.Stream) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) AbstractMap(java.util.AbstractMap) Watermark(io.pravega.shared.watermarks.Watermark) Test(org.junit.Test)

Aggregations

WriterMark (io.pravega.controller.store.stream.records.WriterMark)16 Test (org.junit.Test)9 StreamConfiguration (io.pravega.client.stream.StreamConfiguration)7 ImmutableMap (com.google.common.collect.ImmutableMap)6 HashMap (java.util.HashMap)6 VisibleForTesting (com.google.common.annotations.VisibleForTesting)5 SynchronizerClientFactory (io.pravega.client.SynchronizerClientFactory)5 Exceptions (io.pravega.common.Exceptions)5 Futures (io.pravega.common.concurrent.Futures)5 TagLogger (io.pravega.common.tracing.TagLogger)5 EpochRecord (io.pravega.controller.store.stream.records.EpochRecord)5 Watermark (io.pravega.shared.watermarks.Watermark)5 ArrayList (java.util.ArrayList)5 Collections (java.util.Collections)5 List (java.util.List)5 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)5 Stream (io.pravega.client.stream.Stream)4 RequestTracker (io.pravega.common.tracing.RequestTracker)4 Map (java.util.Map)4 UUID (java.util.UUID)4