aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <florian.bigard@gmail.com>2017-09-12 14:17:46 +0200
committerChocobozzz <florian.bigard@gmail.com>2017-09-12 14:17:46 +0200
commit91f6f169b1110eeae6ebf5c387f4204b0d07703c (patch)
treecba01c954c311b8b5296222994a64da58c17789e
parent6d33593a0829a7f041127d50d4c455456550a47f (diff)
downloadPeerTube-91f6f169b1110eeae6ebf5c387f4204b0d07703c.tar.gz
PeerTube-91f6f169b1110eeae6ebf5c387f4204b0d07703c.tar.zst
PeerTube-91f6f169b1110eeae6ebf5c387f4204b0d07703c.zip
Fix concurrency error when deleting a video
-rw-r--r--server/controllers/api/videos/index.ts36
-rw-r--r--server/lib/friends.ts4
-rw-r--r--server/models/video/video.ts6
3 files changed, 30 insertions, 16 deletions
diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts
index 7a9cd9d37..6fa84c801 100644
--- a/server/controllers/api/videos/index.ts
+++ b/server/controllers/api/videos/index.ts
@@ -45,6 +45,7 @@ import { VideoCreate, VideoUpdate } from '../../../../shared'
45import { abuseVideoRouter } from './abuse' 45import { abuseVideoRouter } from './abuse'
46import { blacklistRouter } from './blacklist' 46import { blacklistRouter } from './blacklist'
47import { rateVideoRouter } from './rate' 47import { rateVideoRouter } from './rate'
48import { VideoInstance } from '../../../models/video/video-interface'
48 49
49const videosRouter = express.Router() 50const videosRouter = express.Router()
50 51
@@ -106,7 +107,7 @@ videosRouter.get('/:id',
106videosRouter.delete('/:id', 107videosRouter.delete('/:id',
107 authenticate, 108 authenticate,
108 videosRemoveValidator, 109 videosRemoveValidator,
109 removeVideo 110 removeVideoRetryWrapper
110) 111)
111 112
112videosRouter.get('/search/:value', 113videosRouter.get('/search/:value',
@@ -291,7 +292,6 @@ function updateVideoRetryWrapper (req: express.Request, res: express.Response, n
291 292
292 retryTransactionWrapper(updateVideo, options) 293 retryTransactionWrapper(updateVideo, options)
293 .then(() => { 294 .then(() => {
294 // TODO : include Location of the new video -> 201
295 return res.type('json').status(204).end() 295 return res.type('json').status(204).end()
296 }) 296 })
297 .catch(err => next(err)) 297 .catch(err => next(err))
@@ -396,18 +396,32 @@ function listVideos (req: express.Request, res: express.Response, next: express.
396 .catch(err => next(err)) 396 .catch(err => next(err))
397} 397}
398 398
399function removeVideo (req: express.Request, res: express.Response, next: express.NextFunction) { 399function removeVideoRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
400 const videoInstance = res.locals.video 400 const options = {
401 arguments: [ req, res ],
402 errorMessage: 'Cannot remove the video with many retries.'
403 }
401 404
402 videoInstance.destroy() 405 retryTransactionWrapper(removeVideo, options)
403 .then(() => { 406 .then(() => {
404 logger.info('Video with name %s and uuid %s deleted.', videoInstance.name, videoInstance.uuid) 407 return res.type('json').status(204).end()
405 res.type('json').status(204).end()
406 })
407 .catch(err => {
408 logger.error('Errors when removed the video.', err)
409 return next(err)
410 }) 408 })
409 .catch(err => next(err))
410}
411
412function removeVideo (req: express.Request, res: express.Response) {
413 const videoInstance: VideoInstance = res.locals.video
414
415 return db.sequelize.transaction(t => {
416 return videoInstance.destroy({ transaction: t })
417 })
418 .then(() => {
419 logger.info('Video with name %s and uuid %s deleted.', videoInstance.name, videoInstance.uuid)
420 })
421 .catch(err => {
422 logger.error('Errors when removed the video.', err)
423 throw err
424 })
411} 425}
412 426
413function searchVideos (req: express.Request, res: express.Response, next: express.NextFunction) { 427function searchVideos (req: express.Request, res: express.Response, next: express.NextFunction) {
diff --git a/server/lib/friends.ts b/server/lib/friends.ts
index 3f0ce3f33..ea9ddbe8d 100644
--- a/server/lib/friends.ts
+++ b/server/lib/friends.ts
@@ -80,12 +80,12 @@ function updateVideoToFriends (videoData: RemoteVideoUpdateData, transaction: Se
80 return createRequest(options) 80 return createRequest(options)
81} 81}
82 82
83function removeVideoToFriends (videoParams: RemoteVideoRemoveData) { 83function removeVideoToFriends (videoParams: RemoteVideoRemoveData, transaction: Sequelize.Transaction) {
84 const options = { 84 const options = {
85 type: ENDPOINT_ACTIONS.REMOVE, 85 type: ENDPOINT_ACTIONS.REMOVE,
86 endpoint: REQUEST_ENDPOINTS.VIDEOS, 86 endpoint: REQUEST_ENDPOINTS.VIDEOS,
87 data: videoParams, 87 data: videoParams,
88 transaction: null 88 transaction
89 } 89 }
90 return createRequest(options) 90 return createRequest(options)
91} 91}
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index 1134525f0..e011c3b4d 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -300,7 +300,7 @@ function associate (models) {
300 }) 300 })
301} 301}
302 302
303function afterDestroy (video: VideoInstance) { 303function afterDestroy (video: VideoInstance, options: { transaction: Sequelize.Transaction }) {
304 const tasks = [] 304 const tasks = []
305 305
306 tasks.push( 306 tasks.push(
@@ -314,10 +314,10 @@ function afterDestroy (video: VideoInstance) {
314 314
315 tasks.push( 315 tasks.push(
316 video.removePreview(), 316 video.removePreview(),
317 removeVideoToFriends(removeVideoToFriendsParams) 317 removeVideoToFriends(removeVideoToFriendsParams, options.transaction)
318 ) 318 )
319 319
320 // TODO: check files is populated 320 // Remove physical files and torrents
321 video.VideoFiles.forEach(file => { 321 video.VideoFiles.forEach(file => {
322 video.removeFile(file), 322 video.removeFile(file),
323 video.removeTorrent(file) 323 video.removeTorrent(file)