-
Notifications
You must be signed in to change notification settings - Fork 50
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
feat(lock): allow for custom lock options #162
Conversation
@pgte @dignifiedquire can I get a review from you on this feature? |
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.
@jacobheun please add docs about this feature
test/options-test.js
Outdated
|
||
it('allows for no locker', () => { | ||
const repo = new Repo(repoPath, { | ||
locker: false |
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.
should also test for undefined
options
@@ -25,6 +41,16 @@ describe('IPFS Repo Tests onNode.js', () => { | |||
lock: 'memory' | |||
}, | |||
init: true | |||
}, { | |||
name: 'custom locker', |
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.
There is no proper locking tests currently, so it would be good to test various locking scenarios in addition to the regular tests
src/index.js
Outdated
* @returns {Locker} | ||
*/ | ||
_getLocker () { | ||
if (this.options.locker === false) { |
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.
This way of options is 👎 from my side. This forces locker
to be of multiple types, so disabling the locker should check for != null
and be if it is not set, rather than a boolean
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.
I know multiple types for an option isn’t especially desirable, but it feels to me like just using lock
for both custom and built-in types instead of adding a new option would be much nicer from the perspective of a user. Maybe we could move towards the type being a Locker object instead of a string? You could support built-ins with:
// Expose the built-in collection as a frozen static var on Repo
new Repo({ lock: Repo.lockers.memory })
// OR
new Repo({ lock: require('ipfs-repo/lock-memory') })
…though we’d probably want to keep string support as a deprecated feature for a little while.
(Found my way here after reviewing ipfs/js-ipfs#1303; I hope I’m not butting in.)
src/index.js
Outdated
* @returns {void} | ||
*/ | ||
_openLock (path, callback) { | ||
if (this._locker) { |
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.
also 👎 on being able to disable the locking, this is just asking for trouble
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.
I am fine with leaving locking required, the custom locker is the needed piece. It's fairly easy to subvert locking at the moment even if we don't explicitly allow it to be disabled. With custom datastore support there is a potential use case for users wanting to handle locking at the object level, rather than the repo level.
If we decide to leave it required, I can update the documentation when I add in the custom locker docs to encourage users to use locking appropriate for their use case and custom datastores, such as storing their lock on S3 if their datastore is there.
fix: failing tests test: add a lock test suite doc: update repo docs for custom locking
I've made a few updates after everyones feedback:
I also updated the repo options to allow for overloading of the |
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.
thanks, looks much better now
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.
Added some quick thoughts on the docs. Looks good!
README.md
Outdated
@@ -142,7 +142,7 @@ Arguments: | |||
|
|||
* `path` (string, mandatory): the path for this repo | |||
* `options` (object, optional): may contain the following values | |||
* `lock` (string, defaults to `"fs"` in Node.js, `"memory"` in the browser): what type of lock to use. Lock has to be acquired when opening. | |||
* `lock` (string *Deprecated* or [Lock](#lock)), string can be `"fs"` or `"memory"`: what type of lock to use. Lock has to be acquired when opening. |
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.
I think it’s generally clearer (and helps encourage correct usage) to describe the intended or standard usage first, then what’s deprecated or not desired — so I think it might be better to describe using an actual Lock
type first, then describe the deprecated string support.
README.md
Outdated
|
||
```js | ||
const fsLock = require('ipfs-repo/src/lock') // Default in Node.js | ||
const memLock = require('ipfs-repo/src/lock-memory') // Default in browser |
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.
When it comes to examples and documentation, where a reader might not be familiar with all the concepts or names being used, it helps to avoid abbreviation if you can (so memoryLock
might be better than memLock
here).
README.md
Outdated
const memLock = require('ipfs-repo/src/lock-memory') // Default in browser | ||
``` | ||
|
||
#### `lock.open (dir, callback)` |
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 lock.lock (directory, callback)
?
Also, it might help to preface this section with a sentence that says:
You can also provide your own custom Lock. It must be an object with the following interface:
README.md
Outdated
|
||
#### `lock.open (dir, callback)` | ||
|
||
Sets the lock if one does not already exist. |
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.
It should also call callback(error)
with an error if a lock does exist, right?
src/index.js
Outdated
* @returns {void} | ||
*/ | ||
_openLock (path, callback) { | ||
this._locker.lock(path, callback) |
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.
Since this can be user-provided now, should we validate that the resulting object has a close()
method? (If yes, we probably also need to change _closeLock
so it doesn’t try and close the unclose-able lock when handling the error 😛)
Ensure locks have a close method when creating the lock
@Mr0grog I updated things based on your comments, and I agree we should check for the |
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.
Looking HAWT 🔥
Allows users to have no repo lockingresolves #161