@@ -6,6 +6,7 @@ package io.airbyte.cdk.load.task.internal
6
6
7
7
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings
8
8
import io.airbyte.cdk.load.command.DestinationCatalog
9
+ import io.airbyte.cdk.load.command.DestinationConfiguration
9
10
import io.airbyte.cdk.load.command.DestinationStream
10
11
import io.airbyte.cdk.load.message.Batch
11
12
import io.airbyte.cdk.load.message.BatchEnvelope
@@ -50,6 +51,8 @@ import io.github.oshai.kotlinlogging.KotlinLogging
50
51
import io.micronaut.context.annotation.Secondary
51
52
import jakarta.inject.Named
52
53
import jakarta.inject.Singleton
54
+ import java.io.RandomAccessFile
55
+ import java.nio.channels.FileChannel
53
56
import java.util.concurrent.ConcurrentHashMap
54
57
55
58
interface InputConsumerTask : Task
@@ -67,6 +70,7 @@ interface InputConsumerTask : Task
67
70
@Singleton
68
71
@Secondary
69
72
class DefaultInputConsumerTask (
73
+ private val config : DestinationConfiguration ,
70
74
private val catalog : DestinationCatalog ,
71
75
private val inputFlow : ReservingDeserializingInputFlow ,
72
76
private val recordQueueSupplier :
@@ -81,6 +85,9 @@ class DefaultInputConsumerTask(
81
85
@Named(" recordQueue" )
82
86
private val recordQueueForPipeline :
83
87
PartitionedQueue <PipelineEvent <StreamKey , DestinationRecordAirbyteValue >>,
88
+ @Named(" fileQueue" )
89
+ private val fileQueueForPipeline :
90
+ PartitionedQueue <PipelineEvent <StreamKey , DestinationFile >>,
84
91
private val loadPipeline : LoadPipeline ? = null ,
85
92
private val partitioner : InputPartitioner ,
86
93
private val openStreamQueue : QueueWriter <DestinationStream >
@@ -182,19 +189,21 @@ class DefaultInputConsumerTask(
182
189
reserved.release()
183
190
}
184
191
is DestinationFile -> {
185
- val index = manager.incrementReadCount()
186
- // destinationTaskLauncher.handleFile(stream, message, index)
187
- fileTransferQueue.publish(FileTransferQueueMessage (stream, message, index))
192
+ val partition = manager.incrementReadCount().toInt() % fileQueueForPipeline.partitions
193
+ fileQueueForPipeline.publish(
194
+ PipelineMessage (
195
+ mapOf (manager.getCurrentCheckpointId() to 1 ),
196
+ StreamKey (stream),
197
+ message
198
+ ) { reserved.release() },
199
+ partition
200
+ )
188
201
}
189
202
is DestinationFileStreamComplete -> {
190
203
reserved.release() // safe because multiple calls conflate
191
204
manager.markEndOfStream(true )
192
- val envelope =
193
- BatchEnvelope (
194
- SimpleBatch (Batch .State .COMPLETE ),
195
- streamDescriptor = message.stream,
196
- )
197
- destinationTaskLauncher.handleNewBatch(stream, envelope)
205
+ log.info { " Read COMPLETE for file stream $stream " }
206
+ fileQueueForPipeline.broadcast(PipelineEndOfStream (stream))
198
207
}
199
208
is DestinationFileStreamIncomplete ->
200
209
throw IllegalStateException (" File stream $stream failed upstream, cannot continue." )
@@ -294,12 +303,14 @@ class DefaultInputConsumerTask(
294
303
catalog.streams.forEach { recordQueueSupplier.get(it.descriptor).close() }
295
304
fileTransferQueue.close()
296
305
recordQueueForPipeline.close()
306
+ fileQueueForPipeline.close()
297
307
}
298
308
}
299
309
}
300
310
301
311
interface InputConsumerTaskFactory {
302
312
fun make (
313
+ config : DestinationConfiguration ,
303
314
catalog : DestinationCatalog ,
304
315
inputFlow : ReservingDeserializingInputFlow ,
305
316
recordQueueSupplier :
@@ -311,6 +322,7 @@ interface InputConsumerTaskFactory {
311
322
// Required by new interface
312
323
recordQueueForPipeline :
313
324
PartitionedQueue <PipelineEvent <StreamKey , DestinationRecordAirbyteValue >>,
325
+ fileQueueForPipeline : PartitionedQueue <PipelineEvent <StreamKey , DestinationFile >>,
314
326
loadPipeline : LoadPipeline ? ,
315
327
partitioner : InputPartitioner ,
316
328
openStreamQueue : QueueWriter <DestinationStream >,
@@ -323,6 +335,7 @@ class DefaultInputConsumerTaskFactory(
323
335
private val syncManager : SyncManager ,
324
336
) : InputConsumerTaskFactory {
325
337
override fun make (
338
+ config : DestinationConfiguration ,
326
339
catalog : DestinationCatalog ,
327
340
inputFlow : ReservingDeserializingInputFlow ,
328
341
recordQueueSupplier :
@@ -334,11 +347,13 @@ class DefaultInputConsumerTaskFactory(
334
347
// Required by new interface
335
348
recordQueueForPipeline :
336
349
PartitionedQueue <PipelineEvent <StreamKey , DestinationRecordAirbyteValue >>,
350
+ fileQueueForPipeline : PartitionedQueue <PipelineEvent <StreamKey , DestinationFile >>,
337
351
loadPipeline : LoadPipeline ? ,
338
352
partitioner : InputPartitioner ,
339
353
openStreamQueue : QueueWriter <DestinationStream >,
340
354
): InputConsumerTask {
341
355
return DefaultInputConsumerTask (
356
+ config,
342
357
catalog,
343
358
inputFlow,
344
359
recordQueueSupplier,
@@ -349,6 +364,7 @@ class DefaultInputConsumerTaskFactory(
349
364
350
365
// Required by new interface
351
366
recordQueueForPipeline,
367
+ fileQueueForPipeline,
352
368
loadPipeline,
353
369
partitioner,
354
370
openStreamQueue,
0 commit comments