aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/controllers/api/videos
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2018-06-13 14:27:40 +0200
committerChocobozzz <me@florianbigard.com>2018-06-13 14:27:40 +0200
commit90d4bb8125e80c8060416d4d135ddeaf0a622ede (patch)
treeb3b7181329a08ecc930b54fe7b48095c4155393c /server/controllers/api/videos
parent3cd0734fd9b0ff21aaef02317a874e8f1c06e027 (diff)
downloadPeerTube-90d4bb8125e80c8060416d4d135ddeaf0a622ede.tar.gz
PeerTube-90d4bb8125e80c8060416d4d135ddeaf0a622ede.tar.zst
PeerTube-90d4bb8125e80c8060416d4d135ddeaf0a622ede.zip
Refractor retry transaction function
Diffstat (limited to 'server/controllers/api/videos')
-rw-r--r--server/controllers/api/videos/abuse.ts25
-rw-r--r--server/controllers/api/videos/comment.ts68
-rw-r--r--server/controllers/api/videos/index.ts62
-rw-r--r--server/controllers/api/videos/rate.ts18
4 files changed, 56 insertions, 117 deletions
diff --git a/server/controllers/api/videos/abuse.ts b/server/controllers/api/videos/abuse.ts
index 61ff3af4f..3413ae894 100644
--- a/server/controllers/api/videos/abuse.ts
+++ b/server/controllers/api/videos/abuse.ts
@@ -1,12 +1,18 @@
1import * as express from 'express' 1import * as express from 'express'
2import { UserRight, VideoAbuseCreate } from '../../../../shared' 2import { UserRight, VideoAbuseCreate } from '../../../../shared'
3import { retryTransactionWrapper } from '../../../helpers/database-utils'
4import { logger } from '../../../helpers/logger' 3import { logger } from '../../../helpers/logger'
5import { getFormattedObjects } from '../../../helpers/utils' 4import { getFormattedObjects } from '../../../helpers/utils'
6import { sequelizeTypescript } from '../../../initializers' 5import { sequelizeTypescript } from '../../../initializers'
7import { sendVideoAbuse } from '../../../lib/activitypub/send' 6import { sendVideoAbuse } from '../../../lib/activitypub/send'
8import { 7import {
9 asyncMiddleware, authenticate, ensureUserHasRight, paginationValidator, setDefaultSort, setDefaultPagination, videoAbuseReportValidator, 8 asyncMiddleware,
9 asyncRetryTransactionMiddleware,
10 authenticate,
11 ensureUserHasRight,
12 paginationValidator,
13 setDefaultPagination,
14 setDefaultSort,
15 videoAbuseReportValidator,
10 videoAbusesSortValidator 16 videoAbusesSortValidator
11} from '../../../middlewares' 17} from '../../../middlewares'
12import { AccountModel } from '../../../models/account/account' 18import { AccountModel } from '../../../models/account/account'
@@ -27,7 +33,7 @@ abuseVideoRouter.get('/abuse',
27abuseVideoRouter.post('/:id/abuse', 33abuseVideoRouter.post('/:id/abuse',
28 authenticate, 34 authenticate,
29 asyncMiddleware(videoAbuseReportValidator), 35 asyncMiddleware(videoAbuseReportValidator),
30 asyncMiddleware(reportVideoAbuseRetryWrapper) 36 asyncRetryTransactionMiddleware(reportVideoAbuse)
31) 37)
32 38
33// --------------------------------------------------------------------------- 39// ---------------------------------------------------------------------------
@@ -44,17 +50,6 @@ async function listVideoAbuses (req: express.Request, res: express.Response, nex
44 return res.json(getFormattedObjects(resultList.data, resultList.total)) 50 return res.json(getFormattedObjects(resultList.data, resultList.total))
45} 51}
46 52
47async function reportVideoAbuseRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
48 const options = {
49 arguments: [ req, res ],
50 errorMessage: 'Cannot report abuse to the video with many retries.'
51 }
52
53 await retryTransactionWrapper(reportVideoAbuse, options)
54
55 return res.type('json').status(204).end()
56}
57
58async function reportVideoAbuse (req: express.Request, res: express.Response) { 53async function reportVideoAbuse (req: express.Request, res: express.Response) {
59 const videoInstance = res.locals.video as VideoModel 54 const videoInstance = res.locals.video as VideoModel
60 const reporterAccount = res.locals.oauth.token.User.Account as AccountModel 55 const reporterAccount = res.locals.oauth.token.User.Account as AccountModel
@@ -77,4 +72,6 @@ async function reportVideoAbuse (req: express.Request, res: express.Response) {
77 }) 72 })
78 73
79 logger.info('Abuse report for video %s created.', videoInstance.name) 74 logger.info('Abuse report for video %s created.', videoInstance.name)
75
76 return res.type('json').status(204).end()
80} 77}
diff --git a/server/controllers/api/videos/comment.ts b/server/controllers/api/videos/comment.ts
index f8a669e35..bbeb0d557 100644
--- a/server/controllers/api/videos/comment.ts
+++ b/server/controllers/api/videos/comment.ts
@@ -1,15 +1,24 @@
1import * as express from 'express' 1import * as express from 'express'
2import { ResultList } from '../../../../shared/models' 2import { ResultList } from '../../../../shared/models'
3import { VideoCommentCreate } from '../../../../shared/models/videos/video-comment.model' 3import { VideoCommentCreate } from '../../../../shared/models/videos/video-comment.model'
4import { retryTransactionWrapper } from '../../../helpers/database-utils'
5import { logger } from '../../../helpers/logger' 4import { logger } from '../../../helpers/logger'
6import { getFormattedObjects } from '../../../helpers/utils' 5import { getFormattedObjects } from '../../../helpers/utils'
7import { sequelizeTypescript } from '../../../initializers' 6import { sequelizeTypescript } from '../../../initializers'
8import { buildFormattedCommentTree, createVideoComment } from '../../../lib/video-comment' 7import { buildFormattedCommentTree, createVideoComment } from '../../../lib/video-comment'
9import { asyncMiddleware, authenticate, paginationValidator, setDefaultSort, setDefaultPagination } from '../../../middlewares' 8import {
9 asyncMiddleware,
10 asyncRetryTransactionMiddleware,
11 authenticate,
12 paginationValidator,
13 setDefaultPagination,
14 setDefaultSort
15} from '../../../middlewares'
10import { videoCommentThreadsSortValidator } from '../../../middlewares/validators' 16import { videoCommentThreadsSortValidator } from '../../../middlewares/validators'
11import { 17import {
12 addVideoCommentReplyValidator, addVideoCommentThreadValidator, listVideoCommentThreadsValidator, listVideoThreadCommentsValidator, 18 addVideoCommentReplyValidator,
19 addVideoCommentThreadValidator,
20 listVideoCommentThreadsValidator,
21 listVideoThreadCommentsValidator,
13 removeVideoCommentValidator 22 removeVideoCommentValidator
14} from '../../../middlewares/validators/video-comments' 23} from '../../../middlewares/validators/video-comments'
15import { VideoModel } from '../../../models/video/video' 24import { VideoModel } from '../../../models/video/video'
@@ -33,17 +42,17 @@ videoCommentRouter.get('/:videoId/comment-threads/:threadId',
33videoCommentRouter.post('/:videoId/comment-threads', 42videoCommentRouter.post('/:videoId/comment-threads',
34 authenticate, 43 authenticate,
35 asyncMiddleware(addVideoCommentThreadValidator), 44 asyncMiddleware(addVideoCommentThreadValidator),
36 asyncMiddleware(addVideoCommentThreadRetryWrapper) 45 asyncRetryTransactionMiddleware(addVideoCommentThread)
37) 46)
38videoCommentRouter.post('/:videoId/comments/:commentId', 47videoCommentRouter.post('/:videoId/comments/:commentId',
39 authenticate, 48 authenticate,
40 asyncMiddleware(addVideoCommentReplyValidator), 49 asyncMiddleware(addVideoCommentReplyValidator),
41 asyncMiddleware(addVideoCommentReplyRetryWrapper) 50 asyncRetryTransactionMiddleware(addVideoCommentReply)
42) 51)
43videoCommentRouter.delete('/:videoId/comments/:commentId', 52videoCommentRouter.delete('/:videoId/comments/:commentId',
44 authenticate, 53 authenticate,
45 asyncMiddleware(removeVideoCommentValidator), 54 asyncMiddleware(removeVideoCommentValidator),
46 asyncMiddleware(removeVideoCommentRetryWrapper) 55 asyncRetryTransactionMiddleware(removeVideoComment)
47) 56)
48 57
49// --------------------------------------------------------------------------- 58// ---------------------------------------------------------------------------
@@ -86,23 +95,10 @@ async function listVideoThreadComments (req: express.Request, res: express.Respo
86 return res.json(buildFormattedCommentTree(resultList)) 95 return res.json(buildFormattedCommentTree(resultList))
87} 96}
88 97
89async function addVideoCommentThreadRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) { 98async function addVideoCommentThread (req: express.Request, res: express.Response) {
90 const options = {
91 arguments: [ req, res ],
92 errorMessage: 'Cannot insert the video comment thread with many retries.'
93 }
94
95 const comment = await retryTransactionWrapper(addVideoCommentThread, options)
96
97 res.json({
98 comment: comment.toFormattedJSON()
99 }).end()
100}
101
102function addVideoCommentThread (req: express.Request, res: express.Response) {
103 const videoCommentInfo: VideoCommentCreate = req.body 99 const videoCommentInfo: VideoCommentCreate = req.body
104 100
105 return sequelizeTypescript.transaction(async t => { 101 const comment = await sequelizeTypescript.transaction(async t => {
106 return createVideoComment({ 102 return createVideoComment({
107 text: videoCommentInfo.text, 103 text: videoCommentInfo.text,
108 inReplyToComment: null, 104 inReplyToComment: null,
@@ -110,25 +106,16 @@ function addVideoCommentThread (req: express.Request, res: express.Response) {
110 account: res.locals.oauth.token.User.Account 106 account: res.locals.oauth.token.User.Account
111 }, t) 107 }, t)
112 }) 108 })
113}
114 109
115async function addVideoCommentReplyRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) { 110 return res.json({
116 const options = {
117 arguments: [ req, res ],
118 errorMessage: 'Cannot insert the video comment reply with many retries.'
119 }
120
121 const comment = await retryTransactionWrapper(addVideoCommentReply, options)
122
123 res.json({
124 comment: comment.toFormattedJSON() 111 comment: comment.toFormattedJSON()
125 }).end() 112 }).end()
126} 113}
127 114
128function addVideoCommentReply (req: express.Request, res: express.Response, next: express.NextFunction) { 115async function addVideoCommentReply (req: express.Request, res: express.Response) {
129 const videoCommentInfo: VideoCommentCreate = req.body 116 const videoCommentInfo: VideoCommentCreate = req.body
130 117
131 return sequelizeTypescript.transaction(async t => { 118 const comment = await sequelizeTypescript.transaction(async t => {
132 return createVideoComment({ 119 return createVideoComment({
133 text: videoCommentInfo.text, 120 text: videoCommentInfo.text,
134 inReplyToComment: res.locals.videoComment, 121 inReplyToComment: res.locals.videoComment,
@@ -136,17 +123,10 @@ function addVideoCommentReply (req: express.Request, res: express.Response, next
136 account: res.locals.oauth.token.User.Account 123 account: res.locals.oauth.token.User.Account
137 }, t) 124 }, t)
138 }) 125 })
139}
140
141async function removeVideoCommentRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
142 const options = {
143 arguments: [ req, res ],
144 errorMessage: 'Cannot remove the video comment with many retries.'
145 }
146 126
147 await retryTransactionWrapper(removeVideoComment, options) 127 return res.json({
148 128 comment: comment.toFormattedJSON()
149 return res.type('json').status(204).end() 129 }).end()
150} 130}
151 131
152async function removeVideoComment (req: express.Request, res: express.Response) { 132async function removeVideoComment (req: express.Request, res: express.Response) {
@@ -157,4 +137,6 @@ async function removeVideoComment (req: express.Request, res: express.Response)
157 }) 137 })
158 138
159 logger.info('Video comment %d deleted.', videoCommentInstance.id) 139 logger.info('Video comment %d deleted.', videoCommentInstance.id)
140
141 return res.type('json').status(204).end()
160} 142}
diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts
index 9d9b2b0e1..78963d89b 100644
--- a/server/controllers/api/videos/index.ts
+++ b/server/controllers/api/videos/index.ts
@@ -2,7 +2,6 @@ import * as express from 'express'
2import { extname, join } from 'path' 2import { extname, join } from 'path'
3import { VideoCreate, VideoPrivacy, VideoState, VideoUpdate } from '../../../../shared' 3import { VideoCreate, VideoPrivacy, VideoState, VideoUpdate } from '../../../../shared'
4import { renamePromise } from '../../../helpers/core-utils' 4import { renamePromise } from '../../../helpers/core-utils'
5import { retryTransactionWrapper } from '../../../helpers/database-utils'
6import { getVideoFileResolution } from '../../../helpers/ffmpeg-utils' 5import { getVideoFileResolution } from '../../../helpers/ffmpeg-utils'
7import { processImage } from '../../../helpers/image-utils' 6import { processImage } from '../../../helpers/image-utils'
8import { logger } from '../../../helpers/logger' 7import { logger } from '../../../helpers/logger'
@@ -30,6 +29,7 @@ import { JobQueue } from '../../../lib/job-queue'
30import { Redis } from '../../../lib/redis' 29import { Redis } from '../../../lib/redis'
31import { 30import {
32 asyncMiddleware, 31 asyncMiddleware,
32 asyncRetryTransactionMiddleware,
33 authenticate, 33 authenticate,
34 optionalAuthenticate, 34 optionalAuthenticate,
35 paginationValidator, 35 paginationValidator,
@@ -104,13 +104,13 @@ videosRouter.put('/:id',
104 authenticate, 104 authenticate,
105 reqVideoFileUpdate, 105 reqVideoFileUpdate,
106 asyncMiddleware(videosUpdateValidator), 106 asyncMiddleware(videosUpdateValidator),
107 asyncMiddleware(updateVideoRetryWrapper) 107 asyncRetryTransactionMiddleware(updateVideo)
108) 108)
109videosRouter.post('/upload', 109videosRouter.post('/upload',
110 authenticate, 110 authenticate,
111 reqVideoFileAdd, 111 reqVideoFileAdd,
112 asyncMiddleware(videosAddValidator), 112 asyncMiddleware(videosAddValidator),
113 asyncMiddleware(addVideoRetryWrapper) 113 asyncRetryTransactionMiddleware(addVideo)
114) 114)
115 115
116videosRouter.get('/:id/description', 116videosRouter.get('/:id/description',
@@ -129,7 +129,7 @@ videosRouter.post('/:id/views',
129videosRouter.delete('/:id', 129videosRouter.delete('/:id',
130 authenticate, 130 authenticate,
131 asyncMiddleware(videosRemoveValidator), 131 asyncMiddleware(videosRemoveValidator),
132 asyncMiddleware(removeVideoRetryWrapper) 132 asyncRetryTransactionMiddleware(removeVideo)
133) 133)
134 134
135// --------------------------------------------------------------------------- 135// ---------------------------------------------------------------------------
@@ -156,25 +156,8 @@ function listVideoPrivacies (req: express.Request, res: express.Response) {
156 res.json(VIDEO_PRIVACIES) 156 res.json(VIDEO_PRIVACIES)
157} 157}
158 158
159// Wrapper to video add that retry the function if there is a database error 159async function addVideo (req: express.Request, res: express.Response) {
160// We need this because we run the transaction in SERIALIZABLE isolation that can fail 160 const videoPhysicalFile = req.files['videofile'][0]
161async function addVideoRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
162 const options = {
163 arguments: [ req, res, req.files['videofile'][0] ],
164 errorMessage: 'Cannot insert the video with many retries.'
165 }
166
167 const video = await retryTransactionWrapper(addVideo, options)
168
169 res.json({
170 video: {
171 id: video.id,
172 uuid: video.uuid
173 }
174 }).end()
175}
176
177async function addVideo (req: express.Request, res: express.Response, videoPhysicalFile: Express.Multer.File) {
178 const videoInfo: VideoCreate = req.body 161 const videoInfo: VideoCreate = req.body
179 162
180 // Prepare data so we don't block the transaction 163 // Prepare data so we don't block the transaction
@@ -272,18 +255,12 @@ async function addVideo (req: express.Request, res: express.Response, videoPhysi
272 await JobQueue.Instance.createJob({ type: 'video-file', payload: dataInput }) 255 await JobQueue.Instance.createJob({ type: 'video-file', payload: dataInput })
273 } 256 }
274 257
275 return videoCreated 258 return res.json({
276} 259 video: {
277 260 id: videoCreated.id,
278async function updateVideoRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) { 261 uuid: videoCreated.uuid
279 const options = { 262 }
280 arguments: [ req, res ], 263 }).end()
281 errorMessage: 'Cannot update the video with many retries.'
282 }
283
284 await retryTransactionWrapper(updateVideo, options)
285
286 return res.type('json').status(204).end()
287} 264}
288 265
289async function updateVideo (req: express.Request, res: express.Response) { 266async function updateVideo (req: express.Request, res: express.Response) {
@@ -360,6 +337,8 @@ async function updateVideo (req: express.Request, res: express.Response) {
360 337
361 throw err 338 throw err
362 } 339 }
340
341 return res.type('json').status(204).end()
363} 342}
364 343
365function getVideo (req: express.Request, res: express.Response) { 344function getVideo (req: express.Request, res: express.Response) {
@@ -414,17 +393,6 @@ async function listVideos (req: express.Request, res: express.Response, next: ex
414 return res.json(getFormattedObjects(resultList.data, resultList.total)) 393 return res.json(getFormattedObjects(resultList.data, resultList.total))
415} 394}
416 395
417async function removeVideoRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
418 const options = {
419 arguments: [ req, res ],
420 errorMessage: 'Cannot remove the video with many retries.'
421 }
422
423 await retryTransactionWrapper(removeVideo, options)
424
425 return res.type('json').status(204).end()
426}
427
428async function removeVideo (req: express.Request, res: express.Response) { 396async function removeVideo (req: express.Request, res: express.Response) {
429 const videoInstance: VideoModel = res.locals.video 397 const videoInstance: VideoModel = res.locals.video
430 398
@@ -433,6 +401,8 @@ async function removeVideo (req: express.Request, res: express.Response) {
433 }) 401 })
434 402
435 logger.info('Video with name %s and uuid %s deleted.', videoInstance.name, videoInstance.uuid) 403 logger.info('Video with name %s and uuid %s deleted.', videoInstance.name, videoInstance.uuid)
404
405 return res.type('json').status(204).end()
436} 406}
437 407
438async function searchVideos (req: express.Request, res: express.Response, next: express.NextFunction) { 408async function searchVideos (req: express.Request, res: express.Response, next: express.NextFunction) {
diff --git a/server/controllers/api/videos/rate.ts b/server/controllers/api/videos/rate.ts
index 23e9de9f3..9d63b5821 100644
--- a/server/controllers/api/videos/rate.ts
+++ b/server/controllers/api/videos/rate.ts
@@ -1,10 +1,9 @@
1import * as express from 'express' 1import * as express from 'express'
2import { UserVideoRateUpdate } from '../../../../shared' 2import { UserVideoRateUpdate } from '../../../../shared'
3import { retryTransactionWrapper } from '../../../helpers/database-utils'
4import { logger } from '../../../helpers/logger' 3import { logger } from '../../../helpers/logger'
5import { sequelizeTypescript, VIDEO_RATE_TYPES } from '../../../initializers' 4import { sequelizeTypescript, VIDEO_RATE_TYPES } from '../../../initializers'
6import { sendVideoRateChange } from '../../../lib/activitypub' 5import { sendVideoRateChange } from '../../../lib/activitypub'
7import { asyncMiddleware, authenticate, videoRateValidator } from '../../../middlewares' 6import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate, videoRateValidator } from '../../../middlewares'
8import { AccountModel } from '../../../models/account/account' 7import { AccountModel } from '../../../models/account/account'
9import { AccountVideoRateModel } from '../../../models/account/account-video-rate' 8import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
10import { VideoModel } from '../../../models/video/video' 9import { VideoModel } from '../../../models/video/video'
@@ -14,7 +13,7 @@ const rateVideoRouter = express.Router()
14rateVideoRouter.put('/:id/rate', 13rateVideoRouter.put('/:id/rate',
15 authenticate, 14 authenticate,
16 asyncMiddleware(videoRateValidator), 15 asyncMiddleware(videoRateValidator),
17 asyncMiddleware(rateVideoRetryWrapper) 16 asyncRetryTransactionMiddleware(rateVideo)
18) 17)
19 18
20// --------------------------------------------------------------------------- 19// ---------------------------------------------------------------------------
@@ -25,17 +24,6 @@ export {
25 24
26// --------------------------------------------------------------------------- 25// ---------------------------------------------------------------------------
27 26
28async function rateVideoRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
29 const options = {
30 arguments: [ req, res ],
31 errorMessage: 'Cannot update the user video rate.'
32 }
33
34 await retryTransactionWrapper(rateVideo, options)
35
36 return res.type('json').status(204).end()
37}
38
39async function rateVideo (req: express.Request, res: express.Response) { 27async function rateVideo (req: express.Request, res: express.Response) {
40 const body: UserVideoRateUpdate = req.body 28 const body: UserVideoRateUpdate = req.body
41 const rateType = body.rating 29 const rateType = body.rating
@@ -87,4 +75,6 @@ async function rateVideo (req: express.Request, res: express.Response) {
87 }) 75 })
88 76
89 logger.info('Account video rate for video %s of account %s updated.', videoInstance.name, accountInstance.name) 77 logger.info('Account video rate for video %s of account %s updated.', videoInstance.name, accountInstance.name)
78
79 return res.type('json').status(204).end()
90} 80}