Skip to content

Conversation

@javanna
Copy link
Member

@javanna javanna commented Mar 27, 2018

When the BulkProcessor is used with the high-level REST client, a scheduler is internally created that allows to schedule tasks. Such scheduler is not exposed to users and needs to be closed once the BulkProcessor is closed. There are two ways to close the BulkProcessor though, one is the ordinary close method and the other one is awaitClose. The former closes the scheduler while the latter doesn't, leaving threads lingering.

I discovered this when adding some tests for the bulk processor, as we mainly test it with the transport client, and the same tests run with the high-level REST client already uncovered a bug.

When the `BulkProcessor` is used with the high-level REST client, a scheduler is internally created that allows to schedule tasks. Such scheduler is not exposed to users and needs to be closed once the `BulkProcessor` is closed. There are two ways to close the `BulkProcessor` though, one is the ordinary `close` method and the other one is `awaitClose`. The former closes the scheduler while the latter doesn't, leaving threads lingering.

I discovered this when adding some tests for the bulk processor, as we mainly test it with the transport client, and the same tests run with the high-level REST client already uncovered a bug.
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra

Copy link
Member

@nik9000 nik9000 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Member

@tlrx tlrx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great, thanks a lot for all the tests. I added minor comments.

Response response = client().performRequest("PUT", "/test-ro", Collections.emptyMap(), entity);
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));

//ensureGreen();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can you remove this?

try (BulkProcessor processor = initBulkProcessorBuilder(listener)
.setConcurrentRequests(concurrentRequests).setBulkActions(bulkActions)
//set interval and size to high values
.setFlushInterval(TimeValue.timeValueHours(24)).setBulkSize(new ByteSizeValue(1, ByteSizeUnit.GB)).build()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like we always use these values, maybe we could set them in initBulkProcessorBuilder?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we almost always use the same values, but not exactly the same, there are subtle differences. I took these tests from the existing BulkProcessorIT tests, and adapted them from transport client to rest high level client. The idea was to not touch anything and see if things still work the same way, which they kind of do (up to bugs)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay

}
return this.bulkRequestHandler.awaitClose(timeout, unit);
boolean awaitClose = this.bulkRequestHandler.awaitClose(timeout, unit);
onClose.run();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if we should ensure that the onClose.run() is always executed (like in a finally block) if something goes wrong in bulkRequestHandler.awaitClose(). I don't have a strong feeling about this, and if we decide to add it we should also have a test for it, but I think it would be safer.

Copy link
Member

@tlrx tlrx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@javanna javanna merged commit 245dd73 into elastic:master Mar 28, 2018
javanna added a commit that referenced this pull request Mar 28, 2018
When the `BulkProcessor` is used with the high-level REST client, a scheduler is internally created that allows to schedule tasks. Such scheduler is not exposed to users and needs to be closed once the `BulkProcessor` is closed. There are two ways to close the `BulkProcessor` though, one is the ordinary `close` method and the other one is `awaitClose`. The former closes the scheduler while the latter doesn't, leaving threads lingering.
javanna added a commit that referenced this pull request Mar 28, 2018
When the `BulkProcessor` is used with the high-level REST client, a scheduler is internally created that allows to schedule tasks. Such scheduler is not exposed to users and needs to be closed once the `BulkProcessor` is closed. There are two ways to close the `BulkProcessor` though, one is the ordinary `close` method and the other one is `awaitClose`. The former closes the scheduler while the latter doesn't, leaving threads lingering.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants