aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <florian.bigard@gmail.com>2017-01-17 20:38:45 +0100
committerChocobozzz <florian.bigard@gmail.com>2017-01-17 20:50:45 +0100
commit4145c1c68923c13538a5b60d1b384037d0dded9d (patch)
tree36471645006f47d1118fcba59a4f5d3e84598856
parent98dffd102ef76872f027fedfc55cc0dc824b5bad (diff)
downloadPeerTube-4145c1c68923c13538a5b60d1b384037d0dded9d.tar.gz
PeerTube-4145c1c68923c13538a5b60d1b384037d0dded9d.tar.zst
PeerTube-4145c1c68923c13538a5b60d1b384037d0dded9d.zip
Server: transaction refractoring
-rw-r--r--server/controllers/api/remote/videos.js38
-rw-r--r--server/controllers/api/videos.js92
-rw-r--r--server/helpers/database-utils.js22
3 files changed, 68 insertions, 84 deletions
diff --git a/server/controllers/api/remote/videos.js b/server/controllers/api/remote/videos.js
index e8279fe2e..bfe61a35c 100644
--- a/server/controllers/api/remote/videos.js
+++ b/server/controllers/api/remote/videos.js
@@ -146,26 +146,19 @@ function addRemoteVideo (videoToCreateData, fromPod, finalCallback) {
146 video.setTags(tagInstances, options).asCallback(function (err) { 146 video.setTags(tagInstances, options).asCallback(function (err) {
147 return callback(err, t) 147 return callback(err, t)
148 }) 148 })
149 } 149 },
150
151 databaseUtils.commitTransaction
150 152
151 ], function (err, t) { 153 ], function (err, t) {
152 if (err) { 154 if (err) {
153 // This is just a debug because we will retry the insert 155 // This is just a debug because we will retry the insert
154 logger.debug('Cannot insert the remote video.', { error: err }) 156 logger.debug('Cannot insert the remote video.', { error: err })
155 157 return databaseUtils.rollbackTransaction(err, t, finalCallback)
156 // Abort transaction?
157 if (t) t.rollback()
158
159 return finalCallback(err)
160 } 158 }
161 159
162 // Commit transaction 160 logger.info('Remote video %s inserted.', videoToCreateData.name)
163 t.commit().asCallback(function (err) { 161 return finalCallback(null)
164 if (err) return finalCallback(err)
165
166 logger.info('Remote video %s inserted.', videoToCreateData.name)
167 return finalCallback(null)
168 })
169 }) 162 })
170} 163}
171 164
@@ -222,26 +215,19 @@ function updateRemoteVideo (videoAttributesToUpdate, fromPod, finalCallback) {
222 videoInstance.setTags(tagInstances, options).asCallback(function (err) { 215 videoInstance.setTags(tagInstances, options).asCallback(function (err) {
223 return callback(err, t) 216 return callback(err, t)
224 }) 217 })
225 } 218 },
219
220 databaseUtils.commitTransaction
226 221
227 ], function (err, t) { 222 ], function (err, t) {
228 if (err) { 223 if (err) {
229 // This is just a debug because we will retry the insert 224 // This is just a debug because we will retry the insert
230 logger.debug('Cannot update the remote video.', { error: err }) 225 logger.debug('Cannot update the remote video.', { error: err })
231 226 return databaseUtils.rollbackTransaction(err, t, finalCallback)
232 // Abort transaction?
233 if (t) t.rollback()
234
235 return finalCallback(err)
236 } 227 }
237 228
238 // Commit transaction 229 logger.info('Remote video %s updated', videoAttributesToUpdate.name)
239 t.commit().asCallback(function (err) { 230 return finalCallback(null)
240 if (err) return finalCallback(err)
241
242 logger.info('Remote video %s updated', videoAttributesToUpdate.name)
243 return finalCallback(null)
244 })
245 }) 231 })
246} 232}
247 233
diff --git a/server/controllers/api/videos.js b/server/controllers/api/videos.js
index ebfdb32f9..75a661bcc 100644
--- a/server/controllers/api/videos.js
+++ b/server/controllers/api/videos.js
@@ -120,14 +120,14 @@ function addVideoRetryWrapper (req, res, next) {
120 }) 120 })
121} 121}
122 122
123function addVideo (req, res, videoFile, callback) { 123function addVideo (req, res, videoFile, finalCallback) {
124 const videoInfos = req.body 124 const videoInfos = req.body
125 125
126 waterfall([ 126 waterfall([
127 127
128 databaseUtils.startSerializableTransaction, 128 databaseUtils.startSerializableTransaction,
129 129
130 function findOrCreateAuthor (t, callbackWaterfall) { 130 function findOrCreateAuthor (t, callback) {
131 const user = res.locals.oauth.token.User 131 const user = res.locals.oauth.token.User
132 132
133 const name = user.username 133 const name = user.username
@@ -136,19 +136,19 @@ function addVideo (req, res, videoFile, callback) {
136 const userId = user.id 136 const userId = user.id
137 137
138 db.Author.findOrCreateAuthor(name, podId, userId, t, function (err, authorInstance) { 138 db.Author.findOrCreateAuthor(name, podId, userId, t, function (err, authorInstance) {
139 return callbackWaterfall(err, t, authorInstance) 139 return callback(err, t, authorInstance)
140 }) 140 })
141 }, 141 },
142 142
143 function findOrCreateTags (t, author, callbackWaterfall) { 143 function findOrCreateTags (t, author, callback) {
144 const tags = videoInfos.tags 144 const tags = videoInfos.tags
145 145
146 db.Tag.findOrCreateTags(tags, t, function (err, tagInstances) { 146 db.Tag.findOrCreateTags(tags, t, function (err, tagInstances) {
147 return callbackWaterfall(err, t, author, tagInstances) 147 return callback(err, t, author, tagInstances)
148 }) 148 })
149 }, 149 },
150 150
151 function createVideoObject (t, author, tagInstances, callbackWaterfall) { 151 function createVideoObject (t, author, tagInstances, callback) {
152 const videoData = { 152 const videoData = {
153 name: videoInfos.name, 153 name: videoInfos.name,
154 remoteId: null, 154 remoteId: null,
@@ -160,77 +160,70 @@ function addVideo (req, res, videoFile, callback) {
160 160
161 const video = db.Video.build(videoData) 161 const video = db.Video.build(videoData)
162 162
163 return callbackWaterfall(null, t, author, tagInstances, video) 163 return callback(null, t, author, tagInstances, video)
164 }, 164 },
165 165
166 // Set the videoname the same as the id 166 // Set the videoname the same as the id
167 function renameVideoFile (t, author, tagInstances, video, callbackWaterfall) { 167 function renameVideoFile (t, author, tagInstances, video, callback) {
168 const videoDir = constants.CONFIG.STORAGE.VIDEOS_DIR 168 const videoDir = constants.CONFIG.STORAGE.VIDEOS_DIR
169 const source = path.join(videoDir, videoFile.filename) 169 const source = path.join(videoDir, videoFile.filename)
170 const destination = path.join(videoDir, video.getVideoFilename()) 170 const destination = path.join(videoDir, video.getVideoFilename())
171 171
172 fs.rename(source, destination, function (err) { 172 fs.rename(source, destination, function (err) {
173 if (err) return callbackWaterfall(err) 173 if (err) return callback(err)
174 174
175 // This is important in case if there is another attempt 175 // This is important in case if there is another attempt
176 videoFile.filename = video.getVideoFilename() 176 videoFile.filename = video.getVideoFilename()
177 return callbackWaterfall(null, t, author, tagInstances, video) 177 return callback(null, t, author, tagInstances, video)
178 }) 178 })
179 }, 179 },
180 180
181 function insertVideoIntoDB (t, author, tagInstances, video, callbackWaterfall) { 181 function insertVideoIntoDB (t, author, tagInstances, video, callback) {
182 const options = { transaction: t } 182 const options = { transaction: t }
183 183
184 // Add tags association 184 // Add tags association
185 video.save(options).asCallback(function (err, videoCreated) { 185 video.save(options).asCallback(function (err, videoCreated) {
186 if (err) return callbackWaterfall(err) 186 if (err) return callback(err)
187 187
188 // Do not forget to add Author informations to the created video 188 // Do not forget to add Author informations to the created video
189 videoCreated.Author = author 189 videoCreated.Author = author
190 190
191 return callbackWaterfall(err, t, tagInstances, videoCreated) 191 return callback(err, t, tagInstances, videoCreated)
192 }) 192 })
193 }, 193 },
194 194
195 function associateTagsToVideo (t, tagInstances, video, callbackWaterfall) { 195 function associateTagsToVideo (t, tagInstances, video, callback) {
196 const options = { transaction: t } 196 const options = { transaction: t }
197 197
198 video.setTags(tagInstances, options).asCallback(function (err) { 198 video.setTags(tagInstances, options).asCallback(function (err) {
199 video.Tags = tagInstances 199 video.Tags = tagInstances
200 200
201 return callbackWaterfall(err, t, video) 201 return callback(err, t, video)
202 }) 202 })
203 }, 203 },
204 204
205 function sendToFriends (t, video, callbackWaterfall) { 205 function sendToFriends (t, video, callback) {
206 video.toAddRemoteJSON(function (err, remoteVideo) { 206 video.toAddRemoteJSON(function (err, remoteVideo) {
207 if (err) return callbackWaterfall(err) 207 if (err) return callback(err)
208 208
209 // Now we'll add the video's meta data to our friends 209 // Now we'll add the video's meta data to our friends
210 friends.addVideoToFriends(remoteVideo, t, function (err) { 210 friends.addVideoToFriends(remoteVideo, t, function (err) {
211 return callbackWaterfall(err, t) 211 return callback(err, t)
212 }) 212 })
213 }) 213 })
214 } 214 },
215
216 databaseUtils.commitTransaction
215 217
216 ], function andFinally (err, t) { 218 ], function andFinally (err, t) {
217 if (err) { 219 if (err) {
218 // This is just a debug because we will retry the insert 220 // This is just a debug because we will retry the insert
219 logger.debug('Cannot insert the video.', { error: err }) 221 logger.debug('Cannot insert the video.', { error: err })
220 222 return databaseUtils.rollbackTransaction(err, t, finalCallback)
221 // Abort transaction?
222 if (t) t.rollback()
223
224 return callback(err)
225 } 223 }
226 224
227 // Commit transaction 225 logger.info('Video with name %s created.', videoInfos.name)
228 t.commit().asCallback(function (err) { 226 return finalCallback(null)
229 if (err) return callback(err)
230
231 logger.info('Video with name %s created.', videoInfos.name)
232 return callback(null)
233 })
234 }) 227 })
235} 228}
236 229
@@ -301,15 +294,14 @@ function updateVideo (req, res, finalCallback) {
301 friends.updateVideoToFriends(json, t, function (err) { 294 friends.updateVideoToFriends(json, t, function (err) {
302 return callback(err, t) 295 return callback(err, t)
303 }) 296 })
304 } 297 },
298
299 databaseUtils.commitTransaction
305 300
306 ], function andFinally (err, t) { 301 ], function andFinally (err, t) {
307 if (err) { 302 if (err) {
308 logger.debug('Cannot update the video.', { error: err }) 303 logger.debug('Cannot update the video.', { error: err })
309 304
310 // Abort transaction?
311 if (t) t.rollback()
312
313 // Force fields we want to update 305 // Force fields we want to update
314 // If the transaction is retried, sequelize will think the object has not changed 306 // If the transaction is retried, sequelize will think the object has not changed
315 // So it will skip the SQL request, even if the last one was ROLLBACKed! 307 // So it will skip the SQL request, even if the last one was ROLLBACKed!
@@ -318,16 +310,11 @@ function updateVideo (req, res, finalCallback) {
318 videoInstance.set(key, value) 310 videoInstance.set(key, value)
319 }) 311 })
320 312
321 return finalCallback(err) 313 return databaseUtils.rollbackTransaction(err, t, finalCallback)
322 } 314 }
323 315
324 // Commit transaction 316 logger.info('Video with name %s updated.', videoInfosToUpdate.name)
325 t.commit().asCallback(function (err) { 317 return finalCallback(null)
326 if (err) return finalCallback(err)
327
328 logger.info('Video with name %s updated.', videoInfosToUpdate.name)
329 return finalCallback(null)
330 })
331 }) 318 })
332} 319}
333 320
@@ -427,25 +414,18 @@ function reportVideoAbuse (req, res, finalCallback) {
427 } 414 }
428 415
429 return callback(null, t) 416 return callback(null, t)
430 } 417 },
418
419 databaseUtils.commitTransaction
431 420
432 ], function andFinally (err, t) { 421 ], function andFinally (err, t) {
433 if (err) { 422 if (err) {
434 logger.debug('Cannot update the video.', { error: err }) 423 logger.debug('Cannot update the video.', { error: err })
435 424 return databaseUtils.rollbackTransaction(err, t, finalCallback)
436 // Abort transaction?
437 if (t) t.rollback()
438
439 return finalCallback(err)
440 } 425 }
441 426
442 // Commit transaction 427 logger.info('Abuse report for video %s created.', videoInstance.name)
443 t.commit().asCallback(function (err) { 428 return finalCallback(null)
444 if (err) return finalCallback(err)
445
446 logger.info('Abuse report for video %s created.', videoInstance.name)
447 return finalCallback(null)
448 })
449 }) 429 })
450} 430}
451 431
diff --git a/server/helpers/database-utils.js b/server/helpers/database-utils.js
index 046717517..6fe7e99aa 100644
--- a/server/helpers/database-utils.js
+++ b/server/helpers/database-utils.js
@@ -6,9 +6,27 @@ const db = require('../initializers/database')
6const logger = require('./logger') 6const logger = require('./logger')
7 7
8const utils = { 8const utils = {
9 commitTransaction,
9 retryTransactionWrapper, 10 retryTransactionWrapper,
10 transactionRetryer, 11 rollbackTransaction,
11 startSerializableTransaction 12 startSerializableTransaction,
13 transactionRetryer
14}
15
16function commitTransaction (t, callback) {
17 return t.commit().asCallback(callback)
18}
19
20function rollbackTransaction (err, t, callback) {
21 // Try to rollback transaction
22 if (t) {
23 // Do not catch err, report the original one
24 t.rollback().asCallback(function () {
25 return callback(err)
26 })
27 } else {
28 return callback(err)
29 }
12} 30}
13 31
14// { arguments, errorMessage } 32// { arguments, errorMessage }