Refractor retry transaction function
This commit is contained in:
parent
3cd0734fd9
commit
90d4bb8125
19 changed files with 162 additions and 415 deletions
|
@ -4,7 +4,6 @@ import { extname, join } from 'path'
|
||||||
import * as uuidv4 from 'uuid/v4'
|
import * as uuidv4 from 'uuid/v4'
|
||||||
import * as RateLimit from 'express-rate-limit'
|
import * as RateLimit from 'express-rate-limit'
|
||||||
import { UserCreate, UserRight, UserRole, UserUpdate, UserUpdateMe, UserVideoRate as FormattedUserVideoRate } from '../../../shared'
|
import { UserCreate, UserRight, UserRole, UserUpdate, UserUpdateMe, UserVideoRate as FormattedUserVideoRate } from '../../../shared'
|
||||||
import { retryTransactionWrapper } from '../../helpers/database-utils'
|
|
||||||
import { processImage } from '../../helpers/image-utils'
|
import { processImage } from '../../helpers/image-utils'
|
||||||
import { logger } from '../../helpers/logger'
|
import { logger } from '../../helpers/logger'
|
||||||
import { getFormattedObjects } from '../../helpers/utils'
|
import { getFormattedObjects } from '../../helpers/utils'
|
||||||
|
@ -16,6 +15,7 @@ import { Redis } from '../../lib/redis'
|
||||||
import { createUserAccountAndChannel } from '../../lib/user'
|
import { createUserAccountAndChannel } from '../../lib/user'
|
||||||
import {
|
import {
|
||||||
asyncMiddleware,
|
asyncMiddleware,
|
||||||
|
asyncRetryTransactionMiddleware,
|
||||||
authenticate,
|
authenticate,
|
||||||
ensureUserHasRight,
|
ensureUserHasRight,
|
||||||
ensureUserRegistrationAllowed,
|
ensureUserRegistrationAllowed,
|
||||||
|
@ -102,14 +102,14 @@ usersRouter.post('/',
|
||||||
authenticate,
|
authenticate,
|
||||||
ensureUserHasRight(UserRight.MANAGE_USERS),
|
ensureUserHasRight(UserRight.MANAGE_USERS),
|
||||||
asyncMiddleware(usersAddValidator),
|
asyncMiddleware(usersAddValidator),
|
||||||
asyncMiddleware(createUserRetryWrapper)
|
asyncRetryTransactionMiddleware(createUser)
|
||||||
)
|
)
|
||||||
|
|
||||||
usersRouter.post('/register',
|
usersRouter.post('/register',
|
||||||
asyncMiddleware(ensureUserRegistrationAllowed),
|
asyncMiddleware(ensureUserRegistrationAllowed),
|
||||||
ensureUserRegistrationAllowedForIP,
|
ensureUserRegistrationAllowedForIP,
|
||||||
asyncMiddleware(usersRegisterValidator),
|
asyncMiddleware(usersRegisterValidator),
|
||||||
asyncMiddleware(registerUserRetryWrapper)
|
asyncRetryTransactionMiddleware(registerUser)
|
||||||
)
|
)
|
||||||
|
|
||||||
usersRouter.put('/me',
|
usersRouter.put('/me',
|
||||||
|
@ -178,26 +178,7 @@ async function getUserVideos (req: express.Request, res: express.Response, next:
|
||||||
return res.json(getFormattedObjects(resultList.data, resultList.total, { additionalAttributes }))
|
return res.json(getFormattedObjects(resultList.data, resultList.total, { additionalAttributes }))
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createUserRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
|
async function createUser (req: express.Request, res: express.Response) {
|
||||||
const options = {
|
|
||||||
arguments: [ req ],
|
|
||||||
errorMessage: 'Cannot insert the user with many retries.'
|
|
||||||
}
|
|
||||||
|
|
||||||
const { user, account } = await retryTransactionWrapper(createUser, options)
|
|
||||||
|
|
||||||
return res.json({
|
|
||||||
user: {
|
|
||||||
id: user.id,
|
|
||||||
account: {
|
|
||||||
id: account.id,
|
|
||||||
uuid: account.Actor.uuid
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).end()
|
|
||||||
}
|
|
||||||
|
|
||||||
async function createUser (req: express.Request) {
|
|
||||||
const body: UserCreate = req.body
|
const body: UserCreate = req.body
|
||||||
const userToCreate = new UserModel({
|
const userToCreate = new UserModel({
|
||||||
username: body.username,
|
username: body.username,
|
||||||
|
@ -213,21 +194,18 @@ async function createUser (req: express.Request) {
|
||||||
|
|
||||||
logger.info('User %s with its channel and account created.', body.username)
|
logger.info('User %s with its channel and account created.', body.username)
|
||||||
|
|
||||||
return { user, account }
|
return res.json({
|
||||||
}
|
user: {
|
||||||
|
id: user.id,
|
||||||
async function registerUserRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
|
account: {
|
||||||
const options = {
|
id: account.id,
|
||||||
arguments: [ req ],
|
uuid: account.Actor.uuid
|
||||||
errorMessage: 'Cannot insert the user with many retries.'
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
await retryTransactionWrapper(registerUser, options)
|
}).end()
|
||||||
|
|
||||||
return res.type('json').status(204).end()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function registerUser (req: express.Request) {
|
async function registerUser (req: express.Request, res: express.Response) {
|
||||||
const body: UserCreate = req.body
|
const body: UserCreate = req.body
|
||||||
|
|
||||||
const user = new UserModel({
|
const user = new UserModel({
|
||||||
|
@ -243,6 +221,8 @@ async function registerUser (req: express.Request) {
|
||||||
await createUserAccountAndChannel(user)
|
await createUserAccountAndChannel(user)
|
||||||
|
|
||||||
logger.info('User %s with its channel and account registered.', body.username)
|
logger.info('User %s with its channel and account registered.', body.username)
|
||||||
|
|
||||||
|
return res.type('json').status(204).end()
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getUserInformation (req: express.Request, res: express.Response, next: express.NextFunction) {
|
async function getUserInformation (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
|
|
|
@ -2,6 +2,7 @@ import * as express from 'express'
|
||||||
import { getFormattedObjects, resetSequelizeInstance } from '../../helpers/utils'
|
import { getFormattedObjects, resetSequelizeInstance } from '../../helpers/utils'
|
||||||
import {
|
import {
|
||||||
asyncMiddleware,
|
asyncMiddleware,
|
||||||
|
asyncRetryTransactionMiddleware,
|
||||||
authenticate,
|
authenticate,
|
||||||
optionalAuthenticate,
|
optionalAuthenticate,
|
||||||
paginationValidator,
|
paginationValidator,
|
||||||
|
@ -20,7 +21,6 @@ import { VideoChannelCreate, VideoChannelUpdate } from '../../../shared'
|
||||||
import { createVideoChannel } from '../../lib/video-channel'
|
import { createVideoChannel } from '../../lib/video-channel'
|
||||||
import { isNSFWHidden } from '../../helpers/express-utils'
|
import { isNSFWHidden } from '../../helpers/express-utils'
|
||||||
import { setAsyncActorKeys } from '../../lib/activitypub'
|
import { setAsyncActorKeys } from '../../lib/activitypub'
|
||||||
import { retryTransactionWrapper } from '../../helpers/database-utils'
|
|
||||||
import { AccountModel } from '../../models/account/account'
|
import { AccountModel } from '../../models/account/account'
|
||||||
import { sequelizeTypescript } from '../../initializers'
|
import { sequelizeTypescript } from '../../initializers'
|
||||||
import { logger } from '../../helpers/logger'
|
import { logger } from '../../helpers/logger'
|
||||||
|
@ -39,19 +39,19 @@ videoChannelRouter.get('/',
|
||||||
videoChannelRouter.post('/',
|
videoChannelRouter.post('/',
|
||||||
authenticate,
|
authenticate,
|
||||||
videoChannelsAddValidator,
|
videoChannelsAddValidator,
|
||||||
asyncMiddleware(addVideoChannelRetryWrapper)
|
asyncRetryTransactionMiddleware(addVideoChannel)
|
||||||
)
|
)
|
||||||
|
|
||||||
videoChannelRouter.put('/:id',
|
videoChannelRouter.put('/:id',
|
||||||
authenticate,
|
authenticate,
|
||||||
asyncMiddleware(videoChannelsUpdateValidator),
|
asyncMiddleware(videoChannelsUpdateValidator),
|
||||||
updateVideoChannelRetryWrapper
|
asyncRetryTransactionMiddleware(updateVideoChannel)
|
||||||
)
|
)
|
||||||
|
|
||||||
videoChannelRouter.delete('/:id',
|
videoChannelRouter.delete('/:id',
|
||||||
authenticate,
|
authenticate,
|
||||||
asyncMiddleware(videoChannelsRemoveValidator),
|
asyncMiddleware(videoChannelsRemoveValidator),
|
||||||
asyncMiddleware(removeVideoChannelRetryWrapper)
|
asyncRetryTransactionMiddleware(removeVideoChannel)
|
||||||
)
|
)
|
||||||
|
|
||||||
videoChannelRouter.get('/:id',
|
videoChannelRouter.get('/:id',
|
||||||
|
@ -83,23 +83,6 @@ async function listVideoChannels (req: express.Request, res: express.Response, n
|
||||||
return res.json(getFormattedObjects(resultList.data, resultList.total))
|
return res.json(getFormattedObjects(resultList.data, resultList.total))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrapper to video channel add that retry the async function if there is a database error
|
|
||||||
// We need this because we run the transaction in SERIALIZABLE isolation that can fail
|
|
||||||
async function addVideoChannelRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
|
|
||||||
const options = {
|
|
||||||
arguments: [ req, res ],
|
|
||||||
errorMessage: 'Cannot insert the video video channel with many retries.'
|
|
||||||
}
|
|
||||||
|
|
||||||
const videoChannel = await retryTransactionWrapper(addVideoChannel, options)
|
|
||||||
return res.json({
|
|
||||||
videoChannel: {
|
|
||||||
id: videoChannel.id,
|
|
||||||
uuid: videoChannel.Actor.uuid
|
|
||||||
}
|
|
||||||
}).end()
|
|
||||||
}
|
|
||||||
|
|
||||||
async function addVideoChannel (req: express.Request, res: express.Response) {
|
async function addVideoChannel (req: express.Request, res: express.Response) {
|
||||||
const videoChannelInfo: VideoChannelCreate = req.body
|
const videoChannelInfo: VideoChannelCreate = req.body
|
||||||
const account: AccountModel = res.locals.oauth.token.User.Account
|
const account: AccountModel = res.locals.oauth.token.User.Account
|
||||||
|
@ -113,18 +96,12 @@ async function addVideoChannel (req: express.Request, res: express.Response) {
|
||||||
|
|
||||||
logger.info('Video channel with uuid %s created.', videoChannelCreated.Actor.uuid)
|
logger.info('Video channel with uuid %s created.', videoChannelCreated.Actor.uuid)
|
||||||
|
|
||||||
return videoChannelCreated
|
return res.json({
|
||||||
}
|
videoChannel: {
|
||||||
|
id: videoChannelCreated.id,
|
||||||
async function updateVideoChannelRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
|
uuid: videoChannelCreated.Actor.uuid
|
||||||
const options = {
|
|
||||||
arguments: [ req, res ],
|
|
||||||
errorMessage: 'Cannot update the video with many retries.'
|
|
||||||
}
|
}
|
||||||
|
}).end()
|
||||||
await retryTransactionWrapper(updateVideoChannel, options)
|
|
||||||
|
|
||||||
return res.type('json').status(204).end()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateVideoChannel (req: express.Request, res: express.Response) {
|
async function updateVideoChannel (req: express.Request, res: express.Response) {
|
||||||
|
@ -157,15 +134,6 @@ async function updateVideoChannel (req: express.Request, res: express.Response)
|
||||||
|
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
async function removeVideoChannelRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
|
|
||||||
const options = {
|
|
||||||
arguments: [ req, res ],
|
|
||||||
errorMessage: 'Cannot remove the video channel with many retries.'
|
|
||||||
}
|
|
||||||
|
|
||||||
await retryTransactionWrapper(removeVideoChannel, options)
|
|
||||||
|
|
||||||
return res.type('json').status(204).end()
|
return res.type('json').status(204).end()
|
||||||
}
|
}
|
||||||
|
@ -173,12 +141,13 @@ async function removeVideoChannelRetryWrapper (req: express.Request, res: expres
|
||||||
async function removeVideoChannel (req: express.Request, res: express.Response) {
|
async function removeVideoChannel (req: express.Request, res: express.Response) {
|
||||||
const videoChannelInstance: VideoChannelModel = res.locals.videoChannel
|
const videoChannelInstance: VideoChannelModel = res.locals.videoChannel
|
||||||
|
|
||||||
return sequelizeTypescript.transaction(async t => {
|
await sequelizeTypescript.transaction(async t => {
|
||||||
await videoChannelInstance.destroy({ transaction: t })
|
await videoChannelInstance.destroy({ transaction: t })
|
||||||
|
|
||||||
logger.info('Video channel with name %s and uuid %s deleted.', videoChannelInstance.name, videoChannelInstance.Actor.uuid)
|
logger.info('Video channel with name %s and uuid %s deleted.', videoChannelInstance.name, videoChannelInstance.Actor.uuid)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
return res.type('json').status(204).end()
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getVideoChannel (req: express.Request, res: express.Response, next: express.NextFunction) {
|
async function getVideoChannel (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
|
|
|
@ -1,12 +1,18 @@
|
||||||
import * as express from 'express'
|
import * as express from 'express'
|
||||||
import { UserRight, VideoAbuseCreate } from '../../../../shared'
|
import { UserRight, VideoAbuseCreate } from '../../../../shared'
|
||||||
import { retryTransactionWrapper } from '../../../helpers/database-utils'
|
|
||||||
import { logger } from '../../../helpers/logger'
|
import { logger } from '../../../helpers/logger'
|
||||||
import { getFormattedObjects } from '../../../helpers/utils'
|
import { getFormattedObjects } from '../../../helpers/utils'
|
||||||
import { sequelizeTypescript } from '../../../initializers'
|
import { sequelizeTypescript } from '../../../initializers'
|
||||||
import { sendVideoAbuse } from '../../../lib/activitypub/send'
|
import { sendVideoAbuse } from '../../../lib/activitypub/send'
|
||||||
import {
|
import {
|
||||||
asyncMiddleware, authenticate, ensureUserHasRight, paginationValidator, setDefaultSort, setDefaultPagination, videoAbuseReportValidator,
|
asyncMiddleware,
|
||||||
|
asyncRetryTransactionMiddleware,
|
||||||
|
authenticate,
|
||||||
|
ensureUserHasRight,
|
||||||
|
paginationValidator,
|
||||||
|
setDefaultPagination,
|
||||||
|
setDefaultSort,
|
||||||
|
videoAbuseReportValidator,
|
||||||
videoAbusesSortValidator
|
videoAbusesSortValidator
|
||||||
} from '../../../middlewares'
|
} from '../../../middlewares'
|
||||||
import { AccountModel } from '../../../models/account/account'
|
import { AccountModel } from '../../../models/account/account'
|
||||||
|
@ -27,7 +33,7 @@ abuseVideoRouter.get('/abuse',
|
||||||
abuseVideoRouter.post('/:id/abuse',
|
abuseVideoRouter.post('/:id/abuse',
|
||||||
authenticate,
|
authenticate,
|
||||||
asyncMiddleware(videoAbuseReportValidator),
|
asyncMiddleware(videoAbuseReportValidator),
|
||||||
asyncMiddleware(reportVideoAbuseRetryWrapper)
|
asyncRetryTransactionMiddleware(reportVideoAbuse)
|
||||||
)
|
)
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -44,17 +50,6 @@ async function listVideoAbuses (req: express.Request, res: express.Response, nex
|
||||||
return res.json(getFormattedObjects(resultList.data, resultList.total))
|
return res.json(getFormattedObjects(resultList.data, resultList.total))
|
||||||
}
|
}
|
||||||
|
|
||||||
async function reportVideoAbuseRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
|
|
||||||
const options = {
|
|
||||||
arguments: [ req, res ],
|
|
||||||
errorMessage: 'Cannot report abuse to the video with many retries.'
|
|
||||||
}
|
|
||||||
|
|
||||||
await retryTransactionWrapper(reportVideoAbuse, options)
|
|
||||||
|
|
||||||
return res.type('json').status(204).end()
|
|
||||||
}
|
|
||||||
|
|
||||||
async function reportVideoAbuse (req: express.Request, res: express.Response) {
|
async function reportVideoAbuse (req: express.Request, res: express.Response) {
|
||||||
const videoInstance = res.locals.video as VideoModel
|
const videoInstance = res.locals.video as VideoModel
|
||||||
const reporterAccount = res.locals.oauth.token.User.Account as AccountModel
|
const reporterAccount = res.locals.oauth.token.User.Account as AccountModel
|
||||||
|
@ -77,4 +72,6 @@ async function reportVideoAbuse (req: express.Request, res: express.Response) {
|
||||||
})
|
})
|
||||||
|
|
||||||
logger.info('Abuse report for video %s created.', videoInstance.name)
|
logger.info('Abuse report for video %s created.', videoInstance.name)
|
||||||
|
|
||||||
|
return res.type('json').status(204).end()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,24 @@
|
||||||
import * as express from 'express'
|
import * as express from 'express'
|
||||||
import { ResultList } from '../../../../shared/models'
|
import { ResultList } from '../../../../shared/models'
|
||||||
import { VideoCommentCreate } from '../../../../shared/models/videos/video-comment.model'
|
import { VideoCommentCreate } from '../../../../shared/models/videos/video-comment.model'
|
||||||
import { retryTransactionWrapper } from '../../../helpers/database-utils'
|
|
||||||
import { logger } from '../../../helpers/logger'
|
import { logger } from '../../../helpers/logger'
|
||||||
import { getFormattedObjects } from '../../../helpers/utils'
|
import { getFormattedObjects } from '../../../helpers/utils'
|
||||||
import { sequelizeTypescript } from '../../../initializers'
|
import { sequelizeTypescript } from '../../../initializers'
|
||||||
import { buildFormattedCommentTree, createVideoComment } from '../../../lib/video-comment'
|
import { buildFormattedCommentTree, createVideoComment } from '../../../lib/video-comment'
|
||||||
import { asyncMiddleware, authenticate, paginationValidator, setDefaultSort, setDefaultPagination } from '../../../middlewares'
|
import {
|
||||||
|
asyncMiddleware,
|
||||||
|
asyncRetryTransactionMiddleware,
|
||||||
|
authenticate,
|
||||||
|
paginationValidator,
|
||||||
|
setDefaultPagination,
|
||||||
|
setDefaultSort
|
||||||
|
} from '../../../middlewares'
|
||||||
import { videoCommentThreadsSortValidator } from '../../../middlewares/validators'
|
import { videoCommentThreadsSortValidator } from '../../../middlewares/validators'
|
||||||
import {
|
import {
|
||||||
addVideoCommentReplyValidator, addVideoCommentThreadValidator, listVideoCommentThreadsValidator, listVideoThreadCommentsValidator,
|
addVideoCommentReplyValidator,
|
||||||
|
addVideoCommentThreadValidator,
|
||||||
|
listVideoCommentThreadsValidator,
|
||||||
|
listVideoThreadCommentsValidator,
|
||||||
removeVideoCommentValidator
|
removeVideoCommentValidator
|
||||||
} from '../../../middlewares/validators/video-comments'
|
} from '../../../middlewares/validators/video-comments'
|
||||||
import { VideoModel } from '../../../models/video/video'
|
import { VideoModel } from '../../../models/video/video'
|
||||||
|
@ -33,17 +42,17 @@ videoCommentRouter.get('/:videoId/comment-threads/:threadId',
|
||||||
videoCommentRouter.post('/:videoId/comment-threads',
|
videoCommentRouter.post('/:videoId/comment-threads',
|
||||||
authenticate,
|
authenticate,
|
||||||
asyncMiddleware(addVideoCommentThreadValidator),
|
asyncMiddleware(addVideoCommentThreadValidator),
|
||||||
asyncMiddleware(addVideoCommentThreadRetryWrapper)
|
asyncRetryTransactionMiddleware(addVideoCommentThread)
|
||||||
)
|
)
|
||||||
videoCommentRouter.post('/:videoId/comments/:commentId',
|
videoCommentRouter.post('/:videoId/comments/:commentId',
|
||||||
authenticate,
|
authenticate,
|
||||||
asyncMiddleware(addVideoCommentReplyValidator),
|
asyncMiddleware(addVideoCommentReplyValidator),
|
||||||
asyncMiddleware(addVideoCommentReplyRetryWrapper)
|
asyncRetryTransactionMiddleware(addVideoCommentReply)
|
||||||
)
|
)
|
||||||
videoCommentRouter.delete('/:videoId/comments/:commentId',
|
videoCommentRouter.delete('/:videoId/comments/:commentId',
|
||||||
authenticate,
|
authenticate,
|
||||||
asyncMiddleware(removeVideoCommentValidator),
|
asyncMiddleware(removeVideoCommentValidator),
|
||||||
asyncMiddleware(removeVideoCommentRetryWrapper)
|
asyncRetryTransactionMiddleware(removeVideoComment)
|
||||||
)
|
)
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -86,23 +95,10 @@ async function listVideoThreadComments (req: express.Request, res: express.Respo
|
||||||
return res.json(buildFormattedCommentTree(resultList))
|
return res.json(buildFormattedCommentTree(resultList))
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addVideoCommentThreadRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
|
async function addVideoCommentThread (req: express.Request, res: express.Response) {
|
||||||
const options = {
|
|
||||||
arguments: [ req, res ],
|
|
||||||
errorMessage: 'Cannot insert the video comment thread with many retries.'
|
|
||||||
}
|
|
||||||
|
|
||||||
const comment = await retryTransactionWrapper(addVideoCommentThread, options)
|
|
||||||
|
|
||||||
res.json({
|
|
||||||
comment: comment.toFormattedJSON()
|
|
||||||
}).end()
|
|
||||||
}
|
|
||||||
|
|
||||||
function addVideoCommentThread (req: express.Request, res: express.Response) {
|
|
||||||
const videoCommentInfo: VideoCommentCreate = req.body
|
const videoCommentInfo: VideoCommentCreate = req.body
|
||||||
|
|
||||||
return sequelizeTypescript.transaction(async t => {
|
const comment = await sequelizeTypescript.transaction(async t => {
|
||||||
return createVideoComment({
|
return createVideoComment({
|
||||||
text: videoCommentInfo.text,
|
text: videoCommentInfo.text,
|
||||||
inReplyToComment: null,
|
inReplyToComment: null,
|
||||||
|
@ -110,25 +106,16 @@ function addVideoCommentThread (req: express.Request, res: express.Response) {
|
||||||
account: res.locals.oauth.token.User.Account
|
account: res.locals.oauth.token.User.Account
|
||||||
}, t)
|
}, t)
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
async function addVideoCommentReplyRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
|
return res.json({
|
||||||
const options = {
|
|
||||||
arguments: [ req, res ],
|
|
||||||
errorMessage: 'Cannot insert the video comment reply with many retries.'
|
|
||||||
}
|
|
||||||
|
|
||||||
const comment = await retryTransactionWrapper(addVideoCommentReply, options)
|
|
||||||
|
|
||||||
res.json({
|
|
||||||
comment: comment.toFormattedJSON()
|
comment: comment.toFormattedJSON()
|
||||||
}).end()
|
}).end()
|
||||||
}
|
}
|
||||||
|
|
||||||
function addVideoCommentReply (req: express.Request, res: express.Response, next: express.NextFunction) {
|
async function addVideoCommentReply (req: express.Request, res: express.Response) {
|
||||||
const videoCommentInfo: VideoCommentCreate = req.body
|
const videoCommentInfo: VideoCommentCreate = req.body
|
||||||
|
|
||||||
return sequelizeTypescript.transaction(async t => {
|
const comment = await sequelizeTypescript.transaction(async t => {
|
||||||
return createVideoComment({
|
return createVideoComment({
|
||||||
text: videoCommentInfo.text,
|
text: videoCommentInfo.text,
|
||||||
inReplyToComment: res.locals.videoComment,
|
inReplyToComment: res.locals.videoComment,
|
||||||
|
@ -136,17 +123,10 @@ function addVideoCommentReply (req: express.Request, res: express.Response, next
|
||||||
account: res.locals.oauth.token.User.Account
|
account: res.locals.oauth.token.User.Account
|
||||||
}, t)
|
}, t)
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
async function removeVideoCommentRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
|
return res.json({
|
||||||
const options = {
|
comment: comment.toFormattedJSON()
|
||||||
arguments: [ req, res ],
|
}).end()
|
||||||
errorMessage: 'Cannot remove the video comment with many retries.'
|
|
||||||
}
|
|
||||||
|
|
||||||
await retryTransactionWrapper(removeVideoComment, options)
|
|
||||||
|
|
||||||
return res.type('json').status(204).end()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function removeVideoComment (req: express.Request, res: express.Response) {
|
async function removeVideoComment (req: express.Request, res: express.Response) {
|
||||||
|
@ -157,4 +137,6 @@ async function removeVideoComment (req: express.Request, res: express.Response)
|
||||||
})
|
})
|
||||||
|
|
||||||
logger.info('Video comment %d deleted.', videoCommentInstance.id)
|
logger.info('Video comment %d deleted.', videoCommentInstance.id)
|
||||||
|
|
||||||
|
return res.type('json').status(204).end()
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ import * as express from 'express'
|
||||||
import { extname, join } from 'path'
|
import { extname, join } from 'path'
|
||||||
import { VideoCreate, VideoPrivacy, VideoState, VideoUpdate } from '../../../../shared'
|
import { VideoCreate, VideoPrivacy, VideoState, VideoUpdate } from '../../../../shared'
|
||||||
import { renamePromise } from '../../../helpers/core-utils'
|
import { renamePromise } from '../../../helpers/core-utils'
|
||||||
import { retryTransactionWrapper } from '../../../helpers/database-utils'
|
|
||||||
import { getVideoFileResolution } from '../../../helpers/ffmpeg-utils'
|
import { getVideoFileResolution } from '../../../helpers/ffmpeg-utils'
|
||||||
import { processImage } from '../../../helpers/image-utils'
|
import { processImage } from '../../../helpers/image-utils'
|
||||||
import { logger } from '../../../helpers/logger'
|
import { logger } from '../../../helpers/logger'
|
||||||
|
@ -30,6 +29,7 @@ import { JobQueue } from '../../../lib/job-queue'
|
||||||
import { Redis } from '../../../lib/redis'
|
import { Redis } from '../../../lib/redis'
|
||||||
import {
|
import {
|
||||||
asyncMiddleware,
|
asyncMiddleware,
|
||||||
|
asyncRetryTransactionMiddleware,
|
||||||
authenticate,
|
authenticate,
|
||||||
optionalAuthenticate,
|
optionalAuthenticate,
|
||||||
paginationValidator,
|
paginationValidator,
|
||||||
|
@ -104,13 +104,13 @@ videosRouter.put('/:id',
|
||||||
authenticate,
|
authenticate,
|
||||||
reqVideoFileUpdate,
|
reqVideoFileUpdate,
|
||||||
asyncMiddleware(videosUpdateValidator),
|
asyncMiddleware(videosUpdateValidator),
|
||||||
asyncMiddleware(updateVideoRetryWrapper)
|
asyncRetryTransactionMiddleware(updateVideo)
|
||||||
)
|
)
|
||||||
videosRouter.post('/upload',
|
videosRouter.post('/upload',
|
||||||
authenticate,
|
authenticate,
|
||||||
reqVideoFileAdd,
|
reqVideoFileAdd,
|
||||||
asyncMiddleware(videosAddValidator),
|
asyncMiddleware(videosAddValidator),
|
||||||
asyncMiddleware(addVideoRetryWrapper)
|
asyncRetryTransactionMiddleware(addVideo)
|
||||||
)
|
)
|
||||||
|
|
||||||
videosRouter.get('/:id/description',
|
videosRouter.get('/:id/description',
|
||||||
|
@ -129,7 +129,7 @@ videosRouter.post('/:id/views',
|
||||||
videosRouter.delete('/:id',
|
videosRouter.delete('/:id',
|
||||||
authenticate,
|
authenticate,
|
||||||
asyncMiddleware(videosRemoveValidator),
|
asyncMiddleware(videosRemoveValidator),
|
||||||
asyncMiddleware(removeVideoRetryWrapper)
|
asyncRetryTransactionMiddleware(removeVideo)
|
||||||
)
|
)
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -156,25 +156,8 @@ function listVideoPrivacies (req: express.Request, res: express.Response) {
|
||||||
res.json(VIDEO_PRIVACIES)
|
res.json(VIDEO_PRIVACIES)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrapper to video add that retry the function if there is a database error
|
async function addVideo (req: express.Request, res: express.Response) {
|
||||||
// We need this because we run the transaction in SERIALIZABLE isolation that can fail
|
const videoPhysicalFile = req.files['videofile'][0]
|
||||||
async function addVideoRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
|
|
||||||
const options = {
|
|
||||||
arguments: [ req, res, req.files['videofile'][0] ],
|
|
||||||
errorMessage: 'Cannot insert the video with many retries.'
|
|
||||||
}
|
|
||||||
|
|
||||||
const video = await retryTransactionWrapper(addVideo, options)
|
|
||||||
|
|
||||||
res.json({
|
|
||||||
video: {
|
|
||||||
id: video.id,
|
|
||||||
uuid: video.uuid
|
|
||||||
}
|
|
||||||
}).end()
|
|
||||||
}
|
|
||||||
|
|
||||||
async function addVideo (req: express.Request, res: express.Response, videoPhysicalFile: Express.Multer.File) {
|
|
||||||
const videoInfo: VideoCreate = req.body
|
const videoInfo: VideoCreate = req.body
|
||||||
|
|
||||||
// Prepare data so we don't block the transaction
|
// Prepare data so we don't block the transaction
|
||||||
|
@ -272,18 +255,12 @@ async function addVideo (req: express.Request, res: express.Response, videoPhysi
|
||||||
await JobQueue.Instance.createJob({ type: 'video-file', payload: dataInput })
|
await JobQueue.Instance.createJob({ type: 'video-file', payload: dataInput })
|
||||||
}
|
}
|
||||||
|
|
||||||
return videoCreated
|
return res.json({
|
||||||
}
|
video: {
|
||||||
|
id: videoCreated.id,
|
||||||
async function updateVideoRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
|
uuid: videoCreated.uuid
|
||||||
const options = {
|
|
||||||
arguments: [ req, res ],
|
|
||||||
errorMessage: 'Cannot update the video with many retries.'
|
|
||||||
}
|
}
|
||||||
|
}).end()
|
||||||
await retryTransactionWrapper(updateVideo, options)
|
|
||||||
|
|
||||||
return res.type('json').status(204).end()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateVideo (req: express.Request, res: express.Response) {
|
async function updateVideo (req: express.Request, res: express.Response) {
|
||||||
|
@ -360,6 +337,8 @@ async function updateVideo (req: express.Request, res: express.Response) {
|
||||||
|
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return res.type('json').status(204).end()
|
||||||
}
|
}
|
||||||
|
|
||||||
function getVideo (req: express.Request, res: express.Response) {
|
function getVideo (req: express.Request, res: express.Response) {
|
||||||
|
@ -414,17 +393,6 @@ async function listVideos (req: express.Request, res: express.Response, next: ex
|
||||||
return res.json(getFormattedObjects(resultList.data, resultList.total))
|
return res.json(getFormattedObjects(resultList.data, resultList.total))
|
||||||
}
|
}
|
||||||
|
|
||||||
async function removeVideoRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
|
|
||||||
const options = {
|
|
||||||
arguments: [ req, res ],
|
|
||||||
errorMessage: 'Cannot remove the video with many retries.'
|
|
||||||
}
|
|
||||||
|
|
||||||
await retryTransactionWrapper(removeVideo, options)
|
|
||||||
|
|
||||||
return res.type('json').status(204).end()
|
|
||||||
}
|
|
||||||
|
|
||||||
async function removeVideo (req: express.Request, res: express.Response) {
|
async function removeVideo (req: express.Request, res: express.Response) {
|
||||||
const videoInstance: VideoModel = res.locals.video
|
const videoInstance: VideoModel = res.locals.video
|
||||||
|
|
||||||
|
@ -433,6 +401,8 @@ async function removeVideo (req: express.Request, res: express.Response) {
|
||||||
})
|
})
|
||||||
|
|
||||||
logger.info('Video with name %s and uuid %s deleted.', videoInstance.name, videoInstance.uuid)
|
logger.info('Video with name %s and uuid %s deleted.', videoInstance.name, videoInstance.uuid)
|
||||||
|
|
||||||
|
return res.type('json').status(204).end()
|
||||||
}
|
}
|
||||||
|
|
||||||
async function searchVideos (req: express.Request, res: express.Response, next: express.NextFunction) {
|
async function searchVideos (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import * as express from 'express'
|
import * as express from 'express'
|
||||||
import { UserVideoRateUpdate } from '../../../../shared'
|
import { UserVideoRateUpdate } from '../../../../shared'
|
||||||
import { retryTransactionWrapper } from '../../../helpers/database-utils'
|
|
||||||
import { logger } from '../../../helpers/logger'
|
import { logger } from '../../../helpers/logger'
|
||||||
import { sequelizeTypescript, VIDEO_RATE_TYPES } from '../../../initializers'
|
import { sequelizeTypescript, VIDEO_RATE_TYPES } from '../../../initializers'
|
||||||
import { sendVideoRateChange } from '../../../lib/activitypub'
|
import { sendVideoRateChange } from '../../../lib/activitypub'
|
||||||
import { asyncMiddleware, authenticate, videoRateValidator } from '../../../middlewares'
|
import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate, videoRateValidator } from '../../../middlewares'
|
||||||
import { AccountModel } from '../../../models/account/account'
|
import { AccountModel } from '../../../models/account/account'
|
||||||
import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
|
import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
|
||||||
import { VideoModel } from '../../../models/video/video'
|
import { VideoModel } from '../../../models/video/video'
|
||||||
|
@ -14,7 +13,7 @@ const rateVideoRouter = express.Router()
|
||||||
rateVideoRouter.put('/:id/rate',
|
rateVideoRouter.put('/:id/rate',
|
||||||
authenticate,
|
authenticate,
|
||||||
asyncMiddleware(videoRateValidator),
|
asyncMiddleware(videoRateValidator),
|
||||||
asyncMiddleware(rateVideoRetryWrapper)
|
asyncRetryTransactionMiddleware(rateVideo)
|
||||||
)
|
)
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -25,17 +24,6 @@ export {
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
async function rateVideoRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
|
|
||||||
const options = {
|
|
||||||
arguments: [ req, res ],
|
|
||||||
errorMessage: 'Cannot update the user video rate.'
|
|
||||||
}
|
|
||||||
|
|
||||||
await retryTransactionWrapper(rateVideo, options)
|
|
||||||
|
|
||||||
return res.type('json').status(204).end()
|
|
||||||
}
|
|
||||||
|
|
||||||
async function rateVideo (req: express.Request, res: express.Response) {
|
async function rateVideo (req: express.Request, res: express.Response) {
|
||||||
const body: UserVideoRateUpdate = req.body
|
const body: UserVideoRateUpdate = req.body
|
||||||
const rateType = body.rating
|
const rateType = body.rating
|
||||||
|
@ -87,4 +75,6 @@ async function rateVideo (req: express.Request, res: express.Response) {
|
||||||
})
|
})
|
||||||
|
|
||||||
logger.info('Account video rate for video %s of account %s updated.', videoInstance.name, accountInstance.name)
|
logger.info('Account video rate for video %s of account %s updated.', videoInstance.name, accountInstance.name)
|
||||||
|
|
||||||
|
return res.type('json').status(204).end()
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,27 +3,43 @@ import * as Bluebird from 'bluebird'
|
||||||
import { Model } from 'sequelize-typescript'
|
import { Model } from 'sequelize-typescript'
|
||||||
import { logger } from './logger'
|
import { logger } from './logger'
|
||||||
|
|
||||||
type RetryTransactionWrapperOptions = { errorMessage: string, arguments?: any[] }
|
function retryTransactionWrapper <T, A, B, C> (
|
||||||
function retryTransactionWrapper <T> (
|
functionToRetry: (arg1: A, arg2: B, arg3: C) => Promise<T> | Bluebird<T>,
|
||||||
functionToRetry: (...args) => Promise<T> | Bluebird<T>,
|
arg1: A,
|
||||||
options: RetryTransactionWrapperOptions
|
arg2: B,
|
||||||
): Promise<T> {
|
arg3: C
|
||||||
const args = options.arguments ? options.arguments : []
|
): Promise<T>
|
||||||
|
|
||||||
|
function retryTransactionWrapper <T, A, B> (
|
||||||
|
functionToRetry: (arg1: A, arg2: B) => Promise<T> | Bluebird<T>,
|
||||||
|
arg1: A,
|
||||||
|
arg2: B
|
||||||
|
): Promise<T>
|
||||||
|
|
||||||
|
function retryTransactionWrapper <T, A> (
|
||||||
|
functionToRetry: (arg1: A) => Promise<T> | Bluebird<T>,
|
||||||
|
arg1: A
|
||||||
|
): Promise<T>
|
||||||
|
|
||||||
|
function retryTransactionWrapper <T> (
|
||||||
|
functionToRetry: (...args: any[]) => Promise<T> | Bluebird<T>,
|
||||||
|
...args: any[]
|
||||||
|
): Promise<T> {
|
||||||
return transactionRetryer<T>(callback => {
|
return transactionRetryer<T>(callback => {
|
||||||
functionToRetry.apply(this, args)
|
functionToRetry.apply(this, args)
|
||||||
.then((result: T) => callback(null, result))
|
.then((result: T) => callback(null, result))
|
||||||
.catch(err => callback(err))
|
.catch(err => callback(err))
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
logger.error(options.errorMessage, { err })
|
logger.error('Cannot execute %s with many retries.', functionToRetry.toString(), { err })
|
||||||
throw err
|
throw err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function transactionRetryer <T> (func: (err: any, data: T) => any) {
|
function transactionRetryer <T> (func: (err: any, data: T) => any) {
|
||||||
return new Promise<T>((res, rej) => {
|
return new Promise<T>((res, rej) => {
|
||||||
retry({
|
retry(
|
||||||
|
{
|
||||||
times: 5,
|
times: 5,
|
||||||
|
|
||||||
errorFilter: err => {
|
errorFilter: err => {
|
||||||
|
@ -31,7 +47,10 @@ function transactionRetryer <T> (func: (err: any, data: T) => any) {
|
||||||
logger.debug('Maybe retrying the transaction function.', { willRetry, err })
|
logger.debug('Maybe retrying the transaction function.', { willRetry, err })
|
||||||
return willRetry
|
return willRetry
|
||||||
}
|
}
|
||||||
}, func, (err, data) => err ? rej(err) : res(data))
|
},
|
||||||
|
func,
|
||||||
|
(err, data) => err ? rej(err) : res(data)
|
||||||
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,18 +62,10 @@ async function getOrCreateActorAndServerAndModel (activityActor: string | Activi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const options = {
|
actor = await retryTransactionWrapper(saveActorAndServerAndModelIfNotExist, result, ownerActor)
|
||||||
arguments: [ result, ownerActor ],
|
|
||||||
errorMessage: 'Cannot save actor and server with many retries.'
|
|
||||||
}
|
|
||||||
actor = await retryTransactionWrapper(saveActorAndServerAndModelIfNotExist, options)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const options = {
|
return retryTransactionWrapper(refreshActorIfNeeded, actor)
|
||||||
arguments: [ actor ],
|
|
||||||
errorMessage: 'Cannot refresh actor if needed with many retries.'
|
|
||||||
}
|
|
||||||
return retryTransactionWrapper(refreshActorIfNeeded, options)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildActorInstance (type: ActivityPubActorType, url: string, preferredUsername: string, uuid?: string) {
|
function buildActorInstance (type: ActivityPubActorType, url: string, preferredUsername: string, uuid?: string) {
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { getOrCreateAccountAndVideoAndChannel } from '../videos'
|
||||||
async function processAnnounceActivity (activity: ActivityAnnounce) {
|
async function processAnnounceActivity (activity: ActivityAnnounce) {
|
||||||
const actorAnnouncer = await getOrCreateActorAndServerAndModel(activity.actor)
|
const actorAnnouncer = await getOrCreateActorAndServerAndModel(activity.actor)
|
||||||
|
|
||||||
return processVideoShare(actorAnnouncer, activity)
|
return retryTransactionWrapper(processVideoShare, actorAnnouncer, activity)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -22,16 +22,7 @@ export {
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
function processVideoShare (actorAnnouncer: ActorModel, activity: ActivityAnnounce) {
|
async function processVideoShare (actorAnnouncer: ActorModel, activity: ActivityAnnounce) {
|
||||||
const options = {
|
|
||||||
arguments: [ actorAnnouncer, activity ],
|
|
||||||
errorMessage: 'Cannot share the video activity with many retries.'
|
|
||||||
}
|
|
||||||
|
|
||||||
return retryTransactionWrapper(shareVideo, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function shareVideo (actorAnnouncer: ActorModel, activity: ActivityAnnounce) {
|
|
||||||
const objectUri = typeof activity.object === 'string' ? activity.object : activity.object.id
|
const objectUri = typeof activity.object === 'string' ? activity.object : activity.object.id
|
||||||
let video: VideoModel
|
let video: VideoModel
|
||||||
|
|
||||||
|
|
|
@ -21,13 +21,13 @@ async function processCreateActivity (activity: ActivityCreate) {
|
||||||
if (activityType === 'View') {
|
if (activityType === 'View') {
|
||||||
return processCreateView(actor, activity)
|
return processCreateView(actor, activity)
|
||||||
} else if (activityType === 'Dislike') {
|
} else if (activityType === 'Dislike') {
|
||||||
return processCreateDislike(actor, activity)
|
return retryTransactionWrapper(processCreateDislike, actor, activity)
|
||||||
} else if (activityType === 'Video') {
|
} else if (activityType === 'Video') {
|
||||||
return processCreateVideo(actor, activity)
|
return processCreateVideo(actor, activity)
|
||||||
} else if (activityType === 'Flag') {
|
} else if (activityType === 'Flag') {
|
||||||
return processCreateVideoAbuse(actor, activityObject as VideoAbuseObject)
|
return retryTransactionWrapper(processCreateVideoAbuse, actor, activityObject as VideoAbuseObject)
|
||||||
} else if (activityType === 'Note') {
|
} else if (activityType === 'Note') {
|
||||||
return processCreateVideoComment(actor, activity)
|
return retryTransactionWrapper(processCreateVideoComment, actor, activity)
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.warn('Unknown activity object type %s when creating activity.', activityType, { activity: activity.id })
|
logger.warn('Unknown activity object type %s when creating activity.', activityType, { activity: activity.id })
|
||||||
|
@ -54,15 +54,6 @@ async function processCreateVideo (
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processCreateDislike (byActor: ActorModel, activity: ActivityCreate) {
|
async function processCreateDislike (byActor: ActorModel, activity: ActivityCreate) {
|
||||||
const options = {
|
|
||||||
arguments: [ byActor, activity ],
|
|
||||||
errorMessage: 'Cannot dislike the video with many retries.'
|
|
||||||
}
|
|
||||||
|
|
||||||
return retryTransactionWrapper(createVideoDislike, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function createVideoDislike (byActor: ActorModel, activity: ActivityCreate) {
|
|
||||||
const dislike = activity.object as DislikeObject
|
const dislike = activity.object as DislikeObject
|
||||||
const byAccount = byActor.Account
|
const byAccount = byActor.Account
|
||||||
|
|
||||||
|
@ -109,16 +100,7 @@ async function processCreateView (byActor: ActorModel, activity: ActivityCreate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function processCreateVideoAbuse (actor: ActorModel, videoAbuseToCreateData: VideoAbuseObject) {
|
async function processCreateVideoAbuse (actor: ActorModel, videoAbuseToCreateData: VideoAbuseObject) {
|
||||||
const options = {
|
|
||||||
arguments: [ actor, videoAbuseToCreateData ],
|
|
||||||
errorMessage: 'Cannot insert the remote video abuse with many retries.'
|
|
||||||
}
|
|
||||||
|
|
||||||
return retryTransactionWrapper(addRemoteVideoAbuse, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function addRemoteVideoAbuse (actor: ActorModel, videoAbuseToCreateData: VideoAbuseObject) {
|
|
||||||
logger.debug('Reporting remote abuse for video %s.', videoAbuseToCreateData.object)
|
logger.debug('Reporting remote abuse for video %s.', videoAbuseToCreateData.object)
|
||||||
|
|
||||||
const account = actor.Account
|
const account = actor.Account
|
||||||
|
@ -139,16 +121,7 @@ async function addRemoteVideoAbuse (actor: ActorModel, videoAbuseToCreateData: V
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function processCreateVideoComment (byActor: ActorModel, activity: ActivityCreate) {
|
async function processCreateVideoComment (byActor: ActorModel, activity: ActivityCreate) {
|
||||||
const options = {
|
|
||||||
arguments: [ byActor, activity ],
|
|
||||||
errorMessage: 'Cannot create video comment with many retries.'
|
|
||||||
}
|
|
||||||
|
|
||||||
return retryTransactionWrapper(createVideoComment, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function createVideoComment (byActor: ActorModel, activity: ActivityCreate) {
|
|
||||||
const comment = activity.object as VideoCommentObject
|
const comment = activity.object as VideoCommentObject
|
||||||
const byAccount = byActor.Account
|
const byAccount = byActor.Account
|
||||||
|
|
||||||
|
|
|
@ -21,12 +21,12 @@ async function processDeleteActivity (activity: ActivityDelete) {
|
||||||
if (!actor.Account) throw new Error('Actor ' + actor.url + ' is a person but we cannot find it in database.')
|
if (!actor.Account) throw new Error('Actor ' + actor.url + ' is a person but we cannot find it in database.')
|
||||||
|
|
||||||
actor.Account.Actor = await actor.Account.$get('Actor') as ActorModel
|
actor.Account.Actor = await actor.Account.$get('Actor') as ActorModel
|
||||||
return processDeleteAccount(actor.Account)
|
return retryTransactionWrapper(processDeleteAccount, actor.Account)
|
||||||
} else if (actor.type === 'Group') {
|
} else if (actor.type === 'Group') {
|
||||||
if (!actor.VideoChannel) throw new Error('Actor ' + actor.url + ' is a group but we cannot find it in database.')
|
if (!actor.VideoChannel) throw new Error('Actor ' + actor.url + ' is a group but we cannot find it in database.')
|
||||||
|
|
||||||
actor.VideoChannel.Actor = await actor.VideoChannel.$get('Actor') as ActorModel
|
actor.VideoChannel.Actor = await actor.VideoChannel.$get('Actor') as ActorModel
|
||||||
return processDeleteVideoChannel(actor.VideoChannel)
|
return retryTransactionWrapper(processDeleteVideoChannel, actor.VideoChannel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,14 +34,14 @@ async function processDeleteActivity (activity: ActivityDelete) {
|
||||||
{
|
{
|
||||||
const videoCommentInstance = await VideoCommentModel.loadByUrlAndPopulateAccount(objectUrl)
|
const videoCommentInstance = await VideoCommentModel.loadByUrlAndPopulateAccount(objectUrl)
|
||||||
if (videoCommentInstance) {
|
if (videoCommentInstance) {
|
||||||
return processDeleteVideoComment(actor, videoCommentInstance, activity)
|
return retryTransactionWrapper(processDeleteVideoComment, actor, videoCommentInstance, activity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const videoInstance = await VideoModel.loadByUrlAndPopulateAccount(objectUrl)
|
const videoInstance = await VideoModel.loadByUrlAndPopulateAccount(objectUrl)
|
||||||
if (videoInstance) {
|
if (videoInstance) {
|
||||||
return processDeleteVideo(actor, videoInstance)
|
return retryTransactionWrapper(processDeleteVideo, actor, videoInstance)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,15 +57,6 @@ export {
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
async function processDeleteVideo (actor: ActorModel, videoToDelete: VideoModel) {
|
async function processDeleteVideo (actor: ActorModel, videoToDelete: VideoModel) {
|
||||||
const options = {
|
|
||||||
arguments: [ actor, videoToDelete ],
|
|
||||||
errorMessage: 'Cannot remove the remote video with many retries.'
|
|
||||||
}
|
|
||||||
|
|
||||||
await retryTransactionWrapper(deleteRemoteVideo, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function deleteRemoteVideo (actor: ActorModel, videoToDelete: VideoModel) {
|
|
||||||
logger.debug('Removing remote video "%s".', videoToDelete.uuid)
|
logger.debug('Removing remote video "%s".', videoToDelete.uuid)
|
||||||
|
|
||||||
await sequelizeTypescript.transaction(async t => {
|
await sequelizeTypescript.transaction(async t => {
|
||||||
|
@ -80,15 +71,6 @@ async function deleteRemoteVideo (actor: ActorModel, videoToDelete: VideoModel)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processDeleteAccount (accountToRemove: AccountModel) {
|
async function processDeleteAccount (accountToRemove: AccountModel) {
|
||||||
const options = {
|
|
||||||
arguments: [ accountToRemove ],
|
|
||||||
errorMessage: 'Cannot remove the remote account with many retries.'
|
|
||||||
}
|
|
||||||
|
|
||||||
await retryTransactionWrapper(deleteRemoteAccount, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function deleteRemoteAccount (accountToRemove: AccountModel) {
|
|
||||||
logger.debug('Removing remote account "%s".', accountToRemove.Actor.uuid)
|
logger.debug('Removing remote account "%s".', accountToRemove.Actor.uuid)
|
||||||
|
|
||||||
await sequelizeTypescript.transaction(async t => {
|
await sequelizeTypescript.transaction(async t => {
|
||||||
|
@ -99,15 +81,6 @@ async function deleteRemoteAccount (accountToRemove: AccountModel) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processDeleteVideoChannel (videoChannelToRemove: VideoChannelModel) {
|
async function processDeleteVideoChannel (videoChannelToRemove: VideoChannelModel) {
|
||||||
const options = {
|
|
||||||
arguments: [ videoChannelToRemove ],
|
|
||||||
errorMessage: 'Cannot remove the remote video channel with many retries.'
|
|
||||||
}
|
|
||||||
|
|
||||||
await retryTransactionWrapper(deleteRemoteVideoChannel, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function deleteRemoteVideoChannel (videoChannelToRemove: VideoChannelModel) {
|
|
||||||
logger.debug('Removing remote video channel "%s".', videoChannelToRemove.Actor.uuid)
|
logger.debug('Removing remote video channel "%s".', videoChannelToRemove.Actor.uuid)
|
||||||
|
|
||||||
await sequelizeTypescript.transaction(async t => {
|
await sequelizeTypescript.transaction(async t => {
|
||||||
|
@ -117,16 +90,7 @@ async function deleteRemoteVideoChannel (videoChannelToRemove: VideoChannelModel
|
||||||
logger.info('Remote video channel with uuid %s removed.', videoChannelToRemove.Actor.uuid)
|
logger.info('Remote video channel with uuid %s removed.', videoChannelToRemove.Actor.uuid)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processDeleteVideoComment (byActor: ActorModel, videoComment: VideoCommentModel, activity: ActivityDelete) {
|
function processDeleteVideoComment (byActor: ActorModel, videoComment: VideoCommentModel, activity: ActivityDelete) {
|
||||||
const options = {
|
|
||||||
arguments: [ byActor, videoComment, activity ],
|
|
||||||
errorMessage: 'Cannot remove the remote video comment with many retries.'
|
|
||||||
}
|
|
||||||
|
|
||||||
await retryTransactionWrapper(deleteRemoteVideoComment, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteRemoteVideoComment (byActor: ActorModel, videoComment: VideoCommentModel, activity: ActivityDelete) {
|
|
||||||
logger.debug('Removing remote video comment "%s".', videoComment.url)
|
logger.debug('Removing remote video comment "%s".', videoComment.url)
|
||||||
|
|
||||||
return sequelizeTypescript.transaction(async t => {
|
return sequelizeTypescript.transaction(async t => {
|
||||||
|
|
|
@ -11,7 +11,7 @@ async function processFollowActivity (activity: ActivityFollow) {
|
||||||
const activityObject = activity.object
|
const activityObject = activity.object
|
||||||
const actor = await getOrCreateActorAndServerAndModel(activity.actor)
|
const actor = await getOrCreateActorAndServerAndModel(activity.actor)
|
||||||
|
|
||||||
return processFollow(actor, activityObject)
|
return retryTransactionWrapper(processFollow, actor, activityObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -22,16 +22,7 @@ export {
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
function processFollow (actor: ActorModel, targetActorURL: string) {
|
async function processFollow (actor: ActorModel, targetActorURL: string) {
|
||||||
const options = {
|
|
||||||
arguments: [ actor, targetActorURL ],
|
|
||||||
errorMessage: 'Cannot follow with many retries.'
|
|
||||||
}
|
|
||||||
|
|
||||||
return retryTransactionWrapper(follow, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function follow (actor: ActorModel, targetActorURL: string) {
|
|
||||||
await sequelizeTypescript.transaction(async t => {
|
await sequelizeTypescript.transaction(async t => {
|
||||||
const targetActor = await ActorModel.loadByUrl(targetActorURL, t)
|
const targetActor = await ActorModel.loadByUrl(targetActorURL, t)
|
||||||
|
|
||||||
|
|
|
@ -4,14 +4,13 @@ import { sequelizeTypescript } from '../../../initializers'
|
||||||
import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
|
import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
|
||||||
import { ActorModel } from '../../../models/activitypub/actor'
|
import { ActorModel } from '../../../models/activitypub/actor'
|
||||||
import { getOrCreateActorAndServerAndModel } from '../actor'
|
import { getOrCreateActorAndServerAndModel } from '../actor'
|
||||||
import { forwardActivity, forwardVideoRelatedActivity } from '../send/utils'
|
import { forwardVideoRelatedActivity } from '../send/utils'
|
||||||
import { getOrCreateAccountAndVideoAndChannel } from '../videos'
|
import { getOrCreateAccountAndVideoAndChannel } from '../videos'
|
||||||
import { getActorsInvolvedInVideo } from '../audience'
|
|
||||||
|
|
||||||
async function processLikeActivity (activity: ActivityLike) {
|
async function processLikeActivity (activity: ActivityLike) {
|
||||||
const actor = await getOrCreateActorAndServerAndModel(activity.actor)
|
const actor = await getOrCreateActorAndServerAndModel(activity.actor)
|
||||||
|
|
||||||
return processLikeVideo(actor, activity)
|
return retryTransactionWrapper(processLikeVideo, actor, activity)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -22,16 +21,7 @@ export {
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
async function processLikeVideo (actor: ActorModel, activity: ActivityLike) {
|
async function processLikeVideo (byActor: ActorModel, activity: ActivityLike) {
|
||||||
const options = {
|
|
||||||
arguments: [ actor, activity ],
|
|
||||||
errorMessage: 'Cannot like the video with many retries.'
|
|
||||||
}
|
|
||||||
|
|
||||||
return retryTransactionWrapper(createVideoLike, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function createVideoLike (byActor: ActorModel, activity: ActivityLike) {
|
|
||||||
const videoUrl = activity.object
|
const videoUrl = activity.object
|
||||||
|
|
||||||
const byAccount = byActor.Account
|
const byAccount = byActor.Account
|
||||||
|
|
|
@ -18,13 +18,13 @@ async function processUndoActivity (activity: ActivityUndo) {
|
||||||
const actorUrl = getActorUrl(activity.actor)
|
const actorUrl = getActorUrl(activity.actor)
|
||||||
|
|
||||||
if (activityToUndo.type === 'Like') {
|
if (activityToUndo.type === 'Like') {
|
||||||
return processUndoLike(actorUrl, activity)
|
return retryTransactionWrapper(processUndoLike, actorUrl, activity)
|
||||||
} else if (activityToUndo.type === 'Create' && activityToUndo.object.type === 'Dislike') {
|
} else if (activityToUndo.type === 'Create' && activityToUndo.object.type === 'Dislike') {
|
||||||
return processUndoDislike(actorUrl, activity)
|
return retryTransactionWrapper(processUndoDislike, actorUrl, activity)
|
||||||
} else if (activityToUndo.type === 'Follow') {
|
} else if (activityToUndo.type === 'Follow') {
|
||||||
return processUndoFollow(actorUrl, activityToUndo)
|
return retryTransactionWrapper(processUndoFollow, actorUrl, activityToUndo)
|
||||||
} else if (activityToUndo.type === 'Announce') {
|
} else if (activityToUndo.type === 'Announce') {
|
||||||
return processUndoAnnounce(actorUrl, activityToUndo)
|
return retryTransactionWrapper(processUndoAnnounce, actorUrl, activityToUndo)
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.warn('Unknown activity object type %s -> %s when undo activity.', activityToUndo.type, { activity: activity.id })
|
logger.warn('Unknown activity object type %s -> %s when undo activity.', activityToUndo.type, { activity: activity.id })
|
||||||
|
@ -40,16 +40,7 @@ export {
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
function processUndoLike (actorUrl: string, activity: ActivityUndo) {
|
async function processUndoLike (actorUrl: string, activity: ActivityUndo) {
|
||||||
const options = {
|
|
||||||
arguments: [ actorUrl, activity ],
|
|
||||||
errorMessage: 'Cannot undo like with many retries.'
|
|
||||||
}
|
|
||||||
|
|
||||||
return retryTransactionWrapper(undoLike, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function undoLike (actorUrl: string, activity: ActivityUndo) {
|
|
||||||
const likeActivity = activity.object as ActivityLike
|
const likeActivity = activity.object as ActivityLike
|
||||||
|
|
||||||
const { video } = await getOrCreateAccountAndVideoAndChannel(likeActivity.object)
|
const { video } = await getOrCreateAccountAndVideoAndChannel(likeActivity.object)
|
||||||
|
@ -73,16 +64,7 @@ async function undoLike (actorUrl: string, activity: ActivityUndo) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function processUndoDislike (actorUrl: string, activity: ActivityUndo) {
|
async function processUndoDislike (actorUrl: string, activity: ActivityUndo) {
|
||||||
const options = {
|
|
||||||
arguments: [ actorUrl, activity ],
|
|
||||||
errorMessage: 'Cannot undo dislike with many retries.'
|
|
||||||
}
|
|
||||||
|
|
||||||
return retryTransactionWrapper(undoDislike, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function undoDislike (actorUrl: string, activity: ActivityUndo) {
|
|
||||||
const dislike = activity.object.object as DislikeObject
|
const dislike = activity.object.object as DislikeObject
|
||||||
|
|
||||||
const { video } = await getOrCreateAccountAndVideoAndChannel(dislike.object)
|
const { video } = await getOrCreateAccountAndVideoAndChannel(dislike.object)
|
||||||
|
@ -107,15 +89,6 @@ async function undoDislike (actorUrl: string, activity: ActivityUndo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function processUndoFollow (actorUrl: string, followActivity: ActivityFollow) {
|
function processUndoFollow (actorUrl: string, followActivity: ActivityFollow) {
|
||||||
const options = {
|
|
||||||
arguments: [ actorUrl, followActivity ],
|
|
||||||
errorMessage: 'Cannot undo follow with many retries.'
|
|
||||||
}
|
|
||||||
|
|
||||||
return retryTransactionWrapper(undoFollow, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
function undoFollow (actorUrl: string, followActivity: ActivityFollow) {
|
|
||||||
return sequelizeTypescript.transaction(async t => {
|
return sequelizeTypescript.transaction(async t => {
|
||||||
const follower = await ActorModel.loadByUrl(actorUrl, t)
|
const follower = await ActorModel.loadByUrl(actorUrl, t)
|
||||||
const following = await ActorModel.loadByUrl(followActivity.object, t)
|
const following = await ActorModel.loadByUrl(followActivity.object, t)
|
||||||
|
@ -130,15 +103,6 @@ function undoFollow (actorUrl: string, followActivity: ActivityFollow) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function processUndoAnnounce (actorUrl: string, announceActivity: ActivityAnnounce) {
|
function processUndoAnnounce (actorUrl: string, announceActivity: ActivityAnnounce) {
|
||||||
const options = {
|
|
||||||
arguments: [ actorUrl, announceActivity ],
|
|
||||||
errorMessage: 'Cannot undo announce with many retries.'
|
|
||||||
}
|
|
||||||
|
|
||||||
return retryTransactionWrapper(undoAnnounce, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
function undoAnnounce (actorUrl: string, announceActivity: ActivityAnnounce) {
|
|
||||||
return sequelizeTypescript.transaction(async t => {
|
return sequelizeTypescript.transaction(async t => {
|
||||||
const byAccount = await AccountModel.loadByUrl(actorUrl, t)
|
const byAccount = await AccountModel.loadByUrl(actorUrl, t)
|
||||||
if (!byAccount) throw new Error('Unknown account ' + actorUrl)
|
if (!byAccount) throw new Error('Unknown account ' + actorUrl)
|
||||||
|
|
|
@ -25,9 +25,9 @@ async function processUpdateActivity (activity: ActivityUpdate) {
|
||||||
const objectType = activity.object.type
|
const objectType = activity.object.type
|
||||||
|
|
||||||
if (objectType === 'Video') {
|
if (objectType === 'Video') {
|
||||||
return processUpdateVideo(actor, activity)
|
return retryTransactionWrapper(processUpdateVideo, actor, activity)
|
||||||
} else if (objectType === 'Person' || objectType === 'Application' || objectType === 'Group') {
|
} else if (objectType === 'Person' || objectType === 'Application' || objectType === 'Group') {
|
||||||
return processUpdateActor(actor, activity)
|
return retryTransactionWrapper(processUpdateActor, actor, activity)
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined
|
return undefined
|
||||||
|
@ -41,16 +41,7 @@ export {
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
function processUpdateVideo (actor: ActorModel, activity: ActivityUpdate) {
|
async function processUpdateVideo (actor: ActorModel, activity: ActivityUpdate) {
|
||||||
const options = {
|
|
||||||
arguments: [ actor, activity ],
|
|
||||||
errorMessage: 'Cannot update the remote video with many retries'
|
|
||||||
}
|
|
||||||
|
|
||||||
return retryTransactionWrapper(updateRemoteVideo, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function updateRemoteVideo (actor: ActorModel, activity: ActivityUpdate) {
|
|
||||||
const videoObject = activity.object as VideoTorrentObject
|
const videoObject = activity.object as VideoTorrentObject
|
||||||
|
|
||||||
if (sanitizeAndCheckVideoTorrentObject(videoObject) === false) {
|
if (sanitizeAndCheckVideoTorrentObject(videoObject) === false) {
|
||||||
|
@ -136,16 +127,7 @@ async function updateRemoteVideo (actor: ActorModel, activity: ActivityUpdate) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function processUpdateActor (actor: ActorModel, activity: ActivityUpdate) {
|
async function processUpdateActor (actor: ActorModel, activity: ActivityUpdate) {
|
||||||
const options = {
|
|
||||||
arguments: [ actor, activity ],
|
|
||||||
errorMessage: 'Cannot update the remote actor with many retries'
|
|
||||||
}
|
|
||||||
|
|
||||||
return retryTransactionWrapper(updateRemoteActor, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function updateRemoteActor (actor: ActorModel, activity: ActivityUpdate) {
|
|
||||||
const actorAttributesToUpdate = activity.object as ActivityPubActor
|
const actorAttributesToUpdate = activity.object as ActivityPubActor
|
||||||
|
|
||||||
logger.debug('Updating remote account "%s".', actorAttributesToUpdate.uuid)
|
logger.debug('Updating remote account "%s".', actorAttributesToUpdate.uuid)
|
||||||
|
|
|
@ -228,12 +228,7 @@ async function getOrCreateAccountAndVideoAndChannel (videoObject: VideoTorrentOb
|
||||||
|
|
||||||
const channelActor = await getOrCreateVideoChannel(videoObject)
|
const channelActor = await getOrCreateVideoChannel(videoObject)
|
||||||
|
|
||||||
const options = {
|
const video = await retryTransactionWrapper(getOrCreateVideo, videoObject, channelActor)
|
||||||
arguments: [ videoObject, channelActor ],
|
|
||||||
errorMessage: 'Cannot insert the remote video with many retries.'
|
|
||||||
}
|
|
||||||
|
|
||||||
const video = await retryTransactionWrapper(getOrCreateVideo, options)
|
|
||||||
|
|
||||||
// Process outside the transaction because we could fetch remote data
|
// Process outside the transaction because we could fetch remote data
|
||||||
logger.info('Adding likes of video %s.', video.uuid)
|
logger.info('Adding likes of video %s.', video.uuid)
|
||||||
|
|
|
@ -26,12 +26,8 @@ async function processActivityPubFollow (job: kue.Job) {
|
||||||
const targetActor = await getOrCreateActorAndServerAndModel(actorUrl)
|
const targetActor = await getOrCreateActorAndServerAndModel(actorUrl)
|
||||||
|
|
||||||
const fromActor = await getServerActor()
|
const fromActor = await getServerActor()
|
||||||
const options = {
|
|
||||||
arguments: [ fromActor, targetActor ],
|
|
||||||
errorMessage: 'Cannot follow with many retries.'
|
|
||||||
}
|
|
||||||
|
|
||||||
return retryTransactionWrapper(follow, options)
|
return retryTransactionWrapper(follow, fromActor, targetActor)
|
||||||
}
|
}
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -52,19 +52,11 @@ async function processVideoFile (job: kue.Job) {
|
||||||
if (payload.resolution) {
|
if (payload.resolution) {
|
||||||
await video.transcodeOriginalVideofile(payload.resolution, payload.isPortraitMode)
|
await video.transcodeOriginalVideofile(payload.resolution, payload.isPortraitMode)
|
||||||
|
|
||||||
const options = {
|
await retryTransactionWrapper(onVideoFileTranscoderOrImportSuccess, video)
|
||||||
arguments: [ video ],
|
|
||||||
errorMessage: 'Cannot execute onVideoFileTranscoderOrImportSuccess with many retries.'
|
|
||||||
}
|
|
||||||
await retryTransactionWrapper(onVideoFileTranscoderOrImportSuccess, options)
|
|
||||||
} else {
|
} else {
|
||||||
await video.optimizeOriginalVideofile()
|
await video.optimizeOriginalVideofile()
|
||||||
|
|
||||||
const options = {
|
await retryTransactionWrapper(onVideoFileOptimizerSuccess, video, payload.isNewVideo)
|
||||||
arguments: [ video, payload.isNewVideo ],
|
|
||||||
errorMessage: 'Cannot execute onVideoFileOptimizerSuccess with many retries.'
|
|
||||||
}
|
|
||||||
await retryTransactionWrapper(onVideoFileOptimizerSuccess, options)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return video
|
return video
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { eachSeries } from 'async'
|
import { eachSeries } from 'async'
|
||||||
import { NextFunction, Request, RequestHandler, Response } from 'express'
|
import { NextFunction, Request, RequestHandler, Response } from 'express'
|
||||||
|
import { retryTransactionWrapper } from '../helpers/database-utils'
|
||||||
|
|
||||||
// Syntactic sugar to avoid try/catch in express controllers
|
// Syntactic sugar to avoid try/catch in express controllers
|
||||||
// Thanks: https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016
|
// Thanks: https://medium.com/@Abazhenov/using-async-await-in-express-with-node-8-b8af872c0016
|
||||||
|
@ -20,8 +21,17 @@ function asyncMiddleware (fun: RequestPromiseHandler | RequestPromiseHandler[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function asyncRetryTransactionMiddleware (fun: RequestPromiseHandler) {
|
||||||
|
return (req: Request, res: Response, next: NextFunction) => {
|
||||||
|
return Promise.resolve(
|
||||||
|
retryTransactionWrapper(fun, req, res, next)
|
||||||
|
).catch(err => next(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
export {
|
export {
|
||||||
asyncMiddleware
|
asyncMiddleware,
|
||||||
|
asyncRetryTransactionMiddleware
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue