Package io.debezium.embedded.async
Class AsyncEmbeddedEngine<R>
java.lang.Object
io.debezium.embedded.async.AsyncEmbeddedEngine<R>
- All Implemented Interfaces:
AsyncEngineConfig,EmbeddedEngineConfig,io.debezium.engine.DebeziumEngine<R>,Closeable,AutoCloseable,Runnable
public final class AsyncEmbeddedEngine<R>
extends Object
implements io.debezium.engine.DebeziumEngine<R>, AsyncEngineConfig
Implementation of
DebeziumEngine which allows to run multiple tasks in parallel and also
allows to process part or whole record processing pipeline in parallel.
For more detail see DDD-7 (TODO link).- Author:
- vjuranek
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final classImplementation ofDebeziumEngine.Builderwhich createsAsyncEmbeddedEngine.private classImplementation ofDebeziumEngine.RecordCommitterwhich convert records toSourceRecords and pass them toAsyncEmbeddedEngine.SourceRecordCommitter.private static classDefault completion callback which just logs the error.private static classCallablewhich in the loop polls the connector for the records.private static enumEnum with possible placeholders for number of cores to be used record processing.private static enumDetermines how the records will be processed.private static classThe default implementation ofDebeziumEngine.RecordCommitter.private static enumPossible engine states.Nested classes/interfaces inherited from interface io.debezium.engine.DebeziumEngine
io.debezium.engine.DebeziumEngine.Builder<R extends Object>, io.debezium.engine.DebeziumEngine.BuilderFactory, io.debezium.engine.DebeziumEngine.ChangeConsumer<R extends Object>, io.debezium.engine.DebeziumEngine.CompletionCallback, io.debezium.engine.DebeziumEngine.ConnectorCallback, io.debezium.engine.DebeziumEngine.Offsets, io.debezium.engine.DebeziumEngine.RecordCommitter<R extends Object> -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate final ClassLoaderprivate final Clockprivate final io.debezium.engine.DebeziumEngine.CompletionCallbackprivate final Configurationprivate final EngineSourceConnectorprivate final Optional<io.debezium.engine.DebeziumEngine.ConnectorCallback>private final io.debezium.engine.DebeziumEngine.ChangeConsumer<R>private final org.apache.kafka.connect.storage.HeaderConverterprivate static final org.slf4j.Loggerprivate final io.debezium.engine.spi.OffsetCommitPolicyprivate final org.apache.kafka.connect.storage.Converterprivate final org.apache.kafka.connect.storage.Converterprivate final ExecutorServiceprivate final CountDownLatchprivate final AtomicReference<AsyncEmbeddedEngine.State>private final List<EngineSourceTask>private final ExecutorServiceprivate final Transformationsprivate final org.apache.kafka.connect.runtime.WorkerConfigFields inherited from interface io.debezium.embedded.async.AsyncEngineConfig
ALL_FIELDS, AVAILABLE_CORES, RECORD_PROCESSING_ORDER, RECORD_PROCESSING_SHUTDOWN_TIMEOUT_MS, RECORD_PROCESSING_THREADS, RECORD_PROCESSING_THREADS_CAP, RECORD_PROCESSING_WITH_SERIAL_CONSUMER, TASK_MANAGEMENT_TIMEOUT_MSFields inherited from interface io.debezium.engine.DebeziumEngine
OFFSET_FLUSH_INTERVAL_MS_PROPFields inherited from interface io.debezium.embedded.EmbeddedEngineConfig
CONNECTOR_CLASS, CONNECTOR_FIELDS, DEFAULT_ERROR_MAX_RETRIES, ENGINE_NAME, ERRORS_MAX_RETRIES, ERRORS_RETRY_DELAY_INITIAL_MS, ERRORS_RETRY_DELAY_MAX_MS, OFFSET_COMMIT_POLICY, OFFSET_COMMIT_TIMEOUT_MS, OFFSET_FLUSH_INTERVAL_MS, OFFSET_STORAGE, OFFSET_STORAGE_FILE_FILENAME, OFFSET_STORAGE_KAFKA_PARTITIONS, OFFSET_STORAGE_KAFKA_REPLICATION_FACTOR, OFFSET_STORAGE_KAFKA_TOPIC, PREDICATES, TRANSFORMS, WAIT_FOR_COMPLETION_BEFORE_INTERRUPT_MS -
Constructor Summary
ConstructorsModifierConstructorDescriptionprivateAsyncEmbeddedEngine(Properties config, Consumer<R> consumer, io.debezium.engine.DebeziumEngine.ChangeConsumer<R> handler, ClassLoader classLoader, Clock clock, io.debezium.engine.DebeziumEngine.CompletionCallback completionCallback, io.debezium.engine.DebeziumEngine.ConnectorCallback connectorCallback, io.debezium.engine.spi.OffsetCommitPolicy offsetCommitPolicy, org.apache.kafka.connect.storage.HeaderConverter headerConverter, Function<org.apache.kafka.connect.source.SourceRecord, R> recordConverter) -
Method Summary
Modifier and TypeMethodDescriptionprivate static io.debezium.engine.DebeziumEngine.ChangeConsumerbuildConvertingChangeConsumer(Consumer consumer, Function<org.apache.kafka.connect.source.SourceRecord, ?> recordConverter) private static io.debezium.engine.DebeziumEngine.ChangeConsumer<org.apache.kafka.connect.source.SourceRecord>buildDefaultChangeConsumer(Consumer<org.apache.kafka.connect.source.SourceRecord> consumer) Build the defaultDebeziumEngine.ChangeConsumerfrom provided customConsumer.private voidcallCompletionHandler(Throwable error) Calls provided implementation ofDebeziumEngine.CompletionCallback.voidclose()private voidclose(AsyncEmbeddedEngine.State stateBeforeStop) Shuts down the engine.private voidcloseEngineWithException(Throwable exitError) Stops engine if needed upon the failure.private static booleancommitOffsets(org.apache.kafka.connect.storage.OffsetStorageWriter offsetWriter, Clock clock, long commitTimeout, org.apache.kafka.connect.source.SourceTask task) Commits the offset toOffsetBackingStoreviaOffsetStorageWriter.private intcomputeRecordThreads(String recordProcessingThreads) Determines the size of the thread pool which will be used for processing records.private org.apache.kafka.connect.storage.OffsetBackingStorecreateAndStartOffsetStore(Map<String, String> connectorConfig) Determines which offset backing store should be used, instantiate it and starts the offset store.private RecordProcessorcreateRecordProcessor(String processorClassName, EngineSourceTask task) InstantiateRecordProcessorbased on the class name deremined inselectRecordProcessor()method.private voidcreateSourceTasks(EngineSourceConnector connector, List<EngineSourceTask> tasks) Creates list of connector tasks to be started as the sources of records.private voidfinishShutDown(Throwable exitError) Finish engine shut down - move it intoSTOPPEDstate and call the completion callback.private AsyncEmbeddedEngine.StateGets the current state of the engine.Initialize all the required pieces for initialization of the connector and returns configuration of the connector.voidrun()private voidrunTasksPolling(List<EngineSourceTask> tasks) Schedules polling of provided tasks and wait until all polling tasks eventually finish.voidrunWithTask(Consumer<org.apache.kafka.connect.source.SourceTask> consumer) For backward compatibility with tests and for testing purposes ONLY.private StringSelectRecordProcessorclass based on the user configuration.private voidsetEngineState(AsyncEmbeddedEngine.State expectedState, AsyncEmbeddedEngine.State requestedState) Sets the new state ofAsyncEmbeddedEngine.private voidstartSourceTasks(List<EngineSourceTask> tasks) Starts the source tasks.private voidstopConnector(List<EngineSourceTask> tasks, AsyncEmbeddedEngine.State engineState) Stops connector's tasks if they are already running and then stops connector itself.private voidstopOffsetStore(DebeziumSourceConnectorContext connectorContext) StopsOffsetBackingStoreused by engine if there is any.private voidStops task polling if they haven't stopped yet.private voidShuts down theExecutorServicewhich processes the change event records.private voidstopSourceTasks(List<EngineSourceTask> tasks) Stops all the connector's tasks.validateAndGetConnectorConfig(org.apache.kafka.connect.source.SourceConnector connector, String connectorClassName) Validates provided configuration of the Kafka Connect connector and returns its configuration if it's a valid config.
-
Field Details
-
LOGGER
private static final org.slf4j.Logger LOGGER -
config
-
clock
-
classLoader
-
consumer
-
handler
-
completionCallback
private final io.debezium.engine.DebeziumEngine.CompletionCallback completionCallback -
connectorCallback
-
offsetKeyConverter
private final org.apache.kafka.connect.storage.Converter offsetKeyConverter -
offsetValueConverter
private final org.apache.kafka.connect.storage.Converter offsetValueConverter -
workerConfig
private final org.apache.kafka.connect.runtime.WorkerConfig workerConfig -
offsetCommitPolicy
private final io.debezium.engine.spi.OffsetCommitPolicy offsetCommitPolicy -
connector
-
transformations
-
headerConverter
private final org.apache.kafka.connect.storage.HeaderConverter headerConverter -
recordConverter
-
sourceConverter
-
state
-
tasks
-
pollingFutures
-
taskService
-
recordService
-
shutDownLatch
-
-
Constructor Details
-
AsyncEmbeddedEngine
private AsyncEmbeddedEngine(Properties config, Consumer<R> consumer, io.debezium.engine.DebeziumEngine.ChangeConsumer<R> handler, ClassLoader classLoader, Clock clock, io.debezium.engine.DebeziumEngine.CompletionCallback completionCallback, io.debezium.engine.DebeziumEngine.ConnectorCallback connectorCallback, io.debezium.engine.spi.OffsetCommitPolicy offsetCommitPolicy, org.apache.kafka.connect.storage.HeaderConverter headerConverter, Function<org.apache.kafka.connect.source.SourceRecord, R> recordConverter)
-
-
Method Details
-
run
public void run() -
close
- Specified by:
closein interfaceAutoCloseable- Specified by:
closein interfaceCloseable- Throws:
IOException
-
runWithTask
@VisibleForTesting public void runWithTask(Consumer<org.apache.kafka.connect.source.SourceTask> consumer) For backward compatibility with tests and for testing purposes ONLY. MUST NOT be used in user applications! Exposes tasks to a use defined consumer, which allows to run the tasks in tests.- Parameters:
consumer-Consumerfor running tasks.
-
close
Shuts down the engine. Currently, it's limited only to closing header converter and stopping the source connector.- Parameters:
stateBeforeStop-AsyncEmbeddedEngine.Stateof the engine when the shutdown was requested.
-
closeEngineWithException
Stops engine if needed upon the failure. The engine is stopped if it's not already stopped, or it's being stopped in right now.- Parameters:
exitError-Throwablewhich was thrown during the engine run and propagated to the main thread.
-
finishShutDown
Finish engine shut down - move it intoSTOPPEDstate and call the completion callback.- Parameters:
exitError-Throwablewhich was thrown during engine run,nullis engine finished without any issue.
-
initializeConnector
Initialize all the required pieces for initialization of the connector and returns configuration of the connector. -
createSourceTasks
private void createSourceTasks(EngineSourceConnector connector, List<EngineSourceTask> tasks) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException Creates list of connector tasks to be started as the sources of records.- Parameters:
connector-EngineSourceConnectorto which the source tasks belong to.tasks-List<EngineSourceTask>to be populated by the source tasks create in this method.- Throws:
NoSuchMethodExceptionInvocationTargetExceptionInstantiationExceptionIllegalAccessException
-
startSourceTasks
Starts the source tasks. The caller is responsible for handling possible error states. However, all the tasks are awaited to either start of fail.- Parameters:
tasks-List<EngineSourceTask>of tasks to be started- Throws:
Exception
-
runTasksPolling
Schedules polling of provided tasks and wait until all polling tasks eventually finish.- Parameters:
tasks-List<EngineSourceTask>of source tasks which should poll for the records.- Throws:
ExecutionException
-
selectRecordProcessor
SelectRecordProcessorclass based on the user configuration.- Returns:
- Name of the class which should be used for creating
RecordProcessorinstances.
-
createRecordProcessor
InstantiateRecordProcessorbased on the class name deremined inselectRecordProcessor()method.- Returns:
RecordProcessorinstance which will be used for processing the records.
-
stopRecordService
private void stopRecordService()Shuts down theExecutorServicewhich processes the change event records. WaitsRECORD_PROCESSING_SHUTDOWN_TIMEOUT_MSmilliseconds for already submitted records to finish. If the specified timeout is exceeded, the service is shut down immediately. -
stopPollingIfNeeded
private void stopPollingIfNeeded()Stops task polling if they haven't stopped yet. Some tasks may be stuck in the polling, we should interrupt such tasks. -
stopSourceTasks
Stops all the connector's tasks. There are no checks if the tasks were fully stated or already running, stop is always called. Also tries to stop all the other tasks which may be still running or awaiting execution in the task's thread pool.- Parameters:
tasks-List<EngineSourceTask>of source tasks which should be stopped.
-
stopOffsetStore
StopsOffsetBackingStoreused by engine if there is any. If engine fails during initialization phase before connector context is created, the reference may benulland in such this method does nothing.- Parameters:
connectorContext-DebeziumSourceConnectorContextused by the connector ornullif the context hasn't been initialized yet.
-
stopConnector
Stops connector's tasks if they are already running and then stops connector itself.- Parameters:
tasks-List<EngineSourceTask>of source task should be stopped now.
-
callCompletionHandler
Calls provided implementation ofDebeziumEngine.CompletionCallback.- Parameters:
error- Error with which the engine has failed,nullif the engine has finished successfully.
-
getEngineState
Gets the current state of the engine.- Returns:
- current
AsyncEmbeddedEngine.Stateof theAsyncEmbeddedEngine.
-
setEngineState
private void setEngineState(AsyncEmbeddedEngine.State expectedState, AsyncEmbeddedEngine.State requestedState) Sets the new state ofAsyncEmbeddedEngine. Initial state is alwaysState.CREATING. State transition checks current engine state and if it doesn't correspond with expected state an exception is thrown as there is likely a bug in engine implementation or usage.- Parameters:
expectedState- expected currentAsyncEmbeddedEngine.Stateof theAsyncEmbeddedEngine.requestedState- newAsyncEmbeddedEngine.Stateof theAsyncEmbeddedEngineto be set.- Throws:
IllegalStateException- The exception is thrown when expected engine state doesn't match the actual engine state.
-
validateAndGetConnectorConfig
private Map<String,String> validateAndGetConnectorConfig(org.apache.kafka.connect.source.SourceConnector connector, String connectorClassName) Validates provided configuration of the Kafka Connect connector and returns its configuration if it's a valid config. -
createAndStartOffsetStore
private org.apache.kafka.connect.storage.OffsetBackingStore createAndStartOffsetStore(Map<String, String> connectorConfig) throws ExceptionDetermines which offset backing store should be used, instantiate it and starts the offset store. -
commitOffsets
private static boolean commitOffsets(org.apache.kafka.connect.storage.OffsetStorageWriter offsetWriter, Clock clock, long commitTimeout, org.apache.kafka.connect.source.SourceTask task) throws InterruptedException, TimeoutException Commits the offset toOffsetBackingStoreviaOffsetStorageWriter.- Parameters:
offsetWriter-OffsetStorageWriterwhich performs the flushing the offset intoOffsetBackingStore.commitTimeout- amount of time to wait for offset flush to finish before it's aborted.task-SourceTaskwhich performs the offset commit.- Returns:
trueif the offset was successfully committed,falseotherwise.- Throws:
InterruptedExceptionTimeoutException
-
buildDefaultChangeConsumer
private static io.debezium.engine.DebeziumEngine.ChangeConsumer<org.apache.kafka.connect.source.SourceRecord> buildDefaultChangeConsumer(Consumer<org.apache.kafka.connect.source.SourceRecord> consumer) Build the defaultDebeziumEngine.ChangeConsumerfrom provided customConsumer. -
buildConvertingChangeConsumer
private static io.debezium.engine.DebeziumEngine.ChangeConsumer buildConvertingChangeConsumer(Consumer consumer, Function<org.apache.kafka.connect.source.SourceRecord, ?> recordConverter) -
computeRecordThreads
Determines the size of the thread pool which will be used for processing records. The value can be either number (provided as aStringvalue) or a predefined placeholder fromAsyncEmbeddedEngine.ProcessingCoresenumeration. If the number of threads is provided as a number, it will be eventually limited toAsyncEngineConfig.RECORD_PROCESSING_THREADS_CAPto avoid possible overhead with too many context switches on a beefy machines with many cores, but running many other tasks.- Parameters:
recordProcessingThreads- Requested number of processing threads as aString. It can be a number or predefined placeholder.- Returns:
- Either requested number of threads or minimum of
AsyncEngineConfig.RECORD_PROCESSING_THREADS_CAPandAsyncEngineConfig.AVAILABLE_CORES.
-