@@ -261,7 +261,7 @@ internal constructor(
261
261
}
262
262
messageIterator.forEachRemaining(recordCollector)
263
263
messageIterator.airbyteStream.ifPresent { s: AirbyteStreamNameNamespacePair ? ->
264
- LOGGER .debug(" Finished producing messages for stream {}..." )
264
+ LOGGER .debug(" Finished producing messages for stream {}..." , s )
265
265
}
266
266
}
267
267
@@ -373,67 +373,34 @@ internal constructor(
373
373
374
374
private lateinit var validator: JsonSchemaValidator
375
375
376
- @VisibleForTesting
377
376
@Throws(Exception ::class )
378
- fun consumeWriteStream (consumer : SerializedAirbyteMessageConsumer ) {
379
- BufferedInputStream (System .`in `).use { bis ->
380
- ByteArrayOutputStream ().use { baos -> consumeWriteStream(consumer, bis, baos) }
381
- }
382
- }
383
-
384
- @VisibleForTesting
385
- @Throws(Exception ::class )
386
- fun consumeWriteStream (
377
+ internal fun consumeWriteStream (
387
378
consumer : SerializedAirbyteMessageConsumer ,
388
- bis : BufferedInputStream ,
389
- baos : ByteArrayOutputStream
379
+ inputStream : InputStream = System .`in `
390
380
) {
381
+ LOGGER .info(" Starting buffered read of input stream" )
391
382
consumer.start()
392
-
393
- val buffer = ByteArray (8192 ) // 8K buffer
394
- var bytesRead: Int
395
- var lastWasNewLine = false
396
-
397
- while ((bis.read(buffer).also { bytesRead = it }) != - 1 ) {
398
- for (i in 0 until bytesRead) {
399
- val b = buffer[i]
400
- if (b == ' \n ' .code.toByte() || b == ' \r ' .code.toByte()) {
401
- if (! lastWasNewLine && baos.size() > 0 ) {
402
- consumer.accept(baos.toString(StandardCharsets .UTF_8 ), baos.size())
403
- baos.reset()
404
- }
405
- lastWasNewLine = true
383
+ inputStream.bufferedReader(StandardCharsets .UTF_8 ).use {
384
+ var emptyLines = 0
385
+ it.lines().forEach { line: String ->
386
+ if (line.isNotEmpty()) {
387
+ consumer.accept(line, line.toByteArray(StandardCharsets .UTF_8 ).size)
406
388
} else {
407
- baos.write(b.toInt())
408
- lastWasNewLine = false
389
+ emptyLines++
390
+ // We've occasionally seen this loop not exit
391
+ // maybe it's because we keep getting streams of empty lines?
392
+ // TODO: Monitor the logs for occurrences of this log line and if this isn't
393
+ // an issue, remove it.
394
+ if (emptyLines % 1_000 == 0 && emptyLines < 10_000 ) {
395
+ LOGGER .warn(" Encountered $emptyLines empty lines during execution" )
396
+ }
409
397
}
410
398
}
399
+ if (emptyLines > 0 ) {
400
+ LOGGER .warn(" Encountered $emptyLines empty lines in the input stream." )
401
+ }
411
402
}
412
-
413
- // Handle last line if there's one
414
- if (baos.size() > 0 ) {
415
- consumer.accept(baos.toString(StandardCharsets .UTF_8 ), baos.size())
416
- }
417
- }
418
-
419
- /* *
420
- * Stops any non-daemon threads that could block the JVM from exiting when the main thread
421
- * is done.
422
- *
423
- * If any active non-daemon threads would be left as orphans, this method will schedule some
424
- * interrupt/exit hooks after giving it some time delay to close up properly. It is
425
- * generally preferred to have a proper closing sequence from children threads instead of
426
- * interrupting or force exiting the process, so this mechanism serve as a fallback while
427
- * surfacing warnings in logs for maintainers to fix the code behavior instead.
428
- */
429
- fun stopOrphanedThreads () {
430
- stopOrphanedThreads(
431
- EXIT_HOOK ,
432
- INTERRUPT_THREAD_DELAY_MINUTES ,
433
- TimeUnit .MINUTES ,
434
- EXIT_THREAD_DELAY_MINUTES ,
435
- TimeUnit .MINUTES
436
- )
403
+ LOGGER .info(" Finished buffered read of input stream" )
437
404
}
438
405
439
406
/* *
@@ -455,11 +422,11 @@ internal constructor(
455
422
*/
456
423
@VisibleForTesting
457
424
fun stopOrphanedThreads (
458
- exitHook : Runnable ,
459
- interruptTimeDelay : Int ,
460
- interruptTimeUnit : TimeUnit ? ,
461
- exitTimeDelay : Int ,
462
- exitTimeUnit : TimeUnit ?
425
+ exitHook : Runnable = EXIT_HOOK ,
426
+ interruptTimeDelay : Int = INTERRUPT_THREAD_DELAY_MINUTES ,
427
+ interruptTimeUnit : TimeUnit = TimeUnit . MINUTES ,
428
+ exitTimeDelay : Int = EXIT_THREAD_DELAY_MINUTES ,
429
+ exitTimeUnit : TimeUnit = TimeUnit . MINUTES
463
430
) {
464
431
val currentThread = Thread .currentThread()
465
432
@@ -468,7 +435,7 @@ internal constructor(
468
435
.stream()
469
436
.filter(ORPHANED_THREAD_FILTER )
470
437
.collect(Collectors .toList())
471
- if (! runningThreads.isEmpty ()) {
438
+ if (runningThreads.isNotEmpty ()) {
472
439
LOGGER .warn(
473
440
"""
474
441
The main thread is exiting while children non-daemon threads from a connector are still active.
@@ -535,7 +502,7 @@ internal constructor(
535
502
operationType : String
536
503
) {
537
504
val validationResult = validator.validate(schemaJson, objectJson)
538
- if (! validationResult.isEmpty ()) {
505
+ if (validationResult.isNotEmpty ()) {
539
506
throw Exception (
540
507
String .format(
541
508
" Verification error(s) occurred for %s. Errors: %s " ,
0 commit comments