-
-
Notifications
You must be signed in to change notification settings - Fork 7
Reduce scope to what is strictly needed in levelup
#90
Comments
I think there are some more cases we could discuss. Say the db was closed, should another operation cause it to reopen? Or it could even be currently closing and a consumer could expect the next operation to reopen it. If after closing a db the user wants to use the deferred-leveldown behavior again, they need to ensure they called db.open(), so that it's in the opening state, right? I think that makes sense to me. Just want to check it with you |
Right. The way I see it, deferredOpen is a convenience to avoid having to open the db. It goes away if the user explicitly closes the db. It then becomes the user's responsibility to explicitly open the db again. After which the convenience is back. I reckon in most if not all cases, if the user is closing the db, they're not expecting to do further work on the db, and scheduling operations should be an error. |
Which is to say, yielding |
|
Oh, I definitely want to remove it. Just gradually. |
I want to remove it as well. I think we mostly had it because of callback inconvenience, now that we can |
I think you're right. The easiest path for them is to dispose of the db completely after closing it, and then starting fresh. So only treating the |
To clarify, I want to remove await db.open()
const sub = require('subleveldown')(db)
await sub.open() That, plus widespread usage of deferredOpen, and that we may not be seeing other benefits, is why I want to remove it gradually. We may find a new place for it, or that opening sublevels isn't necessary, or... We'll see. |
Why don't you want to have to do that? That code looks fine to me. Async operations are cheap now, I think we can remove deferredOpen altogether |
Asynchronicity is viral. Let's say a module takes a db as input, for example |
Pseudo code: const myIndexer = db => {
db.put = async (key, value) => {
await sub.open()
// ...
}
} Wouldn't something like this work? By moving the async operation into the db hooks |
That just moves the problem. I think in userland you shouldn't have to worry about open/close state; saves boilerplate and prevents race issues. deferredOpen isn't necessarily a complex feature (that should therefore be removed). The problem I have with the current implementation is that the feature is incomplete without require('levelup')(db).supports.deferredOpen // true
require('deferred-leveldown')(db).supports.deferredOpen // false! |
In other states (besides 'open') a 'Database is not open' error is now thrown. This reduces the scope of `deferred-leveldown` to what's strictly needed in `levelup` and aligns behavior. In addition, override public methods of `abstract-leveldown` instead of private methods. This has one downside: they need to do the same callback to promise conversion that `abstract-leveldown` does. The upside is that operation callbacks are not called before the db has finished opening, including in cases where `abstract-leveldown` has a fast-path, like on `db.batch([])` which because the array is empty bypasses `_batch()`. Closes #91 Closes #90
In other states (besides 'open') a 'Database is not open' error is now thrown. This reduces the scope of `deferred-leveldown` to what's strictly needed in `levelup` and aligns behavior. In addition, override public methods of `abstract-leveldown` instead of private methods. This has one downside: they need to do the same callback to promise conversion that `abstract-leveldown` does. The upside is that operation callbacks are not called before the db has finished opening, including in cases where `abstract-leveldown` has a fast-path, like on `db.batch([])` which because the array is empty bypasses `_batch()`. Closes #91 Closes #90
In other states (besides 'open') a 'Database is not open' error is now thrown. This reduces the scope of `deferred-leveldown` to what's strictly needed in `levelup` and aligns behavior. In addition, override public methods of `abstract-leveldown` instead of private methods. This has one downside: they need to do the same callback to promise conversion that `abstract-leveldown` does. The upside is that operation callbacks are not called before the db has finished opening, including in cases where `abstract-leveldown` has a fast-path, like on `db.batch([])` which because the array is empty bypasses `_batch()`. Closes #91 Closes #90
In other states (besides 'open') a 'Database is not open' error is now thrown. This reduces the scope of `deferred-leveldown` to what's strictly needed in `levelup` and aligns behavior. In addition, override public methods of `abstract-leveldown` instead of private methods. This has one downside: they need to do the same callback to promise conversion that `abstract-leveldown` does. The upside is that operation callbacks are not called before the db has finished opening, including in cases where `abstract-leveldown` has a fast-path, like on `db.batch([])` which because the array is empty bypasses `_batch()`. Closes #91 Closes #90
As well as the encoding-down and memdown devDependencies. Adds `db.status` and `db.isOperational()` for API parity. Ref Level/deferred-leveldown#90
As well as the encoding-down and memdown devDependencies. Adds `db.status` and `db.isOperational()` for API parity. Ref Level/deferred-leveldown#90
TLDR: thumbs up if you agree that deferring operations is only useful while the db is opening.
I'm working on
getMany()
. Which is a newabstract-leveldown
andlevelup
method that givesabstract-leveldown
the responsibility of checking whether the db is open whengetMany()
is called. As an experiment for Level/community#58. But I'm running into an inconsistency that's particularly problematic insubleveldown
(which has to deal with two instances ofdeferred-leveldown
andlevelup
, and is a test bed for API parity).deferred-leveldown
andlevelup
are inconsistent in their deferredOpen behavior: the former allows operations while the db has any status, the latter only if 'opening' or 'open'. For example, if the status is 'closed',deferred-leveldown
will put operations in its queue. But in practice we don't get there becauselevelup
will yield anew ReadError('Database is not open')
.@ralphtheninja @juliangruber Given that the order of initialization in
levelup
is:db
withdeferred-leveldown
I propose the following changes:
deferred-leveldown
will only defer operations if the status of its underlying db is 'opening'new Error('Database is not open')
.This is a breaking change for
deferred-leveldown
, but semver-patch forlevelup
.See also Level/levelup#710 (comment).
The text was updated successfully, but these errors were encountered: