mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-29 22:53:31 -05:00
d772dbaceb
Resync Recurly Subscriptions Script Improvements GitOrigin-RevId: b042465b7bffcbb73b40d1a7f23de784185d53ef
175 lines
4.8 KiB
JavaScript
175 lines
4.8 KiB
JavaScript
const { Subscription } = require('../../app/src/models/Subscription')
|
|
const RecurlyWrapper = require('../../app/src/Features/Subscription/RecurlyWrapper')
|
|
const SubscriptionUpdater = require('../../app/src/Features/Subscription/SubscriptionUpdater')
|
|
const async = require('async')
|
|
const minimist = require('minimist')
|
|
|
|
// make sure all `allMismatchReasons` are displayed in the output
|
|
const util = require('util')
|
|
util.inspect.defaultOptions.maxArrayLength = null
|
|
|
|
const ScriptLogger = {
|
|
checkedSubscriptionsCount: 0,
|
|
mismatchSubscriptionsCount: 0,
|
|
allMismatchReasons: {},
|
|
|
|
recordMismatch: (subscription, recurlySubscription) => {
|
|
const mismatchReasons = {}
|
|
if (subscription.planCode !== recurlySubscription.plan.plan_code) {
|
|
mismatchReasons['recurlyPlan'] = recurlySubscription.plan.plan_code
|
|
mismatchReasons['olPlan'] = subscription.planCode
|
|
}
|
|
if (recurlySubscription.state === 'expired') {
|
|
mismatchReasons['state'] = 'expired'
|
|
}
|
|
|
|
if (!Object.keys(mismatchReasons).length) {
|
|
return
|
|
}
|
|
|
|
ScriptLogger.mismatchSubscriptionsCount += 1
|
|
const mismatchReasonsString = JSON.stringify(mismatchReasons)
|
|
if (ScriptLogger.allMismatchReasons[mismatchReasonsString]) {
|
|
ScriptLogger.allMismatchReasons[mismatchReasonsString].push(
|
|
subscription._id
|
|
)
|
|
} else {
|
|
ScriptLogger.allMismatchReasons[mismatchReasonsString] = [
|
|
subscription._id
|
|
]
|
|
}
|
|
},
|
|
|
|
printProgress: () => {
|
|
console.warn(
|
|
`Subscriptions checked: ${
|
|
ScriptLogger.checkedSubscriptionsCount
|
|
}. Mismatches: ${ScriptLogger.mismatchSubscriptionsCount}`
|
|
)
|
|
},
|
|
|
|
printSummary: () => {
|
|
console.log('All Mismatch Reasons:', ScriptLogger.allMismatchReasons)
|
|
console.log(
|
|
'Mismatch Subscriptions Count',
|
|
ScriptLogger.mismatchSubscriptionsCount
|
|
)
|
|
}
|
|
}
|
|
|
|
const slowCallback = callback => setTimeout(callback, 80)
|
|
|
|
const handleSyncSubscriptionError = (subscription, error, callback) => {
|
|
console.warn(`Errors with subscription id=${subscription._id}:`, error)
|
|
if (typeof error === 'string' && error.match(/429$/)) {
|
|
return setTimeout(callback, 1000 * 60 * 5)
|
|
}
|
|
if (typeof error === 'string' && error.match(/5\d\d$/)) {
|
|
return setTimeout(() => {
|
|
syncSubscription(subscription, callback)
|
|
}, 1000 * 60)
|
|
}
|
|
slowCallback(callback)
|
|
}
|
|
|
|
const syncSubscription = (subscription, callback) => {
|
|
RecurlyWrapper.getSubscription(
|
|
subscription.recurlySubscription_id,
|
|
(error, recurlySubscription) => {
|
|
if (error) {
|
|
return handleSyncSubscriptionError(subscription, error, callback)
|
|
}
|
|
|
|
ScriptLogger.recordMismatch(subscription, recurlySubscription)
|
|
|
|
if (!COMMIT) {
|
|
return callback()
|
|
}
|
|
|
|
SubscriptionUpdater._updateSubscriptionFromRecurly(
|
|
recurlySubscription,
|
|
subscription,
|
|
{},
|
|
error => {
|
|
if (error) {
|
|
return handleSyncSubscriptionError(subscription, error, callback)
|
|
}
|
|
slowCallback(callback)
|
|
}
|
|
)
|
|
}
|
|
)
|
|
}
|
|
|
|
const syncSubscriptions = (subscriptions, callback) => {
|
|
async.eachLimit(subscriptions, ASYNC_LIMIT, syncSubscription, callback)
|
|
}
|
|
|
|
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)
|
|
}
|
|
|
|
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
|
|
)
|
|
})
|
|
})
|
|
}
|
|
|
|
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)
|
|
}
|
|
throw error
|
|
}
|
|
process.exit()
|
|
}
|
|
)
|
|
|
|
let FETCH_LIMIT, ASYNC_LIMIT, COMMIT, MONGO_SKIP
|
|
const setup = () => {
|
|
const argv = minimist(process.argv.slice(2))
|
|
FETCH_LIMIT = argv.fetch ? argv.fetch : 100
|
|
ASYNC_LIMIT = argv.async ? argv.async : 10
|
|
MONGO_SKIP = argv.skip ? argv.skip : 0
|
|
COMMIT = argv.commit !== undefined
|
|
if (!COMMIT) {
|
|
console.warn('Doing dry run without --commit')
|
|
}
|
|
if (MONGO_SKIP) {
|
|
console.warn(`Skipping first ${MONGO_SKIP} records`)
|
|
}
|
|
}
|
|
|
|
setup()
|
|
run()
|