-
Notifications
You must be signed in to change notification settings - Fork 171
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
#318 avoid losing an element in leveldb seeker #320
Conversation
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.
The code looks good, it should fix the issue. Also thanks for the regression test!
But I'm actually wondering whether we should just remove that comment? Checking the history I found that the comment was added by a bigger refactoring last week, but the iterator implementation actually did not change as far as I remember.
So maybe just the comment is wrong and after removing it we should be fine?
What do you think?
It's not just a comment. There are two implementations with different semantics. In this patch, I changed the leveldb one to match the comment on the common interface. I'm fine if patching the memory iterator is preferred. The important thing is that all implementations have the same semantics. |
Just noticed there is an old related issue: #181 |
Yep, so it seems that something is quite odd here. I took the comments from the old branch mentioned in #181 because I thought it was improving storage, but actually that branch was adding some layer to track offsets along with keys for some retention-cleanup that we will probably not add. |
Agreed. When I surveyed the implementations (memory, redis, merged, leveldb), it looked like all of them were compatible with calling I agree with your reasoning. Let's fix the comment and the memory iterator. |
Wait what? But if all are compatible with calling |
It comes down to memory vs leveldb. Redis' seek is a noop. The merged iterator is primarily used with leveldb. And I'm getting the impression that LevelDB is probably the only one used in production. Given that, I'd rather avoid a hack in production code. Thoughts? |
Yep, agreeing to that. So let's not use a hack, fix the comment and memory iterator. Just got a bit confused by your earlier comment, because it sounded that "next" after "seek" works, but it doesn't without losing one element. |
@mrahs, while you're on it, could you maybe also replace the type |
My bad 🤦 |
8658538
to
2fb25b0
Compare
@mrahs, would you by any chance have any progress on the PR? |
Sorry for the silence. I've been meaning to wrap this up asap, but life got busy. I'll update the PR later today. |
Using goka.Headers enables implementations of the view callback to avoid importing Sarama as a dependency. However, it is a breaking change that requires all users to update their implementations to explicitly accept the headers argument.
- Corrected the comment on the iterator interface to match LevelDB semantics. All other implementations were compatible with LevelDB except for the memory iterator which is also fixed in this change set. - Updated the memory iterator to be semantically compatible with LevelDB. Iterators traverse the storage using ordered keys and Seek no longer replaces the iterators view.
This should make it easier to implement and extend the behaviour of the callback. Also introduced a default implementation that should be sufficient for most use cases.
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.
Looks good, many thanks for the extra changes. Your contribution is really appreciated here!!
I think we can leave it like this, so we can go forward :).
One question though: the conversion between sarama headers and goka-headers is now moved to its own structure. But the only two places where it's being stored for lazy-conversion is the cbContext
and the UpdateContext
, whereas both could also just store the sarama.Headers and convert on request.
It just seems a bit of overkill to me to have this rather complex Headers
structure supporting both header-types, with things like eval
, Len
, ToSaramaPtr
, ToSarama
and all that, which is mostly needed for testing, instead of the simpler way like before. So I'm just wondering if I'm missing the bigger picture here why this complexity is needed? :)
But again, thanks a lot for your work and your time on all that!
Thanks Franz! The last iteration attempts to satisfy the following requirements and constraints:
Now all of this can still be achieved with a simpler header type of Now that I've typed this, I believe it should be possible to change the proxy interface to use the func (s *storageProxy) Update(ctx UpdateContext, k string, v []byte) error {
return s.update(ctx, s, k, v)
} I've just tried this out and it looks better. The headers are |
Awesome, that looks even better! |
This fix covers iterators for partition tables.
Views use the merge iterator which was not affected by the bug due to calling
Next
upon initialization and caching the pair before callingNext
again (which was perfect forSeek
).That means the merge iterator would have paniced with other implementations such as in-memory which is used the tester package. I have added a test case to demonstrate the panic and the fix.