-
Notifications
You must be signed in to change notification settings - Fork 981
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
middleware_mutex
is racey.
#1065
Comments
If you run this on JRuby, |
Thanks for analysis! |
It's quite interesting to see |
@eregon Yeah, I was surprised by that too. Can we dump the instructions to see what is actually going on? |
So if defined?(@middleware_mutex)
@middleware_mutex
else
@middleware_mutex = expression
end To make it not override in MRI we'd need: if defined?(@middleware_mutex)
@middleware_mutex
else
result = expression
# special bytecode to do `@middleware_mutex = result unless defined?(@middleware_mutex)` atomically
end Of course that has a cost as it's an extra check before assigning. And the block would still execute multiple times, trying to fix that automatically would likely lead to deadlock and high overhead, so that part is best left to user code. |
Oh, I totally agree this isn't something we can fix automatically, the code is horribly broken from the POV of thread safety and making ||= atomic won't fix that. |
Wow thanks for the analysis @ioquatix and once again your expertise around this topic can clearly be seen. Today, we don't officially support JRuby and other non-MRI rubies anymore, mostly because I think we lack the necessary knowledge to do so, but we just left that untouched in the hope it would at least help. I'm not really sure how to tackle this, if you or @eregon could point us in the right direction I'd be happy to gain some knowledge and have a look 🤓 |
This is also a bug on CRuby. I can submit a PR. |
I tried one solution in #1074. I have another idea that involves converting the faraday/lib/faraday/response.rb Lines 26 to 28 in d51a6c6
It could be something like: module Faraday
class Response
self.middleware_registry = MiddlewareRegistry.new(File.expand_path('response', __dir__),
raise_error: [:RaiseError, 'raise_error'],
logger: [:Logger, 'logger'],
) This doesn't rely on class lifecycle hooks. It's pretty clear that class MiddlewareRegistry
def initialize
@mutex = Monitor.new
end
end |
Here is example output on 2.6:
Here is example output on jruby:
The text was updated successfully, but these errors were encountered: