New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Are clients thread-safe? #14
Comments
In my experience it's quite hard to prove something is threadsafe, as opposed to proving it isn't. The library itself and every |
Thanks! I'll start off with the assumption that the |
That'd be great, thanks! |
Technically no. From what I've seen in the code so far, the underlying transport is not thread-safe. In particular, Though I'd prefer this to be addressed, in practice as long as you're using a thread-safe HTTP transport with Faraday, you probably won't see much trouble. We're using it in Sidekiq and haven't run into anything in particular. |
Ae per comment from @kimchy - "Yes, the NodeClient is thread safe (any Client is thread safe, also the TransportClient) and its lifecycle should be similar to the application lifecycle." (http://elasticsearch-users.115913.n3.nabble.com/Is-NodeClient-thread-safe-td2816264.html) But, I would like to know how client handles multiple requests at same time? Will requests queue up? Or does it have a connection pool implemented? Are there some configuration exposed to specify the pool size / concurrent threads etc for NodeClient java API. Thanks |
@ggauravuee Your question seems to be for the Java client -- the mailing list or the Github issues for the main elasticsearch repo are the best place to ask. The Ruby client should be threadsafe in the Ruby environment. |
@karmi "The Ruby client should be threadsafe in the Ruby environment" - is this because of the assumption of the GIL? I'm working in JRuby, which doesn't have a GIL. Is the same assumption valid? |
@cheald No assumptions about GIL -- the statement just means that I'm not aware by any code which would flat out violate thread-safeness (class variables and such) on top of my head. The client is used in thread-safe sensitive environments (eg. Heroku) and seems to run just fine. Of course, any hypothesis like that can be proved wrong :) |
I've dug through the entire I'm using Faraday under the hood. I didn't really care to debug it so I just built a subclass of |
@hydrogen18 this was my assessment as well (see my first post above). Doesn't look like much has changed for the better since then. @karmi we should clarify the question, as it seems like you're discussing thread-safety in a global sense (class variables, global state), whereas I believe @hydrogen18 and I are referring to a single instance of |
Simple demo on JRuby 1.17.19 and elasticsearch-ruby 1.0.12. The failures on one thread are visible without any protection in another.
My output
|
@hydrogen18 unless I'm missing something, your example is actually to be expected I believe—even if the client was thread-safe. As long as the view of the transport's connections and their state is consistent across threads (in this case, one failure of a non-existent host), things are working properly. What you wouldn't want to see is an inconsistent state across threads, and that's actually a little tricky to reproduce since it requires concurrent mutation of that state. |
My demonstration shows that instances of |
I don't see any problem with connections being shared across threads, since Faraday is thread-safe—in fact, that's kind of the point of a shared instance, and is what you want. The only potential thread-safety issue I see is with the connection failure state of the pool being inconsistent across threads, but that would only affect certain failure scenarios. Can you give a bit more detail on the problem are you running into? You mentioned something attempting to invoke a method on |
I've never seen any documentation indicating that Faraday is thread safe. Could you point me in the direction of what you are referring to? |
The demonstration above doesn't really indicate lack of thread-safety, simply that the same connection can be handed to multiple threads at the same time. As long as the connection itself is thread-safe, things should be fine. I can't vouch for Faraday's thread-safety though. If you're on JRuby, then you should consider the Manticore transport instead - it is explicitly threadsafe. Manticore has a Faraday adapter, as well, and while the adapter itself should be threadsafe, I can't say whether Faraday itself is. You might try that as a drop-in replacement though, and see how that works. |
Consider this code from Transport::Connections::Selector::RoundRobin
suppose there is only 1 connection in the connections array. thread 1 does: |
I'm wondering it I can share
Elasticsearch::Client
instances across multiple threads, or should I instantiate a new one per request/thread?The text was updated successfully, but these errors were encountered: