diff options
author | Chocobozzz <florian.bigard@gmail.com> | 2017-01-15 19:53:11 +0100 |
---|---|---|
committer | Chocobozzz <florian.bigard@gmail.com> | 2017-01-15 19:53:11 +0100 |
commit | 4df023f2d4e4ea93d3fbc6010f0460511ba45140 (patch) | |
tree | 02f8df3be3d9a3fff943aa186daed22f0825f266 | |
parent | 9bce75925eb972f7a49c25250e636b7b76734475 (diff) | |
download | PeerTube-4df023f2d4e4ea93d3fbc6010f0460511ba45140.tar.gz PeerTube-4df023f2d4e4ea93d3fbc6010f0460511ba45140.tar.zst PeerTube-4df023f2d4e4ea93d3fbc6010f0460511ba45140.zip |
Server: create transaction refractoring
-rwxr-xr-x | scripts/reset-password.js | 1 | ||||
-rw-r--r-- | server/controllers/api/remote/videos.js | 18 | ||||
-rw-r--r-- | server/controllers/api/videos.js | 38 | ||||
-rw-r--r-- | server/helpers/database-utils.js | 55 | ||||
-rw-r--r-- | server/helpers/utils.js | 36 |
5 files changed, 75 insertions, 73 deletions
diff --git a/scripts/reset-password.js b/scripts/reset-password.js index e5f59a267..6a00b37eb 100755 --- a/scripts/reset-password.js +++ b/scripts/reset-password.js | |||
@@ -6,7 +6,6 @@ | |||
6 | 6 | ||
7 | const program = require('commander') | 7 | const program = require('commander') |
8 | 8 | ||
9 | const constants = require('../server/initializers/constants') | ||
10 | const db = require('../server/initializers/database') | 9 | const db = require('../server/initializers/database') |
11 | 10 | ||
12 | program | 11 | program |
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 | |||
10 | const videosValidators = middlewares.validators.remote.videos | 10 | const videosValidators = middlewares.validators.remote.videos |
11 | const signatureValidators = middlewares.validators.remote.signature | 11 | const signatureValidators = middlewares.validators.remote.signature |
12 | const logger = require('../../../helpers/logger') | 12 | const logger = require('../../../helpers/logger') |
13 | const utils = require('../../../helpers/utils') | 13 | const databaseUtils = require('../../../helpers/database-utils') |
14 | 14 | ||
15 | const router = express.Router() | 15 | const 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 | ||
77 | function addRemoteVideo (videoToCreateData, fromPod, finalCallback) { | 77 | function 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 | ||
186 | function updateRemoteVideo (videoAttributesToUpdate, fromPod, finalCallback) { | 182 | function 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 | |||
20 | const validatorsVideos = validators.videos | 20 | const validatorsVideos = validators.videos |
21 | const search = middlewares.search | 21 | const search = middlewares.search |
22 | const sort = middlewares.sort | 22 | const sort = middlewares.sort |
23 | const databaseUtils = require('../../helpers/database-utils') | ||
23 | const utils = require('../../helpers/utils') | 24 | const utils = require('../../helpers/utils') |
24 | 25 | ||
25 | const router = express.Router() | 26 | const 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 | ||
386 | function reportVideoAbuseRetryWrapper (req, res, next) { | 379 | function 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 | ||
402 | function reportVideoAbuse (req, res, finalCallback) { | 392 | function 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 | |||
3 | const retry = require('async/retry') | ||
4 | |||
5 | const db = require('../initializers/database') | ||
6 | const logger = require('./logger') | ||
7 | |||
8 | const utils = { | ||
9 | retryTransactionWrapper, | ||
10 | transactionRetryer, | ||
11 | startSerializableTransaction | ||
12 | } | ||
13 | |||
14 | // { arguments, errorMessage } | ||
15 | function 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 | |||
33 | function 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 | |||
45 | function 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 | |||
55 | module.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 | ||
3 | const crypto = require('crypto') | 3 | const crypto = require('crypto') |
4 | const retry = require('async/retry') | ||
5 | 4 | ||
6 | const logger = require('./logger') | 5 | const 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 | ||
18 | function badRequest (req, res, next) { | 15 | function badRequest (req, res, next) { |
@@ -49,37 +46,6 @@ function getFormatedObjects (objects, objectsTotal) { | |||
49 | } | 46 | } |
50 | } | 47 | } |
51 | 48 | ||
52 | // { arguments, errorMessage } | ||
53 | function 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 | |||
71 | function 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 | ||
85 | module.exports = utils | 51 | module.exports = utils |