In collect_paypal_past_due_invoice.js, iterate over each page instead of gathering data from all pages at first (#18414)
* Create `getPaginatedEndpointIterator` to iterate each page * Create `waitMs` util, it will replace `slowCallback` * Make `handleAPIError` async * Make `isAccountUsingPaypal` async * Make `attemptInvoiceCollection` async * Make `attemptInvoicesCollection` async * Use `await` instead of `new Promise` * Remove unused callbackified `attemptInvoiceCollection` * Run `attemptInvoiceCollection` for each page instead of gathering all pages in the beginning * Add test on fetching multiple pages of invoice GitOrigin-RevId: 2674b18c6ca5732b873fb2bc71b515909006f93d
This commit is contained in:
@@ -467,9 +467,32 @@ const promises = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @typedef {{getNextPage: () => Promise<PageData>, items: any[]}} PageData
|
||||
*/
|
||||
|
||||
async getPaginatedEndpoint(resource, queryParams) {
|
||||
queryParams.per_page = queryParams.per_page || 200
|
||||
let allItems = []
|
||||
let items
|
||||
|
||||
/** @type {() => Promise<PageData>} */
|
||||
let getNextPage = promises.getPaginatedEndpointIterator(
|
||||
resource,
|
||||
queryParams
|
||||
)
|
||||
while (getNextPage) {
|
||||
;({ items, getNextPage } = await getNextPage())
|
||||
allItems = allItems.concat(items)
|
||||
logger.debug(`total now ${allItems.length}`)
|
||||
}
|
||||
return allItems
|
||||
},
|
||||
|
||||
/**
|
||||
* @returns {() => Promise<PageData>}
|
||||
*/
|
||||
getPaginatedEndpointIterator(resource, queryParams) {
|
||||
queryParams.per_page = queryParams.per_page || 200
|
||||
const getPage = async (cursor = null) => {
|
||||
const opts = {
|
||||
url: resource,
|
||||
@@ -483,21 +506,16 @@ const promises = {
|
||||
const data = await RecurlyWrapper.promises._parseXml(body)
|
||||
|
||||
const items = data[resource]
|
||||
allItems = allItems.concat(items)
|
||||
logger.debug(`got another ${items.length}, total now ${allItems.length}`)
|
||||
logger.debug(`got ${items.length} items in this page`)
|
||||
const match = response.headers.link?.match(/cursor=([0-9.]+%3A[0-9.]+)&/)
|
||||
cursor = match && match[1]
|
||||
if (cursor) {
|
||||
cursor = decodeURIComponent(cursor)
|
||||
return getPage(cursor)
|
||||
} else {
|
||||
return allItems
|
||||
const nextCursor = match && match[1]
|
||||
return {
|
||||
items,
|
||||
getNextPage:
|
||||
nextCursor && (() => getPage(decodeURIComponent(nextCursor))),
|
||||
}
|
||||
}
|
||||
|
||||
await getPage()
|
||||
|
||||
return allItems
|
||||
return getPage
|
||||
},
|
||||
|
||||
async getAccount(accountId) {
|
||||
@@ -860,13 +878,6 @@ const RecurlyWrapper = {
|
||||
apiUrl: Settings.apis.recurly.url || 'https://api.recurly.com/v2',
|
||||
_buildXml,
|
||||
_parseXml: callbackify(promises._parseXml),
|
||||
// This one needs to be callbackified manually because we need to transform {response, body} to (err, response, body)
|
||||
attemptInvoiceCollection: (invoiceId, callback) => {
|
||||
promises
|
||||
.attemptInvoiceCollection(invoiceId)
|
||||
.then(({ response, body }) => callback(null, response, body))
|
||||
.catch(err => callback(err))
|
||||
},
|
||||
createFixedAmmountCoupon: callbackify(promises.createFixedAmmountCoupon),
|
||||
getAccountActiveCoupons: callbackify(promises.getAccountActiveCoupons),
|
||||
getBillingInfo: callbackify(promises.getBillingInfo),
|
||||
|
||||
Reference in New Issue
Block a user