muttakin2301/ccr2000 huggingface dataset:
Code review comment: These variables don't need to be created here. They are only used in the ON_ERROR case.

Code under review:
public void endSpan(Context context, Signal<Void> signal) {
        Objects.requireNonNull(context, "'context' cannot be null");
        Objects.requireNonNull(signal, "'signal' cannot be null");

        
        if (!context.getData(OPENTELEMETRY_SPAN_KEY).isPresent()) {
            return;
        }

        String errorCondition;
        Throwable throwable;

        switch (signal.getType()) {
            case ON_COMPLETE:
                end("success", null, context);
            case ON_ERROR:
                errorCondition = "";
                throwable = null;
                if (signal.hasError()) {
                    
                    throwable = signal.getThrowable();

                    if (throwable instanceof AmqpException) {
                        AmqpException exception = (AmqpException) throwable;
                        errorCondition = exception.getErrorCondition().getErrorCondition();
                    }
                }
                end(errorCondition, throwable, context);
            default:
                
                break;
        }

    }

Line commented on: String errorCondition;

Revised code:
public void endSpan(Context context, Signal<Void> signal) {
        Objects.requireNonNull(context, "'context' cannot be null");
        Objects.requireNonNull(signal, "'signal' cannot be null");

        
        if (!context.getData(OPENTELEMETRY_SPAN_KEY).isPresent()) {
            return;
        }

        switch (signal.getType()) {
            case ON_COMPLETE:
                end("success", null, context);
                break;
            case ON_ERROR:
                String errorCondition = "";
                Throwable throwable = null;
                if (signal.hasError()) {
                    
                    throwable = signal.getThrowable();

                    if (throwable instanceof AmqpException) {
                        AmqpException exception = (AmqpException) throwable;
                        errorCondition = exception.getErrorCondition().getErrorCondition();
                    }
                }
                end(errorCondition, throwable, context);
                break;
            default:
                
                break;
        }
    }
Code review comment: Did we decide to change this during the discussion as it could break something? Sorry, I couldn't remember.

Code under review:
private static ClassLoader createClassLoader(List<Path> jarDependencyPaths) {
        return AccessController.doPrivileged(
                (PrivilegedAction<URLClassLoader>) () -> new URLClassLoader(getJarURLS(jarDependencyPaths),
                        Thread.currentThread().getContextClassLoader())
        );
    }

Line commented on: Thread.currentThread().getContextClassLoader())

Revised code:
private static ClassLoader createClassLoader(List<Path> jarDependencyPaths) {
        return AccessController.doPrivileged(
                (PrivilegedAction<URLClassLoader>) () -> new URLClassLoader(getJarURLS(jarDependencyPaths),
                        Thread.currentThread().getContextClassLoader())
        );
    }
Code review comment: Why are both called in succession here?

Code under review:
void testWriteOnBulkFlush() throws Exception {
        final String index = "test-bulk-flush-without-checkpoint";
        final int flushAfterNActions = 5;
        final BulkProcessorConfig bulkProcessorConfig =
                new BulkProcessorConfig(flushAfterNActions, -1, -1, null, 0, 0);

        try (final ElasticsearchWriter<Tuple2<Integer, String>> writer =
                createWriter(index, false, bulkProcessorConfig)) {
            writer.write(Tuple2.of(1, buildMessage(1)), null);
            writer.write(Tuple2.of(2, buildMessage(2)), null);
            writer.write(Tuple2.of(3, buildMessage(3)), null);
            writer.write(Tuple2.of(4, buildMessage(4)), null);

            
            writer.prepareCommit(true);
            writer.prepareCommit(false);

            context.assertThatIdsAreNotWritten(index, 1, 2, 3, 4);

            
            writer.write(Tuple2.of(5, "test-5"), null);
            context.assertThatIdsAreWritten(index, 1, 2, 3, 4, 5);
        }
    }

Line commented on: writer.prepareCommit(false);

Revised code:
void testWriteOnBulkFlush() throws Exception {
        final String index = "test-bulk-flush-without-checkpoint";
        final int flushAfterNActions = 5;
        final BulkProcessorConfig bulkProcessorConfig =
                new BulkProcessorConfig(flushAfterNActions, -1, -1, FlushBackoffType.NONE, 0, 0);

        try (final ElasticsearchWriter<Tuple2<Integer, String>> writer =
                createWriter(index, false, bulkProcessorConfig)) {
            writer.write(Tuple2.of(1, buildMessage(1)), null);
            writer.write(Tuple2.of(2, buildMessage(2)), null);
            writer.write(Tuple2.of(3, buildMessage(3)), null);
            writer.write(Tuple2.of(4, buildMessage(4)), null);

            
            writer.prepareCommit(false);

            context.assertThatIdsAreNotWritten(index, 1, 2, 3, 4);

            
            writer.write(Tuple2.of(5, "test-5"), null);
            context.assertThatIdsAreWritten(index, 1, 2, 3, 4, 5);

            writer.write(Tuple2.of(6, "test-6"), null);
            context.assertThatIdsAreNotWritten(index, 6);

            
            writer.prepareCommit(true);
            context.assertThatIdsAreWritten(index, 1, 2, 3, 4, 5, 6);
        }
    }
Code review comment: this breaks the proxy flow I think (backward compat), the Pipeline adapter in current flow is only configured if either httpClient is not null or proxy options are not configured.  With this change, the pipeline adapter will get configured if httpClient is null and proxy options are configured.

Code under review:
void initializeHttpPipelineAdapter() {
        
        
        HttpPipeline httpPipeline = options.getHttpPipeline();
        if (httpPipeline != null) {
            this.httpPipeline = httpPipeline;
            httpPipelineAdapter = new HttpPipelineAdapter(httpPipeline, options);
        } else {
            
            HttpClient httpClient = options.getHttpClient();
            this.httpPipeline = setupPipeline(httpClient == null ? HttpClient.createDefault() : httpClient);
            httpPipelineAdapter = new HttpPipelineAdapter(this.httpPipeline, options);
        }
    }

Line commented on: this.httpPipeline = setupPipeline(httpClient == null ? HttpClient.createDefault() : httpClient);

Revised code:
void initializeHttpPipelineAdapter() {
        if (options.getProxyOptions() == null) {
            httpPipelineAdapter = new HttpPipelineAdapter(getPipeline(), options);
        }
    }
Code review comment: Do we need to explicitly returnResource? I thought that's why the try() {} block existed.  If we do need to returnResource, I don't see it being returned in all other paths..

Code under review:
public Flux<Checkpoint> listCheckpoints(String fullyQualifiedNamespace, String eventHubName, String consumerGroup) {
        String prefix = prefixBuilder(fullyQualifiedNamespace, eventHubName, consumerGroup);
        try (Jedis jedis = jedisPool.getResource()) {
            ArrayList<Checkpoint> listStoredCheckpoints = new ArrayList<>();
            Set<String> members = jedis.smembers(prefix);
            if (members.isEmpty()) {
                jedisPool.returnResource(jedis);
                return Flux.fromIterable(listStoredCheckpoints);
            }
            for (String member : members) {
                
                List<String> checkpointJsonList = jedis.hmget(member, CHECKPOINT);
                jedisPool.returnResource(jedis);
                if (checkpointJsonList == null) {
                    return Flux.error(new IllegalStateException("No checkpoints persist in Redis for the given parameters."));
                }
                else {
                    String checkpointJson = checkpointJsonList.get(0);
                    Checkpoint checkpoint = DEFAULT_SERIALIZER.deserializeFromBytes(checkpointJson.getBytes(StandardCharsets.UTF_8), TypeReference.createInstance(Checkpoint.class));
                    listStoredCheckpoints.add(checkpoint);
                }
            }
            return Flux.fromIterable(listStoredCheckpoints);
        }
    }

Line commented on: jedisPool.returnResource(jedis);

Revised code:
public Flux<Checkpoint> listCheckpoints(String fullyQualifiedNamespace, String eventHubName, String consumerGroup) {
        String prefix = prefixBuilder(fullyQualifiedNamespace, eventHubName, consumerGroup);
        try (Jedis jedis = jedisPool.getResource()) {
            ArrayList<Checkpoint> listStoredCheckpoints = new ArrayList<>();
            Set<String> members = jedis.smembers(prefix);
            if (members.isEmpty()) {
                jedisPool.returnResource(jedis);
                return Flux.fromIterable(listStoredCheckpoints);
            }
            for (String member : members) {
                
                List<String> checkpointJsonList = jedis.hmget(member, CHECKPOINT);
                if (!checkpointJsonList.isEmpty()) {
                    String checkpointJson = checkpointJsonList.get(0);
                    if (checkpointJson == null) {
                        LOGGER.verbose("No checkpoint persists yet.");
                        continue;
                    }
                    Checkpoint checkpoint = DEFAULT_SERIALIZER.deserializeFromBytes(checkpointJson.getBytes(StandardCharsets.UTF_8), TypeReference.createInstance(Checkpoint.class));
                    listStoredCheckpoints.add(checkpoint);
                } else {
                    LOGGER.verbose("No checkpoint persists yet.");
                }
            }
            jedisPool.returnResource(jedis);
            return Flux.fromIterable(listStoredCheckpoints);
        }
    }
Code review comment: The default version (no param constructor) is 0.8.6, but it is one of those that don't work.

Code under review:
private static void setupLocalstack() throws Exception {
    System.setProperty(SDKGlobalConfiguration.DISABLE_CERT_CHECKING_SYSTEM_PROPERTY, "true");
    System.setProperty(SDKGlobalConfiguration.AWS_CBOR_DISABLE_SYSTEM_PROPERTY, "true");

    
    now = Instant.ofEpochMilli(Long.divideUnsigned(Instant.now().getMillis(), 1000));

    localstackContainer =
        new LocalStackContainer("0.11.3")
            .withServices(LocalStackContainer.Service.KINESIS)
            .withEnv("USE_SSL", "true")
            .withStartupAttempts(3);
    localstackContainer.start();

    options.setAwsServiceEndpoint(
        localstackContainer
            .getEndpointConfiguration(LocalStackContainer.Service.KINESIS)
            .getServiceEndpoint()
            .replace("http", "https"));
    options.setAwsKinesisRegion(
        localstackContainer
            .getEndpointConfiguration(LocalStackContainer.Service.KINESIS)
            .getSigningRegion());
    options.setAwsAccessKey(
        localstackContainer.getDefaultCredentialsProvider().getCredentials().getAWSAccessKeyId());
    options.setAwsSecretKey(
        localstackContainer.getDefaultCredentialsProvider().getCredentials().getAWSSecretKey());
    options.setNumberOfRecords(1000);
    options.setNumberOfShards(1);
    options.setAwsKinesisStream("beam_kinesis_test");
    options.setAwsVerifyCertificate(false);
    createStream(options.getAwsKinesisStream());
  }

Line commented on: new LocalStackContainer("0.11.3")

Revised code:
private static void setupLocalstack() {
    
    now = Instant.ofEpochMilli(Long.divideUnsigned(now.getMillis(), 1000L));

    System.setProperty(SDKGlobalConfiguration.DISABLE_CERT_CHECKING_SYSTEM_PROPERTY, "true");
    System.setProperty(SDKGlobalConfiguration.AWS_CBOR_DISABLE_SYSTEM_PROPERTY, "true");

    localstackContainer =
        new LocalStackContainer(LOCALSTACK_VERSION)
            .withServices(LocalStackContainer.Service.KINESIS)
            .withEnv("USE_SSL", "true")
            .withStartupAttempts(3);
    localstackContainer.start();

    options.setAwsServiceEndpoint(
        localstackContainer
            .getEndpointConfiguration(LocalStackContainer.Service.KINESIS)
            .getServiceEndpoint()
            .replace("http", "https"));
    options.setAwsKinesisRegion(
        localstackContainer
            .getEndpointConfiguration(LocalStackContainer.Service.KINESIS)
            .getSigningRegion());
    options.setAwsAccessKey(
        localstackContainer.getDefaultCredentialsProvider().getCredentials().getAWSAccessKeyId());
    options.setAwsSecretKey(
        localstackContainer.getDefaultCredentialsProvider().getCredentials().getAWSSecretKey());
    options.setNumberOfRecords(1000);
    options.setNumberOfShards(1);
    options.setAwsKinesisStream("beam_kinesis_test");
    options.setAwsVerifyCertificate(false);
  }
Code review comment: line 64 and line 67 both are trying to set the `itemBodyOverride`, what is the use case for `itemBodyOverride`

Code under review:
private CosmosItemResponse(ResourceResponse<Document> response, T item, JsonNode itemBodyOverride, Class<T> classType, ItemDeserializer itemDeserializer) {
        this.itemClassType = classType;
        this.resourceResponse = response;
        this.itemDeserializer = itemDeserializer;
        this.item = item;
        this.itemBodyOverride = itemBodyOverride;
        boolean hasPayloadStaticValue = item != null;
        this.hasPayload = () -> hasPayloadStaticValue;
        this.itemBodyOverride = null;
    }

Line commented on: this.itemBodyOverride = null;

Revised code:
private CosmosItemResponse(ResourceResponse<Document> response, T item, JsonNode itemBodyOverride, Class<T> classType, ItemDeserializer itemDeserializer) {
        this.itemClassType = classType;
        this.resourceResponse = response;
        this.itemDeserializer = itemDeserializer;
        this.item = item;
        this.itemBodyOverride = itemBodyOverride;
        boolean hasPayloadStaticValue = item != null;
        this.hasPayload = () -> hasPayloadStaticValue;
    }
Code review comment: It doesn't seem like you undid this one :)

Code under review:
private static SpringCloudConfigClientConfig configForTesting() {
        SpringCloudConfigClientConfig springCloudConfigClientConfig = new SpringCloudConfigClientConfig();
        springCloudConfigClientConfig.url = "http:
        springCloudConfigClientConfig.label = Optional.of("master");
        springCloudConfigClientConfig.connectionTimeout = Duration.ZERO;
        springCloudConfigClientConfig.readTimeout = Duration.ofSeconds(10);
        springCloudConfigClientConfig.username = Optional.empty();
        springCloudConfigClientConfig.password = Optional.empty();
        springCloudConfigClientConfig.trustStore = Optional.empty();
        springCloudConfigClientConfig.keyStore = Optional.empty();
        springCloudConfigClientConfig.trustCerts = false;
        springCloudConfigClientConfig.headers = new HashMap<>();
        return springCloudConfigClientConfig;
    }

Line commented on: springCloudConfigClientConfig.password = Optional.empty();

Revised code:
private static SpringCloudConfigClientConfig configForTesting() {
        SpringCloudConfigClientConfig springCloudConfigClientConfig = new SpringCloudConfigClientConfig();
        springCloudConfigClientConfig.url = "http:
        springCloudConfigClientConfig.label = Optional.of("master");
        springCloudConfigClientConfig.connectionTimeout = Duration.ZERO;
        springCloudConfigClientConfig.readTimeout = Duration.ZERO;
        springCloudConfigClientConfig.username = Optional.empty();
        springCloudConfigClientConfig.password = Optional.empty();
        springCloudConfigClientConfig.trustStore = Optional.empty();
        springCloudConfigClientConfig.keyStore = Optional.empty();
        springCloudConfigClientConfig.trustCerts = false;
        springCloudConfigClientConfig.headers = new HashMap<>();
        return springCloudConfigClientConfig;
    }
Code review comment: > Do you think ctx.getChild(1)).getSymbol().getStartIndex() == ctx.LP_().getSymbol().getStartIndex()?  Yes, maybe using `ctx.LP_().getSymbol().getStartIndex()` is more easier to read. I will optimise it.  > From the definition of aggregationFunction , >  > aggregationFunction >     : aggregationFunctionName LP_ distinct? (expr (COMMA_ expr)* | ASTERISK_)? RP_ > What we want is from LP_ to RP_, right?  Yes, the innerExpression include sql string from LP_ to RP_. The previous innerExpressionStartIndex is also the same logic.

Code under review:
private ASTNode createAggregationSegment(final AggregationFunctionContext ctx, final String aggregationType) {
        AggregationType type = AggregationType.valueOf(aggregationType.toUpperCase());
        String innerExpression = ctx.start.getInputStream().getText(new Interval(((TerminalNode) ctx.getChild(1)).getSymbol().getStartIndex(), ctx.stop.getStopIndex()));
        if (null == ctx.distinct()) {
            return new AggregationProjectionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), type, innerExpression);
        }
        return new AggregationDistinctProjectionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), type, innerExpression, getDistinctExpression(ctx));
    }

Line commented on: String innerExpression = ctx.start.getInputStream().getText(new Interval(((TerminalNode) ctx.getChild(1)).getSymbol().getStartIndex(), ctx.stop.getStopIndex()));

Revised code:
private ASTNode createAggregationSegment(final AggregationFunctionContext ctx, final String aggregationType) {
        AggregationType type = AggregationType.valueOf(aggregationType.toUpperCase());
        String innerExpression = ctx.start.getInputStream().getText(new Interval(ctx.LP_().getSymbol().getStartIndex(), ctx.stop.getStopIndex()));
        if (null == ctx.distinct()) {
            return new AggregationProjectionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), type, innerExpression);
        }
        return new AggregationDistinctProjectionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), type, innerExpression, getDistinctExpression(ctx));
    }
Code review comment: Should this throw if `strategies` is null or empty?

Code under review:
public ChainedPollingStrategy(List<PollingStrategy<T, U>> strategies) {
        this.pollingStrategies = Collections.unmodifiableList(strategies);
    }

Line commented on: this.pollingStrategies = Collections.unmodifiableList(strategies);

Revised code:
public ChainedPollingStrategy(List<PollingStrategy<T, U>> strategies) {
        Objects.requireNonNull(strategies, "'strategies' cannot be null.");
        if (strategies.isEmpty()) {
            throw logger.logExceptionAsError(new IllegalArgumentException("'strategies' cannot be empty."));
        }
        this.pollingStrategies = Collections.unmodifiableList(strategies);
    }
Code review comment: This is something I wanted to ask you @cescoffier. So I suppose that RX and Axle versions built on top of a regular router and we should follow the pattern from [VertxProducer](https://github.com/quarkusio/quarkus/blob/master/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/VertxProducer.java#L43). But what's the advantage of the rx version... let's say for `Router`?

Code under review:
private HttpServerOptions createHttpServerOptions(VertxHttpConfiguration vertxHttpConfiguration, LaunchMode launchMode) {
        
        HttpServerOptions options = new HttpServerOptions();
        options.setHost(vertxHttpConfiguration.host);
        options.setPort(vertxHttpConfiguration.determinePort(launchMode));
        return options;
    }

Line commented on: return options;

Revised code:
private HttpServerOptions createHttpServerOptions(VertxHttpConfiguration vertxHttpConfiguration, LaunchMode launchMode) {
        
        HttpServerOptions options = new HttpServerOptions();
        options.setHost(vertxHttpConfiguration.host);
        options.setPort(vertxHttpConfiguration.determinePort(launchMode));
        return options;
    }
Code review comment: We can keep it because it already exists, but what I objected to is searching for the junit jar on a conceptual level. It is not sound to couple the usage of some testing library to the correctness of production code.

Code under review:
public void testJarFromSystemClasspath() throws MalformedURLException {
        classpathProvider.setSystemClasspathWithTwoEntryClasses();
        final Collection<String> systemClasspath =
                StreamSupport.stream(
                                FromClasspathEntryClassInformationProvider.extractSystemClasspath()
                                        .spliterator(),
                                false)
                        .map(File::getName)
                        .collect(Collectors.toList());
        final Collection<String> expectedContent =
                StreamSupport.stream(
                                classpathProvider
                                        .getURLUserClasspathWithTwoEntryClasses()
                                        .spliterator(),
                                false)
                        .map(URL::getPath)
                        .map(FilenameUtils::getName)
                        
                        .filter(name -> name.endsWith("jar"))
                        .collect(Collectors.toList());
        assertThat(
                systemClasspath,
                IsIterableContainingInAnyOrder.containsInAnyOrder(expectedContent.toArray()));
    }

Line commented on: false)

Revised code:
public void testJarFromSystemClasspath() throws MalformedURLException {
        multipleEntryClassesClasspathProvider.setSystemClasspath();
        final Collection<String> systemClasspath =
                StreamSupport.stream(
                                FromClasspathEntryClassInformationProvider.extractSystemClasspath()
                                        .spliterator(),
                                false)
                        .map(File::getName)
                        .collect(Collectors.toList());
        final Collection<String> expectedContent =
                StreamSupport.stream(
                                multipleEntryClassesClasspathProvider
                                        .getURLUserClasspath()
                                        .spliterator(),
                                false)
                        .map(URL::getPath)
                        .map(FilenameUtils::getName)
                        
                        .filter(name -> name.endsWith("jar"))
                        .collect(Collectors.toList());
        assertThat(
                systemClasspath,
                IsIterableContainingInAnyOrder.containsInAnyOrder(expectedContent.toArray()));
    }
Code review comment: If we use `this` we should use it for `app` too.

Code under review:
public void destroy() {
        if (driver != null) {
            this.driver.quit();
        }
        if (app != null) {
            app.close();
        }
    }

Line commented on: app.close();

Revised code:
public void destroy() {
        driver.quit();
        app.close();
    }
Code review comment: No action required, but `CompletableFuture.allOf` is idiomatic and future-proof style for awaiting a list of futures, with the expectation that the underlying implementation will maximize concurrency and early termination.  To utilize it you might have to do some adjustments like building a `Future<Context>` by pairing with the timestamp and some adaptation between the old `Future` APIs and the new `CompletionStage/CompletableFuture` APIs. I wouldn't do it now. The result may come out worse, just because none of Java's three future-like APIs really get it right.

Code under review:
public void finishBundle(FinishBundleContext c) throws InterruptedException {
      stream.flush();
      for (Map.Entry<BoundedWindow, Queue<Context>> pendingWindow : pending.entrySet()) {
        OutputReceiver<Row> r = new OutputReceiverForFinishBundle(c, pendingWindow.getKey());
        for (Context vf : pendingWindow.getValue()) {
          outputRow(vf, r);
        }
      }
    }

Line commented on: for (Context vf : pendingWindow.getValue()) {

Revised code:
public void finishBundle(FinishBundleContext c) throws InterruptedException {
      stream.flush();
      for (Map.Entry<BoundedWindow, Queue<TimestampedFuture>> pendingWindow : pending.entrySet()) {
        OutputReceiver<Row> rowOutputReciever =
            new OutputReceiverForFinishBundle(c, pendingWindow.getKey());
        for (TimestampedFuture timestampedFuture : pendingWindow.getValue()) {
          outputRow(timestampedFuture, rowOutputReciever);
        }
      }
    }
Code review comment: We don't want to call convert every time `getEmbedding` method is called.   ```suggestion         embedding = convertBase64ToFloatList(embeddingBase64);         return embedding; ```

Code under review:
public List<Float> getEmbedding() {
        if (embedding != null) {
            return embedding.stream().map(Double::floatValue).collect(Collectors.toList());
        }
        return convertBase64ToFloatList(embeddingBase64);
    }

Line commented on: return convertBase64ToFloatList(embeddingBase64);

Revised code:
public List<Float> getEmbedding() {
        if (embeddingInFloat == null && embeddingBase64 != null) {
            embeddingInFloat = convertBase64ToFloatList(embeddingBase64);
        }
        return embeddingInFloat;
    }
Code review comment: How did that manifest? 500ms timeout for process termination seems too aggressive. I would prefer a longer timeout to allow for connections to be closed gracefully.

Code under review:
private void stopProcess(String id, Process process) {
    if (process.isAlive()) {
      LOG.debug("Attempting to stop process with id {}", id);
      
      process.destroy();
      long maxTimeToWait = 500;
      try {
        if (waitForProcessToDie(process, maxTimeToWait)) {
          LOG.debug("Process for worker {} shut down gracefully.", id);
        }
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
      } finally {
        if (process.isAlive()) {
          LOG.info("Process for worker {} still running. Killing.", id);
          process.destroyForcibly();
        }
      }
    }
  }

Line commented on: long maxTimeToWait = 500;

Revised code:
private void stopProcess(String id, Process process) {
    if (process.isAlive()) {
      LOG.debug("Attempting to stop process with id {}", id);
      
      process.destroy();
      long maxTimeToWait = 500;
      try {
        if (waitForProcessToDie(process, maxTimeToWait)) {
          LOG.debug("Process for worker {} shut down gracefully.", id);
        }
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
      } finally {
        if (process.isAlive()) {
          LOG.info("Process for worker {} still running. Killing.", id);
          process.destroyForcibly();
        }
      }
    }
  }
Code review comment: Unlike HttpClient and HttpPipeline there is no default handling for HttpLogDetailLevel in the builder. This will end up passing in a null logging level into the logging policy and that will end up throwing a NullPointerException during execution. So add this prevent a consumer from getting further into the call stack to have an error occur.

Code under review:
public ConfigurationClientBuilder httpLogDetailLevel(HttpLogDetailLevel logLevel) {
        httpLogDetailLevel = Objects.requireNonNull(logLevel);
        return this;
    }

Line commented on: httpLogDetailLevel = Objects.requireNonNull(logLevel);

Revised code:
public ConfigurationClientBuilder httpLogDetailLevel(HttpLogDetailLevel logLevel) {
        httpLogDetailLevel = Objects.requireNonNull(logLevel);
        return this;
    }
Code review comment: Yeah, I just don't want to depend on some internal state that I might change. It can wait for the next HV release.

Code under review:
public void testCustomConfigurationViaBeans() {
        assertThat(validatorFactory.getClockProvider()).isInstanceOf(MyClockProvider.class);
        assertThat(validatorFactory.getConstraintValidatorFactory()).isInstanceOf(MyConstraintValidatorFactory.class);
        assertThat(validatorFactory.getMessageInterpolator()).isInstanceOf(MyMessageInterpolator.class);
        assertThat(validatorFactory.getParameterNameProvider()).isInstanceOf(MyParameterNameProvider.class);
        assertThat(validatorFactory.getTraversableResolver()).isInstanceOf(MyTraversableResolver.class);

        HibernateValidatorFactory hibernateValidatorFactory = validatorFactory.unwrap(HibernateValidatorFactory.class);
        assertThat(hibernateValidatorFactory.getScriptEvaluatorFactory()).isInstanceOf(MyScriptEvaluatorFactory.class);
        assertThat(hibernateValidatorFactory.getGetterPropertySelectionStrategy())
                .isInstanceOf(MyGetterPropertySelectionStrategy.class);
        
        
        
    }


Revised code:
public void testCustomConfigurationViaBeans() {
        assertThat(validatorFactory.getClockProvider()).isInstanceOf(MyClockProvider.class);
        assertThat(validatorFactory.getConstraintValidatorFactory()).isInstanceOf(MyConstraintValidatorFactory.class);
        assertThat(validatorFactory.getMessageInterpolator()).isInstanceOf(MyMessageInterpolator.class);
        assertThat(validatorFactory.getParameterNameProvider()).isInstanceOf(MyParameterNameProvider.class);
        assertThat(validatorFactory.getTraversableResolver()).isInstanceOf(MyTraversableResolver.class);

        HibernateValidatorFactory hibernateValidatorFactory = validatorFactory.unwrap(HibernateValidatorFactory.class);
        assertThat(hibernateValidatorFactory.getScriptEvaluatorFactory()).isInstanceOf(MyScriptEvaluatorFactory.class);
        assertThat(hibernateValidatorFactory.getGetterPropertySelectionStrategy())
                .isInstanceOf(MyGetterPropertySelectionStrategy.class);
        
        
        
    }
Code review comment: Hardcoding the asserts is not scaling in long term. Can we use the same approach as in the parser tests?

Code under review:
public void testKeys() throws IOException {
        InputStream inputStream = Thread.currentThread().getContextClassLoader()
                .getResourceAsStream("core/keys.toml");
        Toml read = Toml.read(inputStream);
        String basicKey = ((TomlStringValueNode) read.get("key")).getValue();
        String underscoreKey = ((TomlStringValueNode) read.get("underscore_key")).getValue();
        String dashKey = ((TomlStringValueNode) read.get("dash-key")).getValue();
        String intKey = ((TomlStringValueNode) read.get("1234")).getValue();

        String dottedString =
                ((TomlStringValueNode) read.getTable("127").getTable("0").getTable("0").get("1")).getValue();
        String spacing = ((TomlStringValueNode) read.get("character encoding")).getValue();
        String unicode = ((TomlStringValueNode) read.get("ʎǝʞ")).getValue();
        String general = ((TomlStringValueNode) read.get("key2")).getValue();
        String escape = ((TomlStringValueNode) read.get("quoted \"value\"")).getValue();

        Assert.assertEquals(basicKey, "basic key");
        Assert.assertEquals(underscoreKey, "Underscore Key");
        Assert.assertEquals(dashKey, "Dash Key");
        Assert.assertEquals(intKey, "Int Key");

        Assert.assertEquals(dottedString, "value");
        Assert.assertEquals(spacing, "value");
        Assert.assertEquals(unicode, "value");
        Assert.assertEquals(general, "value");
        Assert.assertEquals(escape, "value");
    }

Line commented on: Assert.assertEquals(unicode, "value");

Revised code:
public void testKeys() throws IOException {
        InputStream inputStream = Thread.currentThread().getContextClassLoader()
                .getResourceAsStream("syntax/core/keys.toml");
        Toml read = Toml.read(inputStream);
        String basicKey = ((TomlStringValueNode) read.get("key")).getValue();
        String underscoreKey = ((TomlStringValueNode) read.get("underscore_key")).getValue();
        String dashKey = ((TomlStringValueNode) read.get("dash-key")).getValue();
        String intKey = ((TomlStringValueNode) read.get("1234")).getValue();

        String dottedString =
                ((TomlStringValueNode) read.get("127.0.0.1")).getValue();
        String spacing = ((TomlStringValueNode) read.get("character encoding")).getValue();
        String unicode = ((TomlStringValueNode) read.get("ʎǝʞ")).getValue();
        String general = ((TomlStringValueNode) read.get("key2")).getValue();
        String escape = ((TomlStringValueNode) read.get("quoted \"value\"")).getValue();

        Assert.assertEquals(basicKey, "basic key");
        Assert.assertEquals(underscoreKey, "Underscore Key");
        Assert.assertEquals(dashKey, "Dash Key");
        Assert.assertEquals(intKey, "Int Key");

        Assert.assertEquals(dottedString, "value");
        Assert.assertEquals(spacing, "value");
        Assert.assertEquals(unicode, "value");
        Assert.assertEquals(general, "value");
        Assert.assertEquals(escape, "value");
    }
Code review comment: `seenPartitions` vs `distinctPartitions` I prefer the latter, because it is only used to remove duplication, and does not save all the partitions we have seen

Code under review:
private Void monitorAndGetSplits() throws Exception {
		stateLock.writeLock().lock();
		try {
			List<Tuple2<Partition, T>> partitions = fetcher.fetchPartitions(fetcherContext, currentReadOffset);
			if (partitions.isEmpty()) {
				return null;
			}

			partitions.sort(Comparator.comparing(o -> o.f1));
			List<HiveSourceSplit> newSplits = new ArrayList<>();
			
			T maxOffset = currentReadOffset;
			Set<List<String>> nextSeen = new HashSet<>();
			for (Tuple2<Partition, T> tuple2 : partitions) {
				Partition partition = tuple2.f0;
				List<String> partSpec = partition.getValues();
				if (seenPartitions.add(partSpec)) {
					T offset = tuple2.f1;
					if (offset.compareTo(currentReadOffset) > 0) {
						nextSeen.add(partSpec);
					}
					if (offset.compareTo(maxOffset) > 0) {
						maxOffset = offset;
					}
					LOG.info("Found new partition {} of table {}, generating splits for it",
							partSpec, tablePath.getFullName());
					newSplits.addAll(HiveSourceFileEnumerator.createInputSplits(
							0, Collections.singletonList(fetcherContext.toHiveTablePartition(partition)), jobConf));
				}
			}
			currentReadOffset = maxOffset;
			splitAssigner.addSplits(new ArrayList<>(newSplits));
			if (!nextSeen.isEmpty()) {
				seenPartitions.clear();
				seenPartitions.addAll(nextSeen);
			}
			return null;
		} finally {
			stateLock.writeLock().unlock();
		}
	}

Line commented on: seenPartitions.clear();

Revised code:
private Void monitorAndGetSplits() throws Exception {
		stateLock.writeLock().lock();
		try {
			List<Tuple2<Partition, T>> partitions = fetcher.fetchPartitions(fetcherContext, currentReadOffset);
			if (partitions.isEmpty()) {
				return null;
			}

			partitions.sort(Comparator.comparing(o -> o.f1));
			List<HiveSourceSplit> newSplits = new ArrayList<>();
			
			T maxOffset = currentReadOffset;
			Set<List<String>> nextSeen = new HashSet<>();
			for (Tuple2<Partition, T> tuple2 : partitions) {
				Partition partition = tuple2.f0;
				List<String> partSpec = partition.getValues();
				if (seenPartitionsSinceOffset.add(partSpec)) {
					T offset = tuple2.f1;
					if (offset.compareTo(currentReadOffset) > 0) {
						nextSeen.add(partSpec);
					}
					if (offset.compareTo(maxOffset) > 0) {
						maxOffset = offset;
					}
					LOG.info("Found new partition {} of table {}, generating splits for it",
							partSpec, tablePath.getFullName());
					newSplits.addAll(HiveSourceFileEnumerator.createInputSplits(
							0, Collections.singletonList(fetcherContext.toHiveTablePartition(partition)), jobConf));
				}
			}
			currentReadOffset = maxOffset;
			splitAssigner.addSplits(new ArrayList<>(newSplits));
			if (!nextSeen.isEmpty()) {
				seenPartitionsSinceOffset.clear();
				seenPartitionsSinceOffset.addAll(nextSeen);
			}
			return null;
		} finally {
			stateLock.writeLock().unlock();
		}
	}
Code review comment: add some comment to describe how to sample the partition

Code under review:
static List<String> getPartitionsSample(List<String> partitions, int sampleSize) {
        checkArgument(sampleSize > 0, "sampleSize is expected to be greater than zero");

        if (partitions.size() <= sampleSize) {
            return partitions;
        }

        List<String> result = new ArrayList<>();
        int left = sampleSize;
        String min = partitions.get(0);
        String max = partitions.get(0);
        for (String partition : partitions) {
            if (partition.compareTo(min) < 0) {
                min = partition;
            } else if (partition.compareTo(max) > 0) {
                max = partition;
            }
        }

        result.add(min);
        left--;
        if (left > 0) {
            result.add(max);
            left--;
        }

        if (left > 0) {
            HashFunction hashFunction = Hashing.murmur3_128();
            Comparator<Map.Entry<String, Long>> hashComparator = Map.Entry.<String, Long>comparingByValue()
                    .thenComparing(Map.Entry::getKey);

            partitions.stream()
                    .filter(partition -> !result.contains(partition))
                    .map(partition -> immutableEntry(partition, hashFunction.hashUnencodedChars(partition).asLong()))
                    .sorted(hashComparator)
                    .limit(left)
                    .forEachOrdered(entry -> result.add(entry.getKey()));
        }
        return Lists.newArrayList(result);
    }

Line commented on: if (partitions.size() <= sampleSize) {

Revised code:
static List<String> getPartitionsSample(List<String> partitions, int sampleSize) {
        checkArgument(sampleSize > 0, "sampleSize is expected to be greater than zero");

        if (partitions.size() <= sampleSize) {
            return partitions;
        }

        List<String> result = new ArrayList<>();
        int left = sampleSize;
        String min = partitions.get(0);
        String max = partitions.get(0);
        for (String partition : partitions) {
            if (partition.compareTo(min) < 0) {
                min = partition;
            } else if (partition.compareTo(max) > 0) {
                max = partition;
            }
        }

        result.add(min);
        left--;
        if (left > 0) {
            result.add(max);
            left--;
        }

        if (left > 0) {
            HashFunction hashFunction = Hashing.murmur3_128();
            Comparator<Map.Entry<String, Long>> hashComparator = Map.Entry.<String, Long>comparingByValue()
                    .thenComparing(Map.Entry::getKey);

            partitions.stream()
                    .filter(partition -> !result.contains(partition))
                    .map(partition -> immutableEntry(partition, hashFunction.hashUnencodedChars(partition).asLong()))
                    .sorted(hashComparator)
                    .limit(left)
                    .forEachOrdered(entry -> result.add(entry.getKey()));
        }
        return Lists.newArrayList(result);
    }
Code review comment: Wondering if it's beneficial to pass a value for "absolute" or not into the Builder so that this method doesn't need to be overridden with the same content in the two children?

Code under review:
protected ConfiguredPathInfo getRouteConfigInfo() {
            if (routeConfigKey == null) {
                return null;
            }
            if (routePath == null) {
                throw new RuntimeException("Cannot discover value of " + routeConfigKey
                        + " as no explicit path was specified and a route function is in use");
            }
            return new ConfiguredPathInfo(routeConfigKey, routePath, false);
        }

Line commented on: if (routeConfigKey == null) {

Revised code:
protected ConfiguredPathInfo getRouteConfigInfo() {
            if (routeConfigKey == null) {
                return null;
            }
            if (routePath == null) {
                throw new RuntimeException("Cannot discover value of " + routeConfigKey
                        + " as no explicit path was specified and a route function is in use");
            }
            if (absolutePath != null) {
                return new ConfiguredPathInfo(routeConfigKey, absolutePath, true);
            }
            return new ConfiguredPathInfo(routeConfigKey, routePath, false);
        }
Code review comment: This test will fail on any machine where the `CLOUDSDK_COMPUTE_REGION` is defined or `gcloud config compute/region` is set.  You can test your code by instantiating the DefaultGcpRegionFactory directly and ensuring that it is factored in such a way where you can pass in the environment map directly to it and similarly for testing the process execution.

Code under review:
public void testDefaultGcpRegion() {
    DataflowPipelineOptions options = PipelineOptionsFactory.as(DataflowPipelineOptions.class);
    assertEquals("us-central1", options.getRegion());
  }

Line commented on: assertEquals("us-central1", options.getRegion());

Revised code:
public void testDefaultGcpRegion() {
    DataflowPipelineOptions options = PipelineOptionsFactory.as(DataflowPipelineOptions.class);
    assertEquals("us-central1", options.getRegion());
  }
Code review comment: Shouldn't this be XOR instead of OR, otherwise `softRebuild` is superset of `rebuild`?

Code under review:
public NodeList rebuilding(boolean soft) {
        return matching(node -> (soft || node.status().wantToRetire()) && node.status().wantToRebuild());
    }

Line commented on: return matching(node -> (soft || node.status().wantToRetire()) && node.status().wantToRebuild());

Revised code:
public NodeList rebuilding(boolean soft) {
        return matching(node -> {
            if (soft) {
                return !node.status().wantToRetire() && node.status().wantToRebuild();
            }
            return node.status().wantToRetire() && node.status().wantToRebuild();
        });
    }
Code review comment: I guess the below `Preconditions.checkState(results.size() < maxCheckpoints, "results.size() > maxCheckpoints", results.size(), maxCheckpoints);` might be invalid if we remove the old ones here?

Code under review:
public void start(long checkpointId, CheckpointOptions checkpointOptions) {
		results.keySet().forEach(oldCheckpointId -> abort(oldCheckpointId, new Exception("Starting new checkpoint " + checkpointId)));
		LOG.debug("start checkpoint {} ({})", checkpointId, checkpointOptions);
		ChannelStateWriteResult result = new ChannelStateWriteResult();
		ChannelStateWriteResult put = results.computeIfAbsent(checkpointId, id -> {
			Preconditions.checkState(results.size() < maxCheckpoints, "results.size() > maxCheckpoints", results.size(), maxCheckpoints);
			enqueue(new CheckpointStartRequest(checkpointId, result, checkpointOptions.getTargetLocation()), false);
			return result;
		});
		Preconditions.checkArgument(put == result, "result future already present for checkpoint id: " + checkpointId);
	}

Line commented on: results.keySet().forEach(oldCheckpointId -> abort(oldCheckpointId, new Exception("Starting new checkpoint " + checkpointId)));

Revised code:
public void start(long checkpointId, CheckpointOptions checkpointOptions) {
		results.keySet().forEach(oldCheckpointId -> abort(oldCheckpointId, new Exception("Starting new checkpoint " + checkpointId)));
		LOG.debug("start checkpoint {} ({})", checkpointId, checkpointOptions);
		ChannelStateWriteResult result = new ChannelStateWriteResult();
		ChannelStateWriteResult put = results.computeIfAbsent(checkpointId, id -> {
			Preconditions.checkState(results.size() < maxCheckpoints, "results.size() > maxCheckpoints", results.size(), maxCheckpoints);
			enqueue(new CheckpointStartRequest(checkpointId, result, checkpointOptions.getTargetLocation()), false);
			return result;
		});
		Preconditions.checkArgument(put == result, "result future already present for checkpoint id: " + checkpointId);
	}
Code review comment: spring has api to do this thing, we should leverage that instead of dealing with these stream by ourselves ( I understand this is easy, but still)  `org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration#loadSource`

Code under review:
private static String getVersion() {
        String version = "unknown";
        Properties properties = new Properties();
        try (InputStream inputStream =
                 new FileInputStream(ResourceUtils.getFile("classpath:azure-spring-boot-version.txt"))) {
            properties.load(inputStream);
            version = properties.getProperty("version");
        } catch (IOException e) {
            LOGGER.warn("Can not get version.");
        }
        return version;
    }

Line commented on: try (InputStream inputStream =

Revised code:
private static String getVersion() {
        String version = "unknown";
        try {
            Properties properties = PropertiesLoaderUtils.loadProperties(
                new ClassPathResource("project.properties"));
            version = properties.getProperty("version");
        } catch (IOException e) {
            LOGGER.warn("Can not get version.");
        }
        return version;
    }
Code review comment: should also test other metric types

Code under review:
public void testStatsDMetersReportingOfNegativeValues() throws Exception {
		MetricRegistryImpl registry = null;
		DatagramSocketReceiver receiver = null;
		Thread receiverThread = null;
		long timeout = 5000;
		long joinTimeout = 30000;

		String meterName = "meter";

		try {
			receiver = new DatagramSocketReceiver();

			receiverThread = new Thread(receiver);

			receiverThread.start();

			int port = receiver.getPort();

			MetricConfig config = new MetricConfig();
			config.setProperty(ConfigConstants.METRICS_REPORTER_INTERVAL_SUFFIX, "1 SECONDS");
			config.setProperty("host", "localhost");
			config.setProperty("port", String.valueOf(port));

			registry = new MetricRegistryImpl(
				MetricRegistryConfiguration.defaultMetricRegistryConfiguration(),
				Collections.singletonList(ReporterSetup.forReporter("test", config, new StatsDReporter())));
			TaskManagerMetricGroup metricGroup = new TaskManagerMetricGroup(registry, "localhost", "tmId");
			TestMeter meter = new TestMeter(-50, -5.3);
			metricGroup.meter(meterName, meter);
			String prefix = metricGroup.getMetricIdentifier(meterName);

			Set<String> expectedLines = new HashSet<>();

			expectedLines.add(prefix + ".rate:0|g");
			expectedLines.add(prefix + ".rate:-5.3|g");
			expectedLines.add(prefix + ".count:0|g");
			expectedLines.add(prefix + ".count:-50|g");

			receiver.waitUntilNumLines(expectedLines.size(), timeout);

			Set<String> lines = receiver.getLines();

			assertEquals(expectedLines, lines);

		} finally {
			if (registry != null) {
				registry.shutdown().get();
			}

			if (receiver != null) {
				receiver.stop();
			}

			if (receiverThread != null) {
				receiverThread.join(joinTimeout);
			}
		}
	}

Line commented on: TestMeter meter = new TestMeter(-50, -5.3);

Revised code:
public void testStatsDMetersReportingOfNegativeValues() throws Exception {
		Set<String> expectedLines = new HashSet<>();
		expectedLines.add("metric.rate:0|g");
		expectedLines.add("metric.rate:-5.3|g");
		expectedLines.add("metric.count:0|g");
		expectedLines.add("metric.count:-50|g");

		testMetricAndAssert(new TestMeter(-50, -5.3), "metric", expectedLines);
	}