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

Pinning APIs #726

Merged
merged 28 commits into from
Jan 24, 2022
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
4deeda2
feat(pinning-api): add skeleton and validation for pinning apis
alexandrastoica Nov 23, 2021
a3d69f4
feat(pinning-apis): work on db to support new pinning apis
flea89 Nov 23, 2021
915edbf
Add endpoint and logic to our api service (#702)
flea89 Nov 29, 2021
4e28252
feat(pinning-apis): POST /pin endpoint
alexandrastoica Dec 1, 2021
a039a33
Merge branch 'main' into feat/pinning-apis
flea89 Dec 1, 2021
708676a
chore: make standard happier
flea89 Dec 1, 2021
6ce3450
fix: fix token referemce
flea89 Dec 1, 2021
cff11e9
Merge branch 'main' into feat/pinning-apis
flea89 Dec 2, 2021
3c5ce63
fix: merge conflict issue
flea89 Dec 2, 2021
dba8c41
Merge branch 'main' into feat/pinning-apis
flea89 Dec 10, 2021
b463a62
Merge branch 'main' into feat/pinning-apis
flea89 Dec 10, 2021
f44e02c
feat : delete and replace pin requests endpoints
alexandrastoica Dec 14, 2021
d205fa8
feat: GET /pins endpoint
flea89 Dec 16, 2021
ae65ae3
Refactor Pin APIs and PR feedback (#810)
flea89 Jan 13, 2022
9ebdd94
fix: do not passa meta to cluster
flea89 Jan 14, 2022
f16ac88
chore: remove comment
flea89 Jan 14, 2022
56ee61e
chore: refactor createPin
flea89 Jan 14, 2022
2f5365e
chore: linting
flea89 Jan 14, 2022
0aace90
Merge branch 'main' into feat/pinning-apis
LeslieOA Jan 17, 2022
9d967ea
Get request id by user token (#863)
alexandrastoica Jan 17, 2022
a097faf
Merge branch 'main' into feat/pinning-apis
LeslieOA Jan 19, 2022
db5a551
Add metadata to API (#881)
alexandrastoica Jan 20, 2022
e7cc298
feat: added pinning service request issue mailto link/github button (…
LeslieOA Jan 20, 2022
ef2407c
Merge branch 'main' into feat/pinning-apis
flea89 Jan 21, 2022
3eea898
Fix test
flea89 Jan 21, 2022
fbb9745
fix: update comment to reflect changes
flea89 Jan 21, 2022
420a6e1
fix: use uuid for psaPinRequests ids
LeslieOA Jan 24, 2022
e224ef1
chore: linting
flea89 Jan 24, 2022
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
3 changes: 3 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@ contact_links:
- name: Account Limit Increase Request
url: https://mailxto.com/xy5ijb
about: Submit a request to increase the size limit on your Web3.Storage account!
- name: Pinning Service Access Request
url: https://mailxto.com/h58kmo
about: Submit a request to access Web3.Storage's IPFS pinning service in your account!
12 changes: 10 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"publish": "wrangler publish --env $(whoami)",
"build": "WEBPACK_CLI_FORCE_LOAD_ESM_CONFIG=true webpack",
"test": "npm-run-all -p -r mock:backup test:e2e -s test:size",
"test:debug": "npm-run-all -p -r mock:backup test:e2e:debug -s test:size",
"test:e2e": "playwright-test \"test/**/*.spec.js\" --sw src/index.js -b webkit",
"test:e2e:debug": "npm run test:e2e -- --debug",
"test:size": "bundlesize",
Expand Down
50 changes: 8 additions & 42 deletions packages/api/src/car.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import * as pb from '@ipld/dag-pb'
import retry from 'p-retry'
import { GATEWAY, LOCAL_ADD_THRESHOLD, MAX_BLOCK_SIZE } from './constants.js'
import { JSONResponse } from './utils/json-response.js'
import { toPinStatusEnum } from './utils/pin.js'
import { getPins, PIN_OK_STATUS, waitAndUpdateOkPins } from './utils/pin.js'
import { normalizeCid } from './utils/normalize-cid.js'

/**
Expand All @@ -19,12 +19,6 @@ import { normalizeCid } from './utils/normalize-cid.js'

const decoders = [pb, raw, cbor]

// Duration between status check polls in ms.
const PIN_STATUS_CHECK_INTERVAL = 5000
// Max time in ms to spend polling for an OK status.
const MAX_PIN_STATUS_CHECK_TIME = 30000
// Pin statuses considered OK.
const PIN_OK_STATUS = ['Pinned', 'Pinning', 'PinQueued']
// Times to retry the transaction after the first failure.
const CREATE_UPLOAD_RETRIES = 4
// Time in ms before starting the first retry.
Expand Down Expand Up @@ -171,25 +165,12 @@ export async function handleCarUpload (request, env, ctx, car, uploadType = 'Car
// Keep querying Cluster until one of the nodes reports something other than
// Unpinned i.e. PinQueued or Pinning or Pinned.
if (!pins.some(p => PIN_OK_STATUS.includes(p.status))) {
tasks.push(async () => {
const start = Date.now()
while (Date.now() - start > MAX_PIN_STATUS_CHECK_TIME) {
await new Promise(resolve => setTimeout(resolve, PIN_STATUS_CHECK_INTERVAL))
const { peerMap } = await env.cluster.status(cid)
const pins = toPins(peerMap)
if (!pins.length) { // should not happen
throw new Error('not pinning on any node')
}

const okPins = pins.filter(p => PIN_OK_STATUS.includes(p.status))
if (!okPins.length) continue

for (const pin of okPins) {
await env.db.upsertPin(normalizedCid, pin)
}
return
}
})
tasks.push(waitAndUpdateOkPins.bind(
null,
normalizeCid,
env.cluster,
env.db)
)
}

if (ctx.waitUntil) {
Expand Down Expand Up @@ -235,12 +216,7 @@ async function addToCluster (car, env) {
// will be done async by bitswap instead.
local: car.size > LOCAL_ADD_THRESHOLD
})

const { peerMap } = await env.cluster.status(cid)
const pins = toPins(peerMap)
if (!pins.length) { // should not happen
throw new Error('not pinning on any node')
}
const pins = await getPins(cid, env.cluster)

return { cid, pins }
}
Expand Down Expand Up @@ -350,13 +326,3 @@ function cumulativeSize (pbNodeBytes, pbNode) {
// This logic is the same as used by go/js-ipfs to display the cumulative size of a dag-pb dag.
return pbNodeBytes.byteLength + pbNode.Links.reduce((acc, curr) => acc + (curr.Tsize || 0), 0)
}

/**
* @param {import('@nftstorage/ipfs-cluster').StatusResponse['peerMap']} peerMap
*/
function toPins (peerMap) {
return Object.entries(peerMap).map(([peerId, { peerName, status }]) => ({
status: toPinStatusEnum(status),
location: { peerId, peerName }
}))
}
7 changes: 7 additions & 0 deletions packages/api/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { statusGet } from './status.js'
import { carHead, carGet, carPut, carPost } from './car.js'
import { uploadPost } from './upload.js'
import { userLoginPost, userTokensPost, userTokensGet, userTokensDelete, userUploadsGet, userUploadsDelete, userAccountGet, userUploadsRename, userInfoGet } from './user.js'
import { pinDelete, pinGet, pinPost, pinsGet } from './pins.js'
import { metricsGet } from './metrics.js'
import { versionGet } from './version.js'
import {
Expand Down Expand Up @@ -44,6 +45,12 @@ router.put('/car/:cid', mode['📝'](auth['🔒'](carPut)))
router.post('/upload', mode['📝'](auth['🔒'](uploadPost)))
router.get('/user/uploads', mode['👀'](auth['🔒'](userUploadsGet)))

router.post('/pins', mode['📝'](auth['🔒'](pinPost)))
router.post('/pins/:requestId', mode['📝'](auth['🔒'](pinPost)))
router.get('/pins/:requestId', mode['👀'](auth['🔒'](pinGet)))
flea89 marked this conversation as resolved.
Show resolved Hide resolved
router.get('/pins', mode['👀'](auth['🔒'](pinsGet)))
router.delete('/pins/:requestId', mode['📝'](auth['🔒'](pinDelete)))

router.get('/name/:key', mode['👀'](auth['🤲'](nameGet)))
router.post('/name/:key', mode['📝'](auth['🔒'](namePost)))

Expand Down
Loading