-
Notifications
You must be signed in to change notification settings - Fork 62
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
RedisClient::ProtocolError: Unknown sigil type: "\r" #190
Comments
Thanks for the report, this is very likely caused by the recent changes in redis-client, I'll look into it tomorrow. |
I forgot to ask if you could share the full backtrace. |
I'd also need to know if you connect with a UNIX socket, regular TCP, or SSL. |
Tentative fix for #190 I wasn't able to reproduce, not to really figure out the root cause. `Unknown sigil type: "\r"` suggest we corrupted the offset after calling `gets_integer`. When we read `\r` we assume `\n` is next but don't check if we read it yet, and just increment the offset, and the offset can potentially be past the buffer. I don't know how it happens exactly, but somehow we sometimes don't handle this case properly. The fact that it was reported with a `pubsub` use case suggest it might be after a read timeout, but can't be certain.
@erikkessler1 I tried the repro by crafting specific responses but couldn't figure it out. I still made a tentative fix in #191, I'd appreciate if you could try it in your app and report back whether it fixes the issue. |
Unfortunately, it looks like it still happens with that fix. The connection is SSL and here is the backtrace:
This is the error with the patch and state of
|
Thank you. SSL socket changes a lot of things. Can you share your Ruby and |
I think I got a repro using SSL:
|
Here are my OpenSSL versions: OpenSSL::VERSION
#=> "3.2.0"
OpenSSL::OPENSSL_LIBRARY_VERSION
#=> "OpenSSL 1.1.1w 11 Sep 2023" |
Alright, I figured the root cause. With a regular socket But with |
Awesome, great find! 🎉 |
Fix: #190 ```ruby buff = "blah".b p io.read_nonblock(10, buffer, exception: false) # :wait_readable p buff ``` The above code when using a regular Ruby IO socket leaves the buffer intact, because it only replaces the content if it actually read something. However when using a `SSLSocket`, the buffer is always cleared regardless of whether something was read or not. This difference could cause the offset to be corrupted by pointing forward.
@erikkessler1 could you try #193 ? I just want to make sure I fixed the same bug you are experiencing (we never know). |
After running things with that patch for 15 minutes I haven't seen the error again (usually would have seen it every few minutes), so I'd say that was the issue. Thank you for the quick fix! |
Welcome. I need to fix a few things on CI and will try to write a test for this (tricky) and I'll cut a release soon. |
Fix: #190 ```ruby buff = "blah".b p io.read_nonblock(10, buffer, exception: false) # :wait_readable p buff ``` The above code when using a regular Ruby IO socket leaves the buffer intact, because it only replaces the content if it actually read something. However when using a `SSLSocket`, the buffer is always cleared regardless of whether something was read or not. This difference could cause the offset to be corrupted by pointing forward.
|
Upstream PR: ruby/openssl#739 |
I have a pubsub connection that will will intermittently hit a
RedisClient::ProtocolError
:This seems to have started with just recently with version 0.22.0.
From patching the
rescue RedisClient::RESP3::UnknownType
inRedisClient::RubyConnection#read
to print the current@io
object and waiting for the error to happen, it looks like the@io
object is the following state:I haven't been able to reproduce the error deterministically, unfortunately, but this is roughly what I've used to reproduce it in a production application:
The text was updated successfully, but these errors were encountered: