Skip to content
This repository was archived by the owner on Feb 12, 2024. It is now read-only.

refactor: convert block and pin APIs to async/await #2660

Closed
Closed
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion src/cli/commands/block/rm.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ module.exports = {
const ipfs = await getIpfs()
let errored = false

for await (const result of ipfs.block._rmAsyncIterator(hash, {
for await (const result of ipfs.block.rm(hash, {
force,
quiet
})) {
Expand Down
5 changes: 2 additions & 3 deletions src/cli/commands/pin/ls.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,13 @@ module.exports = {
resolve((async () => {
const paths = ipfsPath
const ipfs = await getIpfs()
const results = await ipfs.pin.ls(paths, { type })
results.forEach((res) => {
for await (const res of ipfs.pin.ls(paths, { type })) {
let line = cidToString(res.hash, { base: cidBase })
if (!quiet) {
line += ` ${res.type}`
}
print(line)
})
}
})())
}
}
16 changes: 16 additions & 0 deletions src/core/components/block/get.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use strict'

const { cleanCid } = require('./utils')

module.exports = ({ blockService, preload }) => {
return async function get (cid, options) { // eslint-disable-line require-await
options = options || {}
cid = cleanCid(cid)

if (options.preload !== false) {
preload(cid)
}

return blockService.get(cid)
}
}
51 changes: 51 additions & 0 deletions src/core/components/block/put.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
'use strict'

const Block = require('ipfs-block')
const multihashing = require('multihashing-async')
const CID = require('cids')

module.exports = ({ blockService, gcLock, preload }) => {
return async function put (block, options) {
options = options || {}

if (Array.isArray(block)) {
throw new Error('Array is not supported')
}

if (!Block.isBlock(block)) {
if (options.cid && CID.isCID(options.cid)) {
block = new Block(block, options.cid)
} else {
const mhtype = options.mhtype || 'sha2-256'
const format = options.format || 'dag-pb'
let cidVersion

if (options.version == null) {
// Pick appropriate CID version
cidVersion = mhtype === 'sha2-256' && format === 'dag-pb' ? 0 : 1
} else {
cidVersion = options.version
}

const multihash = await multihashing(block, mhtype)
const cid = new CID(cidVersion, format, multihash)

block = new Block(block, cid)
}
}

const release = await gcLock.readLock()

try {
await blockService.put(block)

if (options.preload !== false) {
preload(block.cid)
}

return block
} finally {
release()
}
}
}
61 changes: 61 additions & 0 deletions src/core/components/block/rm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
'use strict'

const CID = require('cids')
const errCode = require('err-code')
const { PinTypes } = require('./pin/pin-manager')
const { cleanCid } = require('./utils')

module.exports = ({ blockService, gcLock, pinManager }) => {
return async function * rm (cids, options) {
options = options || {}

if (!Array.isArray(cids)) {
cids = [cids]
}

// We need to take a write lock here to ensure that adding and removing
// blocks are exclusive operations
const release = await gcLock.writeLock()

try {
for (let cid of cids) {
cid = cleanCid(cid)

const result = {
hash: cid.toString()
}

try {
const pinResult = await pinManager.isPinnedWithType(cid, PinTypes.all)

if (pinResult.pinned) {
if (CID.isCID(pinResult.reason)) { // eslint-disable-line max-depth
throw errCode(new Error(`pinned via ${pinResult.reason}`))
}

throw errCode(new Error(`pinned: ${pinResult.reason}`))
}

// remove has check when https://github.com/ipfs/js-ipfs-block-service/pull/88 is merged
const has = await blockService._repo.blocks.has(cid)

if (!has) {
throw errCode(new Error('block not found'), 'ERR_BLOCK_NOT_FOUND')
}

await blockService.delete(cid)
} catch (err) {
if (!options.force) {
result.error = `cannot remove ${cid}: ${err.message}`
}
}

if (!options.quiet) {
yield result
}
}
} finally {
release()
}
}
}
21 changes: 21 additions & 0 deletions src/core/components/block/stat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use strict'

const { cleanCid } = require('./utils')

module.exports = ({ blockService, preload }) => {
return async function stat (cid, options) {
options = options || {}
cid = cleanCid(cid)

if (options.preload !== false) {
preload(cid)
}

const block = await blockService.get(cid)

return {
key: cid.toString(),
size: block.data.length
}
}
}
17 changes: 17 additions & 0 deletions src/core/components/block/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use strict'

const CID = require('cids')
const errCode = require('err-code')

exports.cleanCid = cid => {
if (CID.isCID(cid)) {
return cid
}

// CID constructor knows how to do the cleaning :)
try {
return new CID(cid)
} catch (err) {
throw errCode(err, 'ERR_INVALID_CID')
}
}
14 changes: 12 additions & 2 deletions src/core/components/index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
'use strict'

exports.add = require('./add')
exports.block = {
get: require('./block/get'),
put: require('./block/put'),
rm: require('./block/rm'),
stat: require('./block/stat')
}
exports.config = require('./config')
exports.init = require('./init')
exports.pin = {
add: require('./pin/add'),
ls: require('./pin/ls'),
rm: require('./pin/rm')
}
exports.start = require('./start')
exports.stop = require('./stop')

exports.legacy = { // TODO: these will be removed as the new API is completed
dag: require('./dag'),
libp2p: require('./libp2p'),
object: require('./object'),
pin: require('./pin')
object: require('./object')
}
27 changes: 19 additions & 8 deletions src/core/components/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const getDefaultConfig = require('../runtime/config-nodejs.js')
const createRepo = require('../runtime/repo-nodejs')
const Keychain = require('libp2p-keychain')
const NoKeychain = require('./no-keychain')
const GCLock = require('./pin/gc-lock')
const mortice = require('mortice')
const { DAGNode } = require('ipld-dag-pb')
const UnixFs = require('ipfs-unixfs')
const multicodec = require('multicodec')
Expand Down Expand Up @@ -95,19 +95,21 @@ module.exports = ({
const preload = createPreloader(constructorOptions.preload)
await preload.start()

const gcLock = new GCLock(constructorOptions.repoOwner, {
// Make sure GCLock is specific to repo, for tests where there are
// multiple instances of IPFS
morticeId: repo.path
})

// Make sure GC lock is specific to repo, for tests where there are
// multiple instances of IPFS
const gcLock = mortice(repo.path, { singleProcess: constructorOptions.repoOwner })
const dag = Commands.legacy.dag({ _ipld: ipld, _preload: preload })
const object = Commands.legacy.object({ _ipld: ipld, _preload: preload, dag, _gcLock: gcLock })

const pinManager = new PinManager(repo, dag)
await pinManager.load()

const pin = Commands.legacy.pin({ _ipld: ipld, _preload: preload, object, _repo: repo, _pinManager: pinManager })
const pin = {
add: Commands.pin.add({ pinManager, gcLock, dag, object }),
ls: Commands.pin.ls({ pinManager, object }),
rm: Commands.pin.rm({ pinManager, gcLock, object })
}

const add = Commands.add({ ipld, dag, preload, pin, gcLock, constructorOptions })

if (!isInitialized && !options.emptyRepo) {
Expand Down Expand Up @@ -135,6 +137,7 @@ module.exports = ({
ipld,
keychain,
peerInfo,
pin,
pinManager,
preload,
print,
Expand Down Expand Up @@ -277,6 +280,7 @@ function createApi ({
ipld,
keychain,
peerInfo,
pin,
pinManager,
preload,
print,
Expand All @@ -299,8 +303,15 @@ function createApi ({

const api = {
add,
block: {
get: Commands.block.get({ blockService, preload }),
put: Commands.block.put({ blockService, gcLock, preload }),
rm: Commands.block.rm({ blockService, gcLock, pinManager }),
stat: Commands.block.stat({ blockService, preload })
},
config: Commands.config({ repo }),
init: () => { throw new AlreadyInitializedError() },
pin,
start
}

Expand Down
Loading