Explorar o código

Merge pull request #18850 from overleaf/ac-promisify-resync-subscriptions

Promisify resync_subscriptions

GitOrigin-RevId: c23a99683a22104815525b179d4e46d3ad568f94
Jimmy Domagala-Tang %!s(int64=2) %!d(string=hai) anos
pai
achega
50b19c7793
Modificáronse 1 ficheiros con 86 adicións e 78 borrados
  1. 86 78
      services/web/scripts/recurly/resync_subscriptions.js

+ 86 - 78
services/web/scripts/recurly/resync_subscriptions.js

@@ -1,11 +1,12 @@
 const { Subscription } = require('../../app/src/models/Subscription')
 const { Subscription } = require('../../app/src/models/Subscription')
 const RecurlyWrapper = require('../../app/src/Features/Subscription/RecurlyWrapper')
 const RecurlyWrapper = require('../../app/src/Features/Subscription/RecurlyWrapper')
 const SubscriptionUpdater = require('../../app/src/Features/Subscription/SubscriptionUpdater')
 const SubscriptionUpdater = require('../../app/src/Features/Subscription/SubscriptionUpdater')
-const async = require('async')
 const minimist = require('minimist')
 const minimist = require('minimist')
+const { setTimeout } = require('node:timers/promises')
 
 
 // make sure all `allMismatchReasons` are displayed in the output
 // make sure all `allMismatchReasons` are displayed in the output
 const util = require('util')
 const util = require('util')
+const pLimit = require('p-limit')
 util.inspect.defaultOptions.maxArrayLength = null
 util.inspect.defaultOptions.maxArrayLength = null
 
 
 const ScriptLogger = {
 const ScriptLogger = {
@@ -59,104 +60,109 @@ const ScriptLogger = {
   },
   },
 }
 }
 
 
-const slowCallback = callback => setTimeout(callback, 80)
-
-const handleSyncSubscriptionError = (subscription, error, callback) => {
+const handleSyncSubscriptionError = async (subscription, error) => {
   console.warn(`Errors with subscription id=${subscription._id}:`, error)
   console.warn(`Errors with subscription id=${subscription._id}:`, error)
   if (typeof error === 'string' && error.match(/429$/)) {
   if (typeof error === 'string' && error.match(/429$/)) {
-    return setTimeout(callback, 1000 * 60 * 5)
+    await setTimeout(1000 * 60 * 5)
+    return
   }
   }
   if (typeof error === 'string' && error.match(/5\d\d$/)) {
   if (typeof error === 'string' && error.match(/5\d\d$/)) {
-    return setTimeout(() => {
-      syncSubscription(subscription, callback)
-    }, 1000 * 60)
+    await setTimeout(1000 * 60)
+    await syncSubscription(subscription)
+    return
   }
   }
-  slowCallback(callback)
+  await setTimeout(80)
 }
 }
 
 
-const syncSubscription = (subscription, callback) => {
-  RecurlyWrapper.getSubscription(
-    subscription.recurlySubscription_id,
-    (error, recurlySubscription) => {
-      if (error) {
-        return handleSyncSubscriptionError(subscription, error, callback)
-      }
+const syncSubscription = async subscription => {
+  let recurlySubscription
+  try {
+    recurlySubscription = await RecurlyWrapper.promises.getSubscription(
+      subscription.recurlySubscription_id
+    )
+  } catch (error) {
+    await handleSyncSubscriptionError(subscription, error)
+    return
+  }
 
 
-      ScriptLogger.recordMismatch(subscription, recurlySubscription)
+  ScriptLogger.recordMismatch(subscription, recurlySubscription)
 
 
-      if (!COMMIT) {
-        return callback()
-      }
+  if (!COMMIT) {
+    return
+  }
 
 
-      SubscriptionUpdater.updateSubscriptionFromRecurly(
-        recurlySubscription,
-        subscription,
-        {},
-        error => {
-          if (error) {
-            return handleSyncSubscriptionError(subscription, error, callback)
-          }
-          slowCallback(callback)
-        }
-      )
-    }
-  )
+  try {
+    await SubscriptionUpdater.promises.updateSubscriptionFromRecurly(
+      recurlySubscription,
+      subscription,
+      {}
+    )
+  } catch (error) {
+    await handleSyncSubscriptionError(subscription, error)
+    return
+  }
+  await setTimeout(80)
 }
 }
 
 
-const syncSubscriptions = (subscriptions, callback) => {
-  async.eachLimit(subscriptions, ASYNC_LIMIT, syncSubscription, callback)
+const syncSubscriptions = async subscriptions => {
+  const limit = pLimit(ASYNC_LIMIT)
+  return await Promise.all(
+    subscriptions.map(subscription =>
+      limit(() => syncSubscription(subscription))
+    )
+  )
 }
 }
 
 
-const loopForSubscriptions = (skip, callback) => {
-  Subscription.find({
-    recurlySubscription_id: { $exists: true, $ne: '' },
-  })
-    .sort('_id')
-    .skip(skip)
-    .limit(FETCH_LIMIT)
-    .exec((error, subscriptions) => {
-      if (error) {
-        return callback(error)
-      }
+const loopForSubscriptions = async skipInitial => {
+  let skip = skipInitial
 
 
-      if (subscriptions.length === 0) {
-        console.warn('DONE')
-        return callback()
-      }
-
-      syncSubscriptions(subscriptions, error => {
-        if (error) {
-          return callback(error)
-        }
-        ScriptLogger.checkedSubscriptionsCount += subscriptions.length
-        retryCounter = 0
-        ScriptLogger.printProgress()
-        ScriptLogger.printSummary()
-        loopForSubscriptions(
-          MONGO_SKIP + ScriptLogger.checkedSubscriptionsCount,
-          callback
-        )
-      })
+  // iterate while there are more subscriptions to fetch
+  while (true) {
+    const subscriptions = await Subscription.find({
+      recurlySubscription_id: { $exists: true, $ne: '' },
     })
     })
+      .sort('_id')
+      .skip(skip)
+      .limit(FETCH_LIMIT)
+      .exec()
+
+    if (subscriptions.length === 0) {
+      console.warn('DONE')
+      return
+    }
+
+    await syncSubscriptions(subscriptions)
+
+    ScriptLogger.checkedSubscriptionsCount += subscriptions.length
+    retryCounter = 0
+    ScriptLogger.printProgress()
+    ScriptLogger.printSummary()
+
+    skip += FETCH_LIMIT
+  }
 }
 }
 
 
 let retryCounter = 0
 let retryCounter = 0
-const run = () =>
-  loopForSubscriptions(
-    MONGO_SKIP + ScriptLogger.checkedSubscriptionsCount,
-    error => {
-      if (error) {
-        if (retryCounter < 3) {
-          console.error(error)
-          retryCounter += 1
-          console.warn(`RETRYING IN 60 SECONDS. (${retryCounter}/3)`)
-          return setTimeout(run, 60000)
-        }
+const run = async () => {
+  while (true) {
+    try {
+      await loopForSubscriptions(
+        MONGO_SKIP + ScriptLogger.checkedSubscriptionsCount
+      )
+      break
+    } catch (error) {
+      if (retryCounter < 3) {
+        console.error(error)
+        retryCounter += 1
+        console.warn(`RETRYING IN 60 SECONDS. (${retryCounter}/3)`)
+        await setTimeout(60000)
+      } else {
+        console.error('Failed after 3 retries')
         throw error
         throw error
       }
       }
-      process.exit()
     }
     }
-  )
+  }
+}
 
 
 let FETCH_LIMIT, ASYNC_LIMIT, COMMIT, MONGO_SKIP
 let FETCH_LIMIT, ASYNC_LIMIT, COMMIT, MONGO_SKIP
 const setup = () => {
 const setup = () => {
@@ -174,4 +180,6 @@ const setup = () => {
 }
 }
 
 
 setup()
 setup()
-run()
+run().then(() => {
+  process.exit()
+})