Skip to content

Commit 78bbcdb

Browse files
authored
fix: update pin status from GET /pins even if failed (#2235)
Update pin status for pins regardless of status. Previously we only updated if the state was positive. Pickup will not retry pins that timeout, so the change here ensures we inform users promptly where that happens. Where the user has a pending pin, the request will now synchronously go check cluster/pickup, update the db and return the response. Previously the worker would respond early, and poll for a positive pin status from the upstream for up to 30s. Just checking the upstream once per request seems sufficient. We may want to rate limit this end point in the future, but it's pretty low volume currently. fixes #2234 License: MIT --------- Signed-off-by: Oli Evans <oli@protocol.ai>
1 parent d347698 commit 78bbcdb

3 files changed

Lines changed: 32 additions & 25 deletions

File tree

packages/api/src/pins.js

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// @ts-nocheck
22
import { JSONResponse } from './utils/json-response.js'
3-
import { getPins, PIN_OK_STATUS, waitAndUpdateOkPins } from './utils/pin.js'
3+
import { getPins, PIN_OK_STATUS, waitAndUpdateOkPins, fetchAndUpdatePins } from './utils/pin.js'
44
import { PSAErrorDB, PSAErrorResourceNotFound, PSAErrorInvalidData, PSAErrorRequiredData, PinningServiceApiError } from './errors.js'
55
import {
66
INVALID_REQUEST_ID,
@@ -144,22 +144,11 @@ export async function pinGet (request, env, ctx) {
144144
throw new PSAErrorResourceNotFound()
145145
}
146146

147-
/** @type {(() => Promise<any>)[]} */
148-
const tasks = []
149-
150147
const inProgress = pinRequest.pins.filter((p) => p.status === 'PinQueued' || p.status === 'Pinning')
151-
if (inProgress.length > 0) {
152-
tasks.push(
153-
waitAndUpdateOkPins.bind(
154-
null,
155-
pinRequest.contentCid,
156-
env.cluster,
157-
env.db)
158-
)
159-
}
160148

161-
if (ctx.waitUntil) {
162-
tasks.forEach(t => ctx.waitUntil(t()))
149+
if (inProgress.length > 0) {
150+
await fetchAndUpdatePins(pinRequest.contentCid, env.cluster, env.db)
151+
pinRequest = await env.db.getPsaPinRequest(authToken._id, request.params.requestId)
163152
}
164153

165154
/** @type { PsaPinStatusResponse } */

packages/api/src/utils/pin.js

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import retry from 'p-retry'
12
/**
23
* @typedef {import('@nftstorage/ipfs-cluster').API.TrackerStatus} TrackerStatus
34
* @typedef {'Undefined'
@@ -155,15 +156,32 @@ export async function waitOkPins (cid, cluster, waitTime = MAX_PIN_STATUS_CHECK_
155156
*/
156157
export async function waitAndUpdateOkPins (cid, cluster, db, waitTime = MAX_PIN_STATUS_CHECK_TIME, checkInterval = PIN_STATUS_CHECK_INTERVAL) {
157158
const okPins = await waitOkPins(cid, cluster, waitTime, checkInterval)
158-
const pins = okPins.map((pin) => {
159-
return {
160-
id: pin._id,
161-
status: pin.status,
162-
contentCid: cid,
163-
location: pin.location
164-
}
165-
})
166-
// @ts-ignore
159+
const pins = toPinsUpsert(cid, okPins)
167160
await db.upsertPins(pins)
168161
return okPins
169162
}
163+
164+
/**
165+
* @param {string} contentCid
166+
* @param {import('@web3-storage/db/db-client-types').PinUpsertInput[]} pins
167+
* @returns {import('@web3-storage/db/db-client-types').PinsUpsertInput[]}
168+
*/
169+
export function toPinsUpsert (contentCid, pins) {
170+
return pins.map(pin => ({
171+
id: pin._id,
172+
status: pin.status,
173+
contentCid,
174+
location: pin.location
175+
}))
176+
}
177+
178+
/**
179+
* @param {string} contentCid
180+
* @param {import('@nftstorage/ipfs-cluster').Cluster} cluster
181+
* @param {import('@web3-storage/db').DBClient} db
182+
*/
183+
export async function fetchAndUpdatePins (contentCid, cluster, db) {
184+
const statuses = await retry(() => getPins(contentCid, cluster), { retries: 3 })
185+
const upserts = toPinsUpsert(contentCid, statuses)
186+
return retry(() => db.upsertPins(upserts), { retries: 3 })
187+
}

packages/db/db-client-types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ export type PinItem = PinUpsertInput & {
9595
}
9696

9797
export type PinsUpsertInput = {
98-
id: string
98+
id?: string
9999
status: definitions['pin']['status']
100100
contentCid: definitions['pin']['content_cid']
101101
location: Location

0 commit comments

Comments
 (0)