aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/helpers/database-utils.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/helpers/database-utils.ts')
-rw-r--r--server/helpers/database-utils.ts69
1 files changed, 22 insertions, 47 deletions
diff --git a/server/helpers/database-utils.ts b/server/helpers/database-utils.ts
index f8ee9a454..f761cfb89 100644
--- a/server/helpers/database-utils.ts
+++ b/server/helpers/database-utils.ts
@@ -1,70 +1,45 @@
1import * as Sequelize from 'sequelize'
2// TODO: import from ES6 when retry typing file will include errorFilter function 1// TODO: import from ES6 when retry typing file will include errorFilter function
3import * as retry from 'async/retry' 2import * as retry from 'async/retry'
3import * as Promise from 'bluebird'
4 4
5import { database as db } from '../initializers/database'
6import { logger } from './logger' 5import { logger } from './logger'
7 6
8function commitTransaction (t: Sequelize.Transaction, callback: (err: Error) => void) {
9 return t.commit().asCallback(callback)
10}
11
12function rollbackTransaction (err: Error, t: Sequelize.Transaction, callback: (err: Error) => void) {
13 // Try to rollback transaction
14 if (t) {
15 // Do not catch err, report the original one
16 t.rollback().asCallback(function () {
17 return callback(err)
18 })
19 } else {
20 return callback(err)
21 }
22}
23
24type RetryTransactionWrapperOptions = { errorMessage: string, arguments?: any[] } 7type RetryTransactionWrapperOptions = { errorMessage: string, arguments?: any[] }
25function retryTransactionWrapper (functionToRetry: Function, options: RetryTransactionWrapperOptions, finalCallback: Function) { 8function retryTransactionWrapper (functionToRetry: (... args) => Promise<any>, options: RetryTransactionWrapperOptions) {
26 const args = options.arguments ? options.arguments : [] 9 const args = options.arguments ? options.arguments : []
27 10
28 transactionRetryer( 11 return transactionRetryer(
29 function (callback) { 12 function (callback) {
30 return functionToRetry.apply(this, args.concat([ callback ])) 13 functionToRetry.apply(this, args)
31 }, 14 .then(result => callback(null, result))
32 function (err) { 15 .catch(err => callback(err))
33 if (err) {
34 logger.error(options.errorMessage, { error: err })
35 }
36
37 // Do not return the error, continue the process
38 return finalCallback(null)
39 } 16 }
40 ) 17 )
18 .catch(err => {
19 // Do not throw the error, continue the process
20 logger.error(options.errorMessage, { error: err })
21 })
41} 22}
42 23
43function transactionRetryer (func: Function, callback: (err: Error) => void) { 24function transactionRetryer (func: Function) {
44 retry({ 25 return new Promise((res, rej) => {
45 times: 5, 26 retry({
46 27 times: 5,
47 errorFilter: function (err) {
48 const willRetry = (err.name === 'SequelizeDatabaseError')
49 logger.debug('Maybe retrying the transaction function.', { willRetry })
50 return willRetry
51 }
52 }, func, callback)
53}
54 28
55function startSerializableTransaction (callback: (err: Error, t: Sequelize.Transaction) => void) { 29 errorFilter: function (err) {
56 db.sequelize.transaction(/* { isolationLevel: 'SERIALIZABLE' } */).asCallback(function (err, t) { 30 const willRetry = (err.name === 'SequelizeDatabaseError')
57 // We force to return only two parameters 31 logger.debug('Maybe retrying the transaction function.', { willRetry })
58 return callback(err, t) 32 return willRetry
33 }
34 }, func, function (err) {
35 err ? rej(err) : res()
36 })
59 }) 37 })
60} 38}
61 39
62// --------------------------------------------------------------------------- 40// ---------------------------------------------------------------------------
63 41
64export { 42export {
65 commitTransaction,
66 retryTransactionWrapper, 43 retryTransactionWrapper,
67 rollbackTransaction,
68 startSerializableTransaction,
69 transactionRetryer 44 transactionRetryer
70} 45}