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

db.get() doesn't read from a snapshot #796

Closed
vweevers opened this issue Dec 12, 2021 · 1 comment
Closed

db.get() doesn't read from a snapshot #796

vweevers opened this issue Dec 12, 2021 · 1 comment
Labels
bug Something isn't working

Comments

@vweevers
Copy link
Member

We don't set the LevelDB snapshot option for database_->Get(), so rather than reading from a snapshot created at the time that db.get() was called, it will read from an implicit snapshot (i.e. latest state) at the time the async worker runs:

SetStatus(database_->Get(options_, key_, value_));

For comparison, see db.getMany() where we do set the snapshot option:

options_.snapshot = database->NewSnapshot();

This may have been the case for a long time and I've personally not found this to be a problem in real-world apps. Putting this in the backlog until there are upvotes.

@vweevers vweevers added the bug Something isn't working label Dec 12, 2021
vweevers added a commit to Level/abstract-level that referenced this issue Sep 25, 2022
At the moment, this is a documentation-only PR, acting as an RFC. In
particular I'd like review of my choice to use a token-based
approach (as first suggested by Rod Vagg in
Level/community#45) as opposed to a
dedicated snapshot API surface (as suggested by Julian Gruber in
Level/community#47). Main reasons for not
choosing the latter:

- It would be a third API surface. We have the main database API,
  the sublevel API which is equal to that except for implementation-
  specific additional methods, and would now add another API which
  only has read methods (get, iterator, etc, but not put and batch).
  If the API was reusable, meaning you could pass around a snapshot
  as if it was a regular database (like you can with sublevels) then
  I'd be cool with it. But for that to happen, we'd have to
  implement transactions as well, which I consider to be out of
  scope although transactions are in fact a use case of snapshots.
- It would have a higher complexity once you factor in sublevels.
  I.e. to make `db.sublevel().snapshot().get(key)` read from the
  snapshot but also prefix the given key. By instead doing
  `db.sublevel().get(key, { snapshot })`, the sublevel can just
  forward that snapshot option to its parent database.
- Furthermore, with the token approach, you can pass a snapshot to
  multiple sublevels, which cleanly solves the main use case of
  retrieving data from an index (I included an example in the docs).

I renamed the existing snapshot mechanism to "implicit snapshots"
and attempted to clarify the behavior of those as well.

If accepted, some related issues can be closed, because this PR:

- Includes (a more complete write-up than)
  Level/classic-level#40.
- Mentions Level/leveldown#796 (which
  should be moved rather than closed).
- Answers Level/classic-level#28.
- Solves the main use case as described in
  Level/leveldown#486.
- Effectively completes Level/awesome#19.
@vweevers
Copy link
Member Author

Tracked in Level/community#118. It won't be fixed in leveldown, only its successor classic-level.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Status: Done
Development

No branches or pull requests

1 participant