Skip to content
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

interleave read and write on pipelined_get (#776, #941) #942

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

marvinthepa
Copy link

@marvinthepa marvinthepa commented Dec 10, 2022

fixes #776.
fixes #941.

When reading a large number of keys, memcached starts sending the
response when dalli is not yet finished sending the request.

As we did not start reading the response until we were finished writing
the request, this could lead to the following problem:

  • the receive buffer (rcvbuf) would fill up
  • due to TCP backpressure, memcached would stop sending (okay as we are
    not reading anyway), but also stop reading
  • the send buffer (sndbuf) would also fill up
  • as we were using a blocking write without timeout, we would block
    forever (at least with ruby < 3.2, which introduces IO::Timeout, see
    IO::TimeoutError exceptions are not handled, breaking automatic retry #967)

This is addressed by using IO::select on the sockets for both read and
write, and thus start reading as soon as data is available.

@marvinthepa marvinthepa force-pushed the interleaved_fetch branch 3 times, most recently from 350d7b4 to 03ad88e Compare December 12, 2022 07:18
@petergoldstein
Copy link
Owner

There's a bit of "devil in the details", but directionally this looks correct. Thanks for drafting @marvinthepa . With a little back and forth we can almost certainly get this in.

@marvinthepa
Copy link
Author

Thanks for drafting @marvinthepa

Happy to give back and spend some company time on a library we have been using for a few years now..

@marvinthepa marvinthepa marked this pull request as draft November 1, 2024 11:40
@marvinthepa marvinthepa force-pushed the interleaved_fetch branch 3 times, most recently from 427f027 to 6493f3d Compare November 2, 2024 09:27
@marvinthepa marvinthepa changed the title WIP: first attempt at #776 / #941 interleave read and write on pipelined_get (#776, #941) Nov 2, 2024
@marvinthepa marvinthepa marked this pull request as ready for review November 2, 2024 09:41
@marvinthepa
Copy link
Author

@petergoldstein sorry for not following up on this PR for so long, but I found some time and hope I can manage to get this ready to integrate in the next weeks.

I rebased on main, fixing the conflicts with especially #963 - so maybe if @casperisfine could check this PR as well it would be highly appreciated.

I am still not 100% confident if the error handling is completely correct, but I was not able to find a flaw (at least not one that did not exist before anyway) after some time searching for one.

fixes petergoldstein#776.
fixes petergoldstein#941.

When reading a large number of keys, memcached starts sending the
response when dalli is not yet finished sending the request.

As we did not start reading the response until we were finished writing
the request, this could lead to the following problem:

* the receive buffer (rcvbuf) would fill up
* due to TCP backpressure, memcached would stop sending (okay as we are
  not reading anyway), but also stop reading
* the send buffer (sndbuf) would also fill up
* as we were using a blocking write without timeout, we would block
  forever (at least with ruby < 3.2, which introduces IO::Timeout, see
  petergoldstein#967)

This is addressed by using IO::select on the sockets for both read and
write, and thus start reading as soon as data is available.
@marvinthepa
Copy link
Author

Back to draft, as I think I found a problem relating to #963, where the connection is unnecessarily closed during a pipelined get. sigh.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants