Search in sources :

Example 1 with StateContextImpl

use of org.apache.pulsar.functions.instance.state.StateContextImpl in project incubator-pulsar by apache.

the class JavaInstanceRunnable method run.

/**
 * The core logic that initialize the instance thread and executes the function
 */
@Override
public void run() {
    try {
        javaInstance = setupJavaInstance();
        while (running) {
            // some src topics might be put into resubscribe list because of processing failure
            // so this is the chance to resubscribe to those topics.
            resubscribeTopicsIfNeeded();
            JavaExecutionResult result;
            InputMessage msg;
            try {
                msg = queue.take();
                log.debug("Received message: {}", msg.getActualMessage().getMessageId());
            } catch (InterruptedException ie) {
                log.info("Function thread {} is interrupted", FunctionConfigUtils.getFullyQualifiedName(instanceConfig.getFunctionConfig()), ie);
                break;
            }
            if (ProcessingGuarantees.EFFECTIVELY_ONCE == processingGuarantees) {
                // re-created for the correctness of effectively-once
                if (msg.getConsumer() != inputConsumers.get(msg.getTopicName())) {
                    continue;
                }
            }
            if (null != outputProducer) {
                // before processing the message, we have a producer connection setup for producing results.
                Producer producer = null;
                while (null == producer) {
                    try {
                        producer = outputProducer.getProducer(msg.getTopicName(), msg.getTopicPartition());
                    } catch (PulsarClientException e) {
                        // so we need to wait until the old active consumer release the produce connection.
                        if (!(e instanceof ProducerBusyException)) {
                            log.error("Failed to get a producer for producing results computed from input topic {}", msg.getTopicName());
                        }
                        TimeUnit.MILLISECONDS.sleep(500);
                    }
                }
            }
            // state object is per function, because we need to have the ability to know what updates
            // are made in this function and ensure we only acknowledge after the state is persisted.
            StateContextImpl stateContext;
            if (null != stateTable) {
                stateContext = new StateContextImpl(stateTable);
                javaInstance.getContext().setStateContext(stateContext);
            } else {
                stateContext = null;
            }
            // process the message
            Object input;
            try {
                input = msg.getInputSerDe().deserialize(msg.getActualMessage().getData());
            } catch (Exception ex) {
                stats.incrementDeserializationExceptions(msg.getTopicName());
                continue;
            }
            long processAt = System.currentTimeMillis();
            stats.incrementProcessed(processAt);
            addLogTopicHandler();
            result = javaInstance.handleMessage(msg.getActualMessage().getMessageId(), msg.getTopicName(), input);
            removeLogTopicHandler();
            long doneProcessing = System.currentTimeMillis();
            log.debug("Got result: {}", result.getResult());
            if (null != stateContext) {
                stateContext.flush().thenRun(() -> processResult(msg, result, processAt, doneProcessing)).exceptionally(cause -> {
                    // log the messages, since we DONT ack, pulsar consumer will re-deliver the messages.
                    log.error("Failed to flush the state updates of message {}", msg, cause);
                    return null;
                });
            } else {
                processResult(msg, result, processAt, doneProcessing);
            }
        }
        javaInstance.close();
    } catch (Exception ex) {
        log.info("Uncaught exception in Java Instance", ex);
        failureException = ex;
    }
}
Also used : ProducerBusyException(org.apache.pulsar.client.api.PulsarClientException.ProducerBusyException) StateContextImpl(org.apache.pulsar.functions.instance.state.StateContextImpl) NamespaceNotFoundException(org.apache.bookkeeper.clients.exceptions.NamespaceNotFoundException) ProducerBusyException(org.apache.pulsar.client.api.PulsarClientException.ProducerBusyException) StreamNotFoundException(org.apache.bookkeeper.clients.exceptions.StreamNotFoundException)

Aggregations

NamespaceNotFoundException (org.apache.bookkeeper.clients.exceptions.NamespaceNotFoundException)1 StreamNotFoundException (org.apache.bookkeeper.clients.exceptions.StreamNotFoundException)1 ProducerBusyException (org.apache.pulsar.client.api.PulsarClientException.ProducerBusyException)1 StateContextImpl (org.apache.pulsar.functions.instance.state.StateContextImpl)1