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

js: handle 408 fetch requests pending status #967

Merged
merged 1 commit into from May 3, 2022
Merged

Conversation

wallyqs
Copy link
Member

@wallyqs wallyqs commented May 2, 2022

For fetch batches of n > 1, sometimes the client would receive a 408 Requests Pending status messages for Fetch requests (initial request with no wait + expires time) which resulted in the client skipping these errors until reaching the deadline.
In this PR we add special handling for this status so that the client makes a request without no_wait after getting a 408 status with requests pending.
Signed-off-by: Waldemar Quevedo wally@nats.io

@derekcollison
Copy link
Member

@jnmoyne use case was batch == 2 IIRC?

@wallyqs wallyqs requested a review from jnmoyne May 2, 2022 21:53
@wallyqs wallyqs force-pushed the fetch-req-pending branch 3 times, most recently from c52f9c2 to 556d8be Compare May 2, 2022 22:09
@coveralls
Copy link

coveralls commented May 2, 2022

Coverage Status

Coverage decreased (-0.0004%) to 83.85% when pulling 5be4ec5 on fetch-req-pending into 9c077d0 on main.

Copy link
Member

@kozlovic kozlovic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably need to rationalize what those 408 various responses mean from the server perspective and how to react to those. I am not clear on that.

js.go Outdated
@@ -2558,7 +2573,8 @@ func (sub *Subscription) Fetch(batch int, opts ...PullOpt) ([]*Msg, error) {
// are no messages.
msg, err = sub.nextMsgWithContext(ctx, true, false)
if err != nil {
if err == errNoMessages {
// We skip both 404 and any type of 408 errors at this stage.
if err == errNoMessages || err == errRequestsPending {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will have no effect. We just called sub.nextMsgWithContext(), which is a low-level NATS call, but since we indicate that this is an internal pull call, it will return errNoMessages if there was no message and not go into a wait. You can check that function for details, but there is no way this function returns errRequestsPending since I don't see that you added that outside of checkMsg().

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the review, removed the check since it had no effect

js.go Outdated
err = ErrTimeout
// In case of a fetch request with no wait request and expires time,
// it will be a 408 error but with a Requests Pending description.
desc := msg.Header.Get(descrHdr)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From looking at server code, there are several possible descriptions for 408 (so far..): "Interest Expired", "Requests Pending", "Request Canceled" and "Request Timeout".
We need to think if we need to behave any differently for those error status or not. I am not sure. Depending on that answer, we can decide if we need to distinguish description or not.. (again, there are more than that one, and some may be added in the future).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about the rest of the status at the moment but I think one way to simplify this could be to refactor the code to skip 408s unless making the initial expires + no wait batch request.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of those mean the request is no longer valid and no additional messages will be sent for that request.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to just check that it was a 408 from a no wait request instead of checking that it is a Requests Pending, this will have the same effect and avoid the timeouts that @jnmoyne was running into.

@wallyqs wallyqs marked this pull request as ready for review May 3, 2022 20:36
Copy link
Member

@kozlovic kozlovic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Skip 408 errors thrown to client no wait + expires requests

Signed-off-by: Waldemar Quevedo <wally@nats.io>
@wallyqs wallyqs merged commit 96c1445 into main May 3, 2022
@wallyqs wallyqs deleted the fetch-req-pending branch May 3, 2022 23:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants