aboutsummaryrefslogtreecommitdiffhomepage
path: root/server
diff options
context:
space:
mode:
authorChocobozzz <florian.bigard@gmail.com>2017-01-15 19:53:11 +0100
committerChocobozzz <florian.bigard@gmail.com>2017-01-15 19:53:11 +0100
commit4df023f2d4e4ea93d3fbc6010f0460511ba45140 (patch)
tree02f8df3be3d9a3fff943aa186daed22f0825f266 /server
parent9bce75925eb972f7a49c25250e636b7b76734475 (diff)
downloadPeerTube-4df023f2d4e4ea93d3fbc6010f0460511ba45140.tar.gz
PeerTube-4df023f2d4e4ea93d3fbc6010f0460511ba45140.tar.zst
PeerTube-4df023f2d4e4ea93d3fbc6010f0460511ba45140.zip
Server: create transaction refractoring
Diffstat (limited to 'server')
-rw-r--r--server/controllers/api/remote/videos.js18
-rw-r--r--server/controllers/api/videos.js38
-rw-r--r--server/helpers/database-utils.js55
-rw-r--r--server/helpers/utils.js36
4 files changed, 75 insertions, 72 deletions
diff --git a/server/controllers/api/remote/videos.js b/server/controllers/api/remote/videos.js
index 9d007246f..33b521c5f 100644
--- a/server/controllers/api/remote/videos.js
+++ b/server/controllers/api/remote/videos.js
@@ -10,7 +10,7 @@ const secureMiddleware = middlewares.secure
10const videosValidators = middlewares.validators.remote.videos 10const videosValidators = middlewares.validators.remote.videos
11const signatureValidators = middlewares.validators.remote.signature 11const signatureValidators = middlewares.validators.remote.signature
12const logger = require('../../../helpers/logger') 12const logger = require('../../../helpers/logger')
13const utils = require('../../../helpers/utils') 13const databaseUtils = require('../../../helpers/database-utils')
14 14
15const router = express.Router() 15const router = express.Router()
16 16
@@ -71,7 +71,7 @@ function addRemoteVideoRetryWrapper (videoToCreateData, fromPod, finalCallback)
71 errorMessage: 'Cannot insert the remote video with many retries.' 71 errorMessage: 'Cannot insert the remote video with many retries.'
72 } 72 }
73 73
74 utils.retryWrapper(addRemoteVideo, options, finalCallback) 74 databaseUtils.retryTransactionWrapper(addRemoteVideo, options, finalCallback)
75} 75}
76 76
77function addRemoteVideo (videoToCreateData, fromPod, finalCallback) { 77function addRemoteVideo (videoToCreateData, fromPod, finalCallback) {
@@ -79,11 +79,7 @@ function addRemoteVideo (videoToCreateData, fromPod, finalCallback) {
79 79
80 waterfall([ 80 waterfall([
81 81
82 function startTransaction (callback) { 82 databaseUtils.startSerializableTransaction,
83 db.sequelize.transaction({ isolationLevel: 'SERIALIZABLE' }).asCallback(function (err, t) {
84 return callback(err, t)
85 })
86 },
87 83
88 function findOrCreateAuthor (t, callback) { 84 function findOrCreateAuthor (t, callback) {
89 const name = videoToCreateData.author 85 const name = videoToCreateData.author
@@ -180,7 +176,7 @@ function updateRemoteVideoRetryWrapper (videoAttributesToUpdate, fromPod, finalC
180 errorMessage: 'Cannot update the remote video with many retries' 176 errorMessage: 'Cannot update the remote video with many retries'
181 } 177 }
182 178
183 utils.retryWrapper(updateRemoteVideo, options, finalCallback) 179 databaseUtils.retryWrapper(updateRemoteVideo, options, finalCallback)
184} 180}
185 181
186function updateRemoteVideo (videoAttributesToUpdate, fromPod, finalCallback) { 182function updateRemoteVideo (videoAttributesToUpdate, fromPod, finalCallback) {
@@ -188,11 +184,7 @@ function updateRemoteVideo (videoAttributesToUpdate, fromPod, finalCallback) {
188 184
189 waterfall([ 185 waterfall([
190 186
191 function startTransaction (callback) { 187 databaseUtils.startSerializableTransaction,
192 db.sequelize.transaction({ isolationLevel: 'SERIALIZABLE' }).asCallback(function (err, t) {
193 return callback(err, t)
194 })
195 },
196 188
197 function findVideo (t, callback) { 189 function findVideo (t, callback) {
198 fetchVideo(fromPod.host, videoAttributesToUpdate.remoteId, function (err, videoInstance) { 190 fetchVideo(fromPod.host, videoAttributesToUpdate.remoteId, function (err, videoInstance) {
diff --git a/server/controllers/api/videos.js b/server/controllers/api/videos.js
index 9a50a29be..ebfdb32f9 100644
--- a/server/controllers/api/videos.js
+++ b/server/controllers/api/videos.js
@@ -20,6 +20,7 @@ const validatorsSort = validators.sort
20const validatorsVideos = validators.videos 20const validatorsVideos = validators.videos
21const search = middlewares.search 21const search = middlewares.search
22const sort = middlewares.sort 22const sort = middlewares.sort
23const databaseUtils = require('../../helpers/database-utils')
23const utils = require('../../helpers/utils') 24const utils = require('../../helpers/utils')
24 25
25const router = express.Router() 26const router = express.Router()
@@ -111,7 +112,7 @@ function addVideoRetryWrapper (req, res, next) {
111 errorMessage: 'Cannot insert the video with many retries.' 112 errorMessage: 'Cannot insert the video with many retries.'
112 } 113 }
113 114
114 utils.retryWrapper(addVideo, options, function (err) { 115 databaseUtils.retryTransactionWrapper(addVideo, options, function (err) {
115 if (err) return next(err) 116 if (err) return next(err)
116 117
117 // TODO : include Location of the new video -> 201 118 // TODO : include Location of the new video -> 201
@@ -124,11 +125,7 @@ function addVideo (req, res, videoFile, callback) {
124 125
125 waterfall([ 126 waterfall([
126 127
127 function startTransaction (callbackWaterfall) { 128 databaseUtils.startSerializableTransaction,
128 db.sequelize.transaction({ isolationLevel: 'SERIALIZABLE' }).asCallback(function (err, t) {
129 return callbackWaterfall(err, t)
130 })
131 },
132 129
133 function findOrCreateAuthor (t, callbackWaterfall) { 130 function findOrCreateAuthor (t, callbackWaterfall) {
134 const user = res.locals.oauth.token.User 131 const user = res.locals.oauth.token.User
@@ -243,7 +240,7 @@ function updateVideoRetryWrapper (req, res, next) {
243 errorMessage: 'Cannot update the video with many retries.' 240 errorMessage: 'Cannot update the video with many retries.'
244 } 241 }
245 242
246 utils.retryWrapper(updateVideo, options, function (err) { 243 databaseUtils.retryTransactionWrapper(updateVideo, options, function (err) {
247 if (err) return next(err) 244 if (err) return next(err)
248 245
249 // TODO : include Location of the new video -> 201 246 // TODO : include Location of the new video -> 201
@@ -258,11 +255,7 @@ function updateVideo (req, res, finalCallback) {
258 255
259 waterfall([ 256 waterfall([
260 257
261 function startTransaction (callback) { 258 databaseUtils.startSerializableTransaction,
262 db.sequelize.transaction({ isolationLevel: 'SERIALIZABLE' }).asCallback(function (err, t) {
263 return callback(err, t)
264 })
265 },
266 259
267 function findOrCreateTags (t, callback) { 260 function findOrCreateTags (t, callback) {
268 if (videoInfosToUpdate.tags) { 261 if (videoInfosToUpdate.tags) {
@@ -384,19 +377,16 @@ function listVideoAbuses (req, res, next) {
384} 377}
385 378
386function reportVideoAbuseRetryWrapper (req, res, next) { 379function reportVideoAbuseRetryWrapper (req, res, next) {
387 utils.transactionRetryer( 380 const options = {
388 function (callback) { 381 arguments: [ req, res ],
389 return reportVideoAbuse(req, res, callback) 382 errorMessage: 'Cannot report abuse to the video with many retries.'
390 }, 383 }
391 function (err) {
392 if (err) {
393 logger.error('Cannot report abuse to the video with many retries.', { error: err })
394 return next(err)
395 }
396 384
397 return res.type('json').status(204).end() 385 databaseUtils.retryTransactionWrapper(reportVideoAbuse, options, function (err) {
398 } 386 if (err) return next(err)
399 ) 387
388 return res.type('json').status(204).end()
389 })
400} 390}
401 391
402function reportVideoAbuse (req, res, finalCallback) { 392function reportVideoAbuse (req, res, finalCallback) {
diff --git a/server/helpers/database-utils.js b/server/helpers/database-utils.js
new file mode 100644
index 000000000..046717517
--- /dev/null
+++ b/server/helpers/database-utils.js
@@ -0,0 +1,55 @@
1'use strict'
2
3const retry = require('async/retry')
4
5const db = require('../initializers/database')
6const logger = require('./logger')
7
8const utils = {
9 retryTransactionWrapper,
10 transactionRetryer,
11 startSerializableTransaction
12}
13
14// { arguments, errorMessage }
15function retryTransactionWrapper (functionToRetry, options, finalCallback) {
16 const args = options.arguments ? options.arguments : []
17
18 utils.transactionRetryer(
19 function (callback) {
20 return functionToRetry.apply(this, args.concat([ callback ]))
21 },
22 function (err) {
23 if (err) {
24 logger.error(options.errorMessage, { error: err })
25 }
26
27 // Do not return the error, continue the process
28 return finalCallback(null)
29 }
30 )
31}
32
33function transactionRetryer (func, callback) {
34 retry({
35 times: 5,
36
37 errorFilter: function (err) {
38 const willRetry = (err.name === 'SequelizeDatabaseError')
39 logger.debug('Maybe retrying the transaction function.', { willRetry })
40 return willRetry
41 }
42 }, func, callback)
43}
44
45function startSerializableTransaction (callback) {
46 console.log(db)
47 db.sequelize.transaction({ isolationLevel: 'SERIALIZABLE' }).asCallback(function (err, t) {
48 // We force to return only two parameters
49 return callback(err, t)
50 })
51}
52
53// ---------------------------------------------------------------------------
54
55module.exports = utils
diff --git a/server/helpers/utils.js b/server/helpers/utils.js
index fb4dd08cc..9f4b14582 100644
--- a/server/helpers/utils.js
+++ b/server/helpers/utils.js
@@ -1,7 +1,6 @@
1'use strict' 1'use strict'
2 2
3const crypto = require('crypto') 3const crypto = require('crypto')
4const retry = require('async/retry')
5 4
6const logger = require('./logger') 5const logger = require('./logger')
7 6
@@ -10,9 +9,7 @@ const utils = {
10 cleanForExit, 9 cleanForExit,
11 generateRandomString, 10 generateRandomString,
12 isTestInstance, 11 isTestInstance,
13 getFormatedObjects, 12 getFormatedObjects
14 retryWrapper,
15 transactionRetryer
16} 13}
17 14
18function badRequest (req, res, next) { 15function badRequest (req, res, next) {
@@ -49,37 +46,6 @@ function getFormatedObjects (objects, objectsTotal) {
49 } 46 }
50} 47}
51 48
52// { arguments, errorMessage }
53function retryWrapper (functionToRetry, options, finalCallback) {
54 const args = options.arguments ? options.arguments : []
55
56 utils.transactionRetryer(
57 function (callback) {
58 return functionToRetry.apply(this, args.concat([ callback ]))
59 },
60 function (err) {
61 if (err) {
62 logger.error(options.errorMessage, { error: err })
63 }
64
65 // Do not return the error, continue the process
66 return finalCallback(null)
67 }
68 )
69}
70
71function transactionRetryer (func, callback) {
72 retry({
73 times: 5,
74
75 errorFilter: function (err) {
76 const willRetry = (err.name === 'SequelizeDatabaseError')
77 logger.debug('Maybe retrying the transaction function.', { willRetry })
78 return willRetry
79 }
80 }, func, callback)
81}
82
83// --------------------------------------------------------------------------- 49// ---------------------------------------------------------------------------
84 50
85module.exports = utils 51module.exports = utils