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

Iter empty db #37

Merged
merged 6 commits into from
Aug 4, 2018
Merged

Iter empty db #37

merged 6 commits into from
Aug 4, 2018

Conversation

danburkert
Copy link
Owner

This is a rollup of #7, #28, and #29, as well as a follow up commit of my own. This should fix the empty database panic issue. Thanks to @tarcieri @marshallpierce and @mykmelez for helping with this!

@mykmelez
Copy link
Contributor

mykmelez commented Aug 3, 2018

Thanks @danburkert, your last change looks good to me.

I do think it'd make sense to return Result instead of panicking on Err for all of the Cursor::iter*() methods (and, more generally, all public methods of this library), so consumers have better control over handling of error conditions.

Nevertheless, that's an orthogonal change that can be considered separately. And in the meantime it makes sense for Cursor::iter_dup_of() to return the same type as the other methods.

@danburkert
Copy link
Owner Author

I do think it'd make sense to return Result instead of panicking on Err for all of the Cursor::iter*() methods (and, more generally, all public methods of this library), so consumers have better control over handling of error conditions.

I agree 100% that lmdb should not panic, and should not use panicking as an error handling strategy, but I'm not aware of any ways in which these methods can fail (other than the issues which this patch addresses). Is there an error condition I'm overlooking?

@danburkert
Copy link
Owner Author

(and obviously the issues you pointed out in #32 can cause everything to go off the rails, but that needs to be handled by tweaking the lifetime rules to cause problematic uses of the iterators to fail to compile)

@mykmelez
Copy link
Contributor

mykmelez commented Aug 3, 2018

I agree 100% that lmdb should not panic, and should not use panicking as an error handling strategy, but I'm not aware of any ways in which these methods can fail (other than the issues which this patch addresses). Is there an error condition I'm overlooking?

I'm also not aware of any other ways in which these methods can fail. My statement was just a general one. I'm glad to hear you agree! Would you be amenable to a pull request that made these methods return Result<Iter|IterDup, Err>?

@danburkert
Copy link
Owner Author

Would you be amenable to a pull request that made these methods return Result<Iter|IterDup, Err>?

No, because I'm not aware of any situations in which they can fail. There are panic! calls in the implementation, but if those are triggered it indicates a bug in this library, not something a caller can handle. If you have an example of non-bug panics I would reconsider, though.

@mykmelez
Copy link
Contributor

mykmelez commented Aug 3, 2018

No, because I'm not aware of any situations in which they can fail. There are panic! calls in the implementation, but if those are triggered it indicates a bug in this library, not something a caller can handle. If you have an example of non-bug panics I would reconsider, though.

Hmm, I suppose I'm thinking of the errors that we don't expect, and those that don't represent bugs in this library but rather issues encountered by the underlying LMDB C library.

The comment on mdb_cursor_get() in lmdb.h only lists MDB_NOTFOUND (which lmdb-rs now handles) and EINVAL (which would suggest a bug in lmdb-rs). But it describes those as merely "some possible errors," suggesting that they're a non-exhaustive list.

And mdb_cursor_get() can call mdb_node_read(), which can call mdb_page_get(), which can return MDB_PAGE_NOTFOUND, which would then propagate back to the return value of mdb_cursor_get().

I'm not an expert on LMDB (nor lmdb-rs!), and I don't know if that would actually happen during lmdb-rs use cases. Perhaps that code is never reached.

Nevertheless, in general, as a consumer of a library that wraps another library, I would expect to be notified about unexpected error conditions from the underlying library, so I can decide how to respond (f.e. by deleting and recreating a database). And Result seems like the best way to receive such notifications, as it is easier to handle than a panic.

@danburkert
Copy link
Owner Author

That's a good point, but if those errors are possible and we want to handle them, then not only do iter/iter_start/iter_dup et al need to return a Result, but the iterator items need to be changed to Result<(&'txn [u8], &'txn [u8])>. At this point the API is barely more ergonomic then forcing everyone to go through Cursor::get. I wonder how difficult it would be to try and repro this in a test.

@danburkert
Copy link
Owner Author

Going to merge this for now, since it fixes some bugs and at least doesn't make the API worse. @mykmelez do you mind creating an issue with your thoughts/suggestions around improving the API in the longer term?

@mykmelez
Copy link
Contributor

mykmelez commented Aug 6, 2018

Going to merge this for now, since it fixes some bugs and at least doesn't make the API worse. @mykmelez do you mind creating an issue with your thoughts/suggestions around improving the API in the longer term?

Sounds like a plan. Will do!

@mykmelez
Copy link
Contributor

mykmelez commented Aug 8, 2018

NB: I submitted #42 with my thoughts around improving the API.

@zshipko zshipko mentioned this pull request Jan 23, 2019
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.

4 participants