X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Fhelpers%2Fdatabase-utils.ts;h=b6ba7fd75a846b449cf127ea511f4ef9d31e3946;hb=472170b4f923a52cceb595221864eab61d624d5b;hp=9b861a88ccd3c417bf963ae659979ab57c28482b;hpb=90d4bb8125e80c8060416d4d135ddeaf0a622ede;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/helpers/database-utils.ts b/server/helpers/database-utils.ts index 9b861a88c..b6ba7fd75 100644 --- a/server/helpers/database-utils.ts +++ b/server/helpers/database-utils.ts @@ -1,37 +1,51 @@ -import * as retry from 'async/retry' -import * as Bluebird from 'bluebird' +import retry from 'async/retry' +import Bluebird from 'bluebird' +import { Transaction } from 'sequelize' import { Model } from 'sequelize-typescript' +import { sequelizeTypescript } from '@server/initializers/database' import { logger } from './logger' +function retryTransactionWrapper ( + functionToRetry: (arg1: A, arg2: B, arg3: C, arg4: D) => Promise, + arg1: A, + arg2: B, + arg3: C, + arg4: D, +): Promise + function retryTransactionWrapper ( - functionToRetry: (arg1: A, arg2: B, arg3: C) => Promise | Bluebird, + functionToRetry: (arg1: A, arg2: B, arg3: C) => Promise, arg1: A, arg2: B, arg3: C ): Promise function retryTransactionWrapper ( - functionToRetry: (arg1: A, arg2: B) => Promise | Bluebird, + functionToRetry: (arg1: A, arg2: B) => Promise, arg1: A, arg2: B ): Promise function retryTransactionWrapper ( - functionToRetry: (arg1: A) => Promise | Bluebird, + functionToRetry: (arg1: A) => Promise, arg1: A ): Promise function retryTransactionWrapper ( - functionToRetry: (...args: any[]) => Promise | Bluebird, + functionToRetry: () => Promise | Bluebird +): Promise + +function retryTransactionWrapper ( + functionToRetry: (...args: any[]) => Promise, ...args: any[] ): Promise { return transactionRetryer(callback => { - functionToRetry.apply(this, args) + functionToRetry.apply(null, args) .then((result: T) => callback(null, result)) .catch(err => callback(err)) }) .catch(err => { - logger.error('Cannot execute %s with many retries.', functionToRetry.toString(), { err }) + logger.warn(`Cannot execute ${functionToRetry.name} with many retries.`, { err }) throw err }) } @@ -44,7 +58,7 @@ function transactionRetryer (func: (err: any, data: T) => any) { errorFilter: err => { const willRetry = (err.name === 'SequelizeDatabaseError') - logger.debug('Maybe retrying the transaction function.', { willRetry, err }) + logger.debug('Maybe retrying the transaction function.', { willRetry, err, tags: [ 'sql', 'retry' ] }) return willRetry } }, @@ -54,18 +68,54 @@ function transactionRetryer (func: (err: any, data: T) => any) { }) } -function updateInstanceWithAnother > (instanceToUpdate: Model, baseInstance: Model) { - const obj = baseInstance.toJSON() +function saveInTransactionWithRetries > (model: T) { + return retryTransactionWrapper(() => { + return sequelizeTypescript.transaction(async transaction => { + await model.save({ transaction }) + }) + }) +} + +// --------------------------------------------------------------------------- + +function resetSequelizeInstance (instance: Model) { + return instance.reload() +} + +function filterNonExistingModels ( + fromDatabase: T[], + newModels: T[] +) { + return fromDatabase.filter(f => !newModels.find(newModel => newModel.hasSameUniqueKeysThan(f))) +} + +function deleteAllModels > (models: T[], transaction: Transaction) { + return Promise.all(models.map(f => f.destroy({ transaction }))) +} + +// --------------------------------------------------------------------------- + +function runInReadCommittedTransaction (fn: (t: Transaction) => Promise) { + const options = { isolationLevel: Transaction.ISOLATION_LEVELS.READ_COMMITTED } + + return sequelizeTypescript.transaction(options, t => fn(t)) +} + +function afterCommitIfTransaction (t: Transaction, fn: Function) { + if (t) return t.afterCommit(() => fn()) - for (const key of Object.keys(obj)) { - instanceToUpdate.set(key, obj[key]) - } + return fn() } // --------------------------------------------------------------------------- export { + resetSequelizeInstance, retryTransactionWrapper, transactionRetryer, - updateInstanceWithAnother + saveInTransactionWithRetries, + afterCommitIfTransaction, + filterNonExistingModels, + deleteAllModels, + runInReadCommittedTransaction }