Description
What is the bug?
The various clients exposed by SDKClient
include this warning in the initialize()
methods:
The user is responsible for calling {@link #doCloseJavaClients()} when finished with the client
This is possible with the SDKRestClient
which delegates its close()
method to the internal RestHighLevelClient and implements Closeable. Users can simply use a try-with-resources to wrap their usage of the client.
However, a "responsible" user can't really do that safely for the Java Clients (OpenSearchAsyncClient
and OpenSearchClient
) because:
- Neither of these clients exposes a
close()
method nor implementCloseable
- Initializing either of these clients sets the same
RestClient
class field, which is the real thing that needs to be closed - We could work around this multithreading issue by instantiating a new
SDKClient()
each time, but with thegetActions()
functionality they require initialization so we are using a singletonSDKClient
object. - So ultimately we are working around this in AD work by initializing a single Sync OR Async client at the Extension level and passing it around. This works effectively but we never close it per the docs.
How can one reproduce the bug?
Call SDKClient.initializeJavaClient and initializeJavaAsyncClient from separate threads using different host/port options, and watch chaos commence. (Actually I think even connecting with the same host/port will create a different connection and could interrupt in-progress calls. And this may be the source of some flaky results we're seeing.)
What is the expected behavior?
Users have the ability to use try-finally in a Rest Handler implementation:
try (OpenSearchClient client = someMethod()) {
// do stuff
} finally {
// some method that safely closes client
}
Alternately, enforce the singleton nature of each client and do not share the same RestClient
between multiple clients and provide an easier closing method than the existing call to close all clients.
Do you have any additional context?
We will soon be adding headers to the client RequestOptions
(See #430) and these need to be per-call, requiring additional localization of these transport calls and a desire for open/close in the same Rest Handler.
I am not sure of the best approach but I'm certain that what we have is not it.