-
Notifications
You must be signed in to change notification settings - Fork 379
feat: make both feed versions race together #5287
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
base: master
Are you sure you want to change the base?
Conversation
e4c7458 to
4a65577
Compare
|
This looks great. However, the racing mechanism introduces some trade-offs for feed v2 payloads that happen to be 48 or 80 bytes. Proposal: Add a dedicated v2 feed endpoint that always uses v2 resolution without any automatic racing:
|
|
Thanks @gacevicljubisa.
I think that maybe having a header to instruct the API how to do the lookup might be a bit nicer (and easier to break in the future - API paths are more difficult). But also we could maybe wait to see how people will use this (and thus request the feature which is most desirable). |
This is a prefix that applies to the entire API so I think it's out of context. For the version to version the feeds endpoint we need it to be hierarchically further "down" the path. |
a125395 to
909173c
Compare
|
| defer cancel() | ||
| if !both { | ||
| if resolving == "v2" { | ||
| return result.ch, resolving, nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In practice we can also have here result.err != nil , right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the problem here, the answer unfortunately is "no". Have a look at the PR description - this issue is documented thoroughly. The problem is the v2 can be either a manifest address OR actual data. This means that you can't "lookup what v2 references" because it may unmarshal as junk in case it is 48/80 bytes long data verbatim which is allowed.
| case result := <-other: | ||
| if !result.v1 { | ||
| // resolving v2 | ||
| return result.ch, resolving, nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, in practice we can also have here result.err != nil , right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
pkg/api/bzz.go
Outdated
| // should fetch both feed versions. if the length isn't v1 | ||
| // then we should only try to fetch v2. | ||
| var ( | ||
| v1, v2 chan getWrappedResult |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For future references I think the naming here will be confusing in the future as v1 is also a bool in getWrappedResult struct and used above. Would be nice a small naming refactoring.
|
Thanks @Cafe137. |
| // if it returns an error we send that over the channel, otherwise | ||
| // we send the wc chunk back to the caller so that the feed can be | ||
| // dereferenced. | ||
| _, err = getter.Get(innerCtx, wc.Address()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this redundant, as in GetWrappedChunk we have a getter.Get(...) that returns nil, err if err, or wc, nil ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately no. GetWrappedChunk only calls Get on the legacy payload, not on a v2 type chunk. Also here, notice that we send the error on the channel, but also whether it is a v1 or v2 payload. Because v2 cannot technically error, we must short-circuit the error and return the payload anyway.
Checklist
Description
Races both feed versions for backwards-compatibility in the bzz endpoint.
Fixes #5280
There's a couple of issues that took quite a bit of time to trace and so for posterity I will describe them here:
TestFeed_Get/legacy_payload_with_non_existing_wrapped_chunk), since the outcome of the test depends on the order of resolution of the goroutines that race the chunks. If v2 gets checked first and only then v1, then the test passes (because v1 returns an error), but if v1 gets checked first and only then v2, the test fails because we can never return an error for v2, as mentioned above. I suggest to disable the test but leaving it there with a comment/reference to this PR.Open API Spec Version Changes (if applicable)
Motivation and Context (Optional)
Related Issue (Optional)
Screenshots (if appropriate):