Search in sources :

Example 1 with LatestConsumer

use of io.confluent.ksql.physical.scalablepush.consumer.LatestConsumer in project ksql by confluentinc.

the class ScalablePushRegistry method close.

/**
 * Called when the server is shutting down.
 */
public synchronized void close() {
    if (closed) {
        LOG.warn("Already closed registry");
        return;
    }
    LOG.info("Closing scalable push registry for topic " + ksqlTopic.getKafkaTopicName());
    final LatestConsumer latestConsumer = this.latestConsumer.get();
    if (latestConsumer != null) {
        latestConsumer.closeAsync();
    }
    for (CatchupConsumer catchupConsumer : catchupConsumers.values()) {
        catchupConsumer.closeAsync();
    }
    catchupConsumers.clear();
    MoreExecutors.shutdownAndAwaitTermination(executorService, 5000, TimeUnit.MILLISECONDS);
    MoreExecutors.shutdownAndAwaitTermination(executorServiceCatchup, 5000, TimeUnit.MILLISECONDS);
    closed = true;
}
Also used : LatestConsumer(io.confluent.ksql.physical.scalablepush.consumer.LatestConsumer) CatchupConsumer(io.confluent.ksql.physical.scalablepush.consumer.CatchupConsumer)

Example 2 with LatestConsumer

use of io.confluent.ksql.physical.scalablepush.consumer.LatestConsumer in project ksql by confluentinc.

the class ScalablePushRegistry method startLatestIfNotRunning.

/**
 * Starts the Latest consumer if it's not started already.
 * @param processingQueue The queue to register with the latest consumer
 */
private synchronized void startLatestIfNotRunning(final Optional<ProcessingQueue> processingQueue) {
    final LatestConsumer latestConsumer = this.latestConsumer.get();
    if (latestConsumer != null && !latestConsumer.isClosed()) {
        return;
    }
    final LatestConsumer newLatestConsumer = createLatestConsumer(processingQueue);
    processingQueue.ifPresent(newLatestConsumer::register);
    this.latestConsumer.set(newLatestConsumer);
    executorService.submit(() -> runLatest(newLatestConsumer));
}
Also used : LatestConsumer(io.confluent.ksql.physical.scalablepush.consumer.LatestConsumer)

Example 3 with LatestConsumer

use of io.confluent.ksql.physical.scalablepush.consumer.LatestConsumer in project ksql by confluentinc.

the class ScalablePushRegistry method register.

/**
 * Registers a ProcessingQueue with this scalable push registry so that it starts receiving
 * data as it streams in for that consumer.
 * @param processingQueue The queue to register
 * @param catchupMetadata The catchup metadata including offsets to start at
 */
public synchronized void register(final ProcessingQueue processingQueue, final Optional<CatchupMetadata> catchupMetadata) {
    if (closed) {
        throw new IllegalStateException("Shouldn't register after closing");
    }
    try {
        if (catchupMetadata.isPresent()) {
            if (catchupConsumers.size() >= ksqlConfig.getInt(KsqlConfig.KSQL_QUERY_PUSH_V2_MAX_CATCHUP_CONSUMERS)) {
                processingQueue.onError();
                throw new KsqlException("Too many catchups registered, " + KsqlConfig.KSQL_QUERY_PUSH_V2_MAX_CATCHUP_CONSUMERS + ":" + ksqlConfig.getInt(KsqlConfig.KSQL_QUERY_PUSH_V2_MAX_CATCHUP_CONSUMERS));
            }
            // Latest must be running for a catchup consumer to exist.
            startLatestIfNotRunning(Optional.empty());
            startCatchup(processingQueue, catchupMetadata.get());
        } else {
            final LatestConsumer latestConsumer = this.latestConsumer.get();
            if (latestConsumer != null && !latestConsumer.isClosed()) {
                latestConsumer.register(processingQueue);
            } else {
                // If latestConsumer is null, that means it's the first time.  If latestConsumer != null
                // but it's already closed, that means that it's stopping async, so we just let it
                // finish while creating a new one.
                startLatestIfNotRunning(Optional.of(processingQueue));
            }
        }
    } finally {
        // Make sure that if anything in the creation process throws an exception, that we stop the
        // latest if there are no existing queries.
        stopLatestConsumerOnLastRequest();
    }
}
Also used : LatestConsumer(io.confluent.ksql.physical.scalablepush.consumer.LatestConsumer) KsqlException(io.confluent.ksql.util.KsqlException)

Example 4 with LatestConsumer

use of io.confluent.ksql.physical.scalablepush.consumer.LatestConsumer in project ksql by confluentinc.

the class ScalablePushRegistry method createLatestConsumer.

/**
 * Creates the latest consumer and its underlying kafka consumer.
 * @param processingQueue The queue on which to send an error if anything goes wrong
 * @return The new LatestConsumer
 */
private LatestConsumer createLatestConsumer(final Optional<ProcessingQueue> processingQueue) {
    KafkaConsumer<Object, GenericRow> consumer = null;
    LatestConsumer latestConsumer = null;
    try {
        consumer = kafkaConsumerFactory.create(ksqlTopic, logicalSchema, serviceContext, consumerProperties, ksqlConfig, getLatestConsumerGroupId());
        latestConsumer = latestConsumerFactory.create(ksqlTopic.getKafkaTopicName(), isWindowed(), logicalSchema, consumer, catchupCoordinator, this::catchupAssignmentUpdater, ksqlConfig, Clock.systemUTC());
        return latestConsumer;
    } catch (Exception e) {
        LOG.error("Couldn't create latest consumer", e);
        processingQueue.ifPresent(ProcessingQueue::onError);
        // We're not supposed to block here, but if it fails here, hopefully it can immediately close.
        if (consumer != null) {
            consumer.close();
        }
        throw e;
    }
}
Also used : GenericRow(io.confluent.ksql.GenericRow) LatestConsumer(io.confluent.ksql.physical.scalablepush.consumer.LatestConsumer) MalformedURLException(java.net.MalformedURLException) KsqlException(io.confluent.ksql.util.KsqlException)

Example 5 with LatestConsumer

use of io.confluent.ksql.physical.scalablepush.consumer.LatestConsumer in project ksql by confluentinc.

the class ScalablePushRegistry method unregister.

/**
 * Unregisters the given ProcessingQueue when its request is complete
 * @param processingQueue The queue to deregister
 */
public synchronized void unregister(final ProcessingQueue processingQueue) {
    if (closed) {
        throw new IllegalStateException("Shouldn't unregister after closing");
    }
    try {
        final LatestConsumer latestConsumer = this.latestConsumer.get();
        if (latestConsumer != null && !latestConsumer.isClosed()) {
            latestConsumer.unregister(processingQueue);
        }
        unregisterCatchup(processingQueue);
    } finally {
        // Make sure we stop latest after any unregisters if necessary. We don't except the above to
        // throw any exceptions, but it's wrapped in a finally to be safe.
        stopLatestConsumerOnLastRequest();
    }
}
Also used : LatestConsumer(io.confluent.ksql.physical.scalablepush.consumer.LatestConsumer)

Aggregations

LatestConsumer (io.confluent.ksql.physical.scalablepush.consumer.LatestConsumer)6 GenericRow (io.confluent.ksql.GenericRow)2 CatchupConsumer (io.confluent.ksql.physical.scalablepush.consumer.CatchupConsumer)2 KsqlException (io.confluent.ksql.util.KsqlException)2 ImmutableMap (com.google.common.collect.ImmutableMap)1 SuppressFBWarnings (edu.umd.cs.findbugs.annotations.SuppressFBWarnings)1 KsqlTopic (io.confluent.ksql.execution.ddl.commands.KsqlTopic)1 ColumnName (io.confluent.ksql.name.ColumnName)1 CatchupMetadata (io.confluent.ksql.physical.scalablepush.ScalablePushRegistry.CatchupMetadata)1 CatchupConsumerFactory (io.confluent.ksql.physical.scalablepush.consumer.CatchupConsumer.CatchupConsumerFactory)1 CatchupCoordinator (io.confluent.ksql.physical.scalablepush.consumer.CatchupCoordinator)1 KafkaConsumerFactoryInterface (io.confluent.ksql.physical.scalablepush.consumer.KafkaConsumerFactory.KafkaConsumerFactoryInterface)1 LatestConsumerFactory (io.confluent.ksql.physical.scalablepush.consumer.LatestConsumer.LatestConsumerFactory)1 PushLocator (io.confluent.ksql.physical.scalablepush.locator.PushLocator)1 QueryId (io.confluent.ksql.query.QueryId)1 LogicalSchema (io.confluent.ksql.schema.ksql.LogicalSchema)1 SqlTypes (io.confluent.ksql.schema.ksql.types.SqlTypes)1 KeyFormat (io.confluent.ksql.serde.KeyFormat)1 ServiceContext (io.confluent.ksql.services.ServiceContext)1 AssertEventually.assertThatEventually (io.confluent.ksql.test.util.AssertEventually.assertThatEventually)1