Skip to content

fix: memlock handling existing locks #195

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

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 3 additions & 13 deletions example.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,6 @@
const Repo = require('ipfs-repo')
const repo = new Repo('/Users/awesome/.jsipfs')

repo.init({ my: 'config' }, (err) => {
if (err) {
throw err
}

repo.open((err) => {
if (err) {
throw err
}

console.log('repo is ready')
})
})
repo.init({ my: 'config' })
.then(repo.open)
.then(() => console.log('repo is ready'))
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,14 @@
"rimraf": "^2.6.2"
},
"dependencies": {
"async": "^2.6.1",
"base32.js": "~0.1.0",
"bignumber.js": "^8.0.2",
"cids": "~0.5.7",
"datastore-core": "~0.6.0",
"datastore-fs": "~0.7.0",
"datastore-level": "~0.10.0",
"datastore-level": "git://github.com/ipfs/js-datastore-level.git#refactor/async-iterators",
"debug": "^4.1.0",
"interface-datastore": "~0.6.0",
"interface-datastore": "git://github.com/ipfs/interface-datastore.git#refactor/async-iterators",
"ipfs-block": "~0.8.0",
"lodash.get": "^4.4.2",
"lodash.has": "^4.5.2",
Expand Down
22 changes: 10 additions & 12 deletions src/api-addr.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,28 @@ module.exports = (store) => {
/**
* Get the current configuration from the repo.
*
* @param {function(Error, Object)} callback
* @returns {void}
* @returns {Promise<Object>}
*/
get (callback) {
store.get(apiFile, (err, value) => callback(err, value && value.toString()))
async get () {
const value = await store.get(apiFile)
return value && value.toString()
},
/**
* Set the current configuration for this repo.
*
* @param {Object} value - the api address to be written
* @param {function(Error)} callback
* @returns {void}
* @returns {Promise<void>}
*/
set (value, callback) {
store.put(apiFile, Buffer.from(value.toString()), callback)
async set (value) {
return store.put(apiFile, Buffer.from(value.toString()))
},
/**
* Deletes api file
*
* @param {function(Error, bool)} callback
* @returns {void}
* @returns {Promise<void>}
*/
delete (callback) {
store.delete(apiFile, callback)
async delete () {
return store.delete(apiFile)
}
}
}
167 changes: 66 additions & 101 deletions src/blockstore.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ const ShardingStore = core.ShardingDatastore
const Key = require('interface-datastore').Key
const base32 = require('base32.js')
const Block = require('ipfs-block')
const setImmediate = require('async/setImmediate')
const reject = require('async/reject')
const CID = require('cids')
const pull = require('pull-stream')

/**
* Transform a raw buffer to a base32 encoded key.
Expand All @@ -31,21 +28,17 @@ const cidToDsKey = (cid) => {
return keyFromBuffer(cid.buffer)
}

module.exports = (filestore, options, callback) => {
maybeWithSharding(filestore, options, (err, store) => {
if (err) { return callback(err) }

callback(null, createBaseStore(store))
})
module.exports = async (filestore, options) => {
const store = await maybeWithSharding(filestore, options)
return createBaseStore(store)
}

function maybeWithSharding (filestore, options, callback) {
function maybeWithSharding (filestore, options) {
if (options.sharding) {
const shard = new core.shard.NextToLast(2)
ShardingStore.createOrOpen(filestore, shard, callback)
} else {
setImmediate(() => callback(null, filestore))
return ShardingStore.createOrOpen(filestore, shard)
}
return filestore
}

function createBaseStore (store) {
Expand All @@ -54,142 +47,114 @@ function createBaseStore (store) {
* Query the store.
*
* @param {object} query
* @param {function(Error, Array)} callback
* @return {void}
* @return {Iterable}
*/
query (query, callback) {
pull(
store.query(query),
pull.collect(callback)
)
query (query) {
return store.query(query)
},
/**
* Get a single block by CID.
*
* @param {CID} cid
* @param {function(Error, Block)} callback
* @returns {void}
* @returns {Promise<Block>}
*/
get (cid, callback) {
async get (cid) {
if (!CID.isCID(cid)) {
return setImmediate(() => {
callback(new Error('Not a valid cid'))
})
throw new Error('Not a valid cid')
}

const key = cidToDsKey(cid)
store.get(key, (err, blockData) => {
if (err) {
// If not found, we try with the other CID version.
// If exists, then store that block under the CID that was requested.
// Some duplication occurs.
if (err.code === 'ERR_NOT_FOUND') {
const otherCid = cidToOtherVersion(cid)
if (!otherCid) return callback(err)

const otherKey = cidToDsKey(otherCid)
return store.get(otherKey, (err, blockData) => {
if (err) return callback(err)

store.put(key, blockData, (err) => {
if (err) return callback(err)
callback(null, new Block(blockData, cid))
})
})
}

return callback(err)
let blockData
try {
blockData = await store.get(key)
return new Block(blockData, cid)
} catch (err) {
if (err.code === 'ERR_NOT_FOUND') {
const otherCid = cidToOtherVersion(cid)
if (!otherCid) throw err

const otherKey = cidToDsKey(otherCid)
const blockData = await store.get(otherKey)
await store.put(key, blockData)
return new Block(blockData, cid)
}

callback(null, new Block(blockData, cid))
})
}
},
put (block, callback) {
/**
* Write a single block to the store.
*
* @param {Block} block
* @returns {Promise<void>}
*/
async put (block) {
if (!Block.isBlock(block)) {
return setImmediate(() => {
callback(new Error('invalid block'))
})
throw new Error('invalid block')
}

const k = cidToDsKey(block.cid)

store.has(k, (err, exists) => {
if (err) { return callback(err) }
if (exists) { return callback() }

store.put(k, block.data, callback)
})
const exists = await store.has(k)
if (exists) return
return store.put(k, block.data)
},

/**
* Like put, but for more.
*
* @param {Array<Block>} blocks
* @param {function(Error)} callback
* @returns {void}
* @returns {Promise<void>}
*/
putMany (blocks, callback) {
async putMany (blocks) {
const keys = blocks.map((b) => ({
key: cidToDsKey(b.cid),
block: b
}))

const batch = store.batch()
reject(keys, (k, cb) => store.has(k.key, cb), (err, newKeys) => {
if (err) {
return callback(err)
}
const newKeys = (await Promise.all(keys.map(async k => {
const exists = await store.has(k.key)
return exists ? null : k
}))).filter(Boolean)

newKeys.forEach((k) => {
batch.put(k.key, k.block.data)
})

batch.commit(callback)
newKeys.forEach((k) => {
batch.put(k.key, k.block.data)
})
return batch.commit()
},
/**
* Does the store contain block with this cid?
*
* @param {CID} cid
* @param {function(Error, bool)} callback
* @returns {void}
* @returns {Promise<bool>}
*/
has (cid, callback) {
async has (cid) {
if (!CID.isCID(cid)) {
return setImmediate(() => {
callback(new Error('Not a valid cid'))
})
throw new Error('Not a valid cid')
}

store.has(cidToDsKey(cid), (err, exists) => {
if (err) return callback(err)
if (exists) return callback(null, true)

// If not found, we try with the other CID version.
const otherCid = cidToOtherVersion(cid)
if (!otherCid) return callback(null, false)

store.has(cidToDsKey(otherCid), callback)
})
const exists = await store.has(cidToDsKey(cid))
if (exists) return exists
const otherCid = cidToOtherVersion(cid)
if (!otherCid) return false
return store.has(cidToDsKey(otherCid))
},
/**
* Delete a block from the store
*
* @param {CID} cid
* @param {function(Error)} callback
* @returns {void}
* @returns {Promise<void>}
*/
delete (cid, callback) {
async delete (cid) {
if (!CID.isCID(cid)) {
return setImmediate(() => {
callback(new Error('Not a valid cid'))
})
throw new Error('Not a valid cid')
}

store.delete(cidToDsKey(cid), callback)
return store.delete(cidToDsKey(cid))
},

close (callback) {
store.close(callback)
/**
* Close the store
*
* @returns {Promise<void>}
*/
async close () {
return store.close()
}
}
}
Expand Down
Loading