aboutsummaryrefslogtreecommitdiffhomepage
path: root/server
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-12-23 11:09:31 +0100
committerChocobozzz <me@florianbigard.com>2021-12-23 11:13:06 +0100
commitdbd9fb44ddd880622265097bd7baf4dd71ea0861 (patch)
treeb531f861026a52bcacfdee076431c1c34d9ba78d /server
parent482b26231b4e39234f107b8400ef606c5f003c55 (diff)
downloadPeerTube-dbd9fb44ddd880622265097bd7baf4dd71ea0861.tar.gz
PeerTube-dbd9fb44ddd880622265097bd7baf4dd71ea0861.tar.zst
PeerTube-dbd9fb44ddd880622265097bd7baf4dd71ea0861.zip
Don't stuck state when move transcoding job failed
Diffstat (limited to 'server')
-rw-r--r--server/initializers/constants.ts3
-rw-r--r--server/lib/job-queue/handlers/move-to-object-storage.ts29
-rw-r--r--server/lib/video-state.ts11
-rw-r--r--server/models/video/video-job-info.ts15
4 files changed, 44 insertions, 14 deletions
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts
index 57f7af789..7816561fd 100644
--- a/server/initializers/constants.ts
+++ b/server/initializers/constants.ts
@@ -427,7 +427,8 @@ const VIDEO_STATES: { [ id in VideoState ]: string } = {
427 [VideoState.WAITING_FOR_LIVE]: 'Waiting for livestream', 427 [VideoState.WAITING_FOR_LIVE]: 'Waiting for livestream',
428 [VideoState.LIVE_ENDED]: 'Livestream ended', 428 [VideoState.LIVE_ENDED]: 'Livestream ended',
429 [VideoState.TO_MOVE_TO_EXTERNAL_STORAGE]: 'To move to an external storage', 429 [VideoState.TO_MOVE_TO_EXTERNAL_STORAGE]: 'To move to an external storage',
430 [VideoState.TRANSCODING_FAILED]: 'Transcoding failed' 430 [VideoState.TRANSCODING_FAILED]: 'Transcoding failed',
431 [VideoState.TO_MOVE_TO_EXTERNAL_STORAGE_FAILED]: 'External storage move failed'
431} 432}
432 433
433const VIDEO_IMPORT_STATES: { [ id in VideoImportState ]: string } = { 434const VIDEO_IMPORT_STATES: { [ id in VideoImportState ]: string } = {
diff --git a/server/lib/job-queue/handlers/move-to-object-storage.ts b/server/lib/job-queue/handlers/move-to-object-storage.ts
index b5eea0184..d9c415b2d 100644
--- a/server/lib/job-queue/handlers/move-to-object-storage.ts
+++ b/server/lib/job-queue/handlers/move-to-object-storage.ts
@@ -7,7 +7,7 @@ import { CONFIG } from '@server/initializers/config'
7import { P2P_MEDIA_LOADER_PEER_VERSION } from '@server/initializers/constants' 7import { P2P_MEDIA_LOADER_PEER_VERSION } from '@server/initializers/constants'
8import { storeHLSFile, storeWebTorrentFile } from '@server/lib/object-storage' 8import { storeHLSFile, storeWebTorrentFile } from '@server/lib/object-storage'
9import { getHLSDirectory, getHlsResolutionPlaylistFilename } from '@server/lib/paths' 9import { getHLSDirectory, getHlsResolutionPlaylistFilename } from '@server/lib/paths'
10import { moveToNextState } from '@server/lib/video-state' 10import { moveToFailedMoveToObjectStorageState, moveToNextState } from '@server/lib/video-state'
11import { VideoModel } from '@server/models/video/video' 11import { VideoModel } from '@server/models/video/video'
12import { VideoJobInfoModel } from '@server/models/video/video-job-info' 12import { VideoJobInfoModel } from '@server/models/video/video-job-info'
13import { MStreamingPlaylistVideo, MVideo, MVideoFile, MVideoWithAllFiles } from '@server/types/models' 13import { MStreamingPlaylistVideo, MVideo, MVideoFile, MVideoWithAllFiles } from '@server/types/models'
@@ -24,18 +24,25 @@ export async function processMoveToObjectStorage (job: Job) {
24 return undefined 24 return undefined
25 } 25 }
26 26
27 if (video.VideoFiles) { 27 try {
28 await moveWebTorrentFiles(video) 28 if (video.VideoFiles) {
29 } 29 await moveWebTorrentFiles(video)
30 }
30 31
31 if (video.VideoStreamingPlaylists) { 32 if (video.VideoStreamingPlaylists) {
32 await moveHLSFiles(video) 33 await moveHLSFiles(video)
33 } 34 }
35
36 const pendingMove = await VideoJobInfoModel.decrease(video.uuid, 'pendingMove')
37 if (pendingMove === 0) {
38 logger.info('Running cleanup after moving files to object storage (video %s in job %d)', video.uuid, job.id)
39 await doAfterLastJob(video, payload.isNewVideo)
40 }
41 } catch (err) {
42 logger.error('Cannot move video %s to object storage.', video.url, { err })
34 43
35 const pendingMove = await VideoJobInfoModel.decrease(video.uuid, 'pendingMove') 44 await moveToFailedMoveToObjectStorageState(video)
36 if (pendingMove === 0) { 45 await VideoJobInfoModel.abortAllTasks(video.uuid, 'pendingMove')
37 logger.info('Running cleanup after moving files to object storage (video %s in job %d)', video.uuid, job.id)
38 await doAfterLastJob(video, payload.isNewVideo)
39 } 46 }
40 47
41 return payload.videoUUID 48 return payload.videoUUID
diff --git a/server/lib/video-state.ts b/server/lib/video-state.ts
index e420991cd..97ff540ed 100644
--- a/server/lib/video-state.ts
+++ b/server/lib/video-state.ts
@@ -4,7 +4,7 @@ import { CONFIG } from '@server/initializers/config'
4import { sequelizeTypescript } from '@server/initializers/database' 4import { sequelizeTypescript } from '@server/initializers/database'
5import { VideoModel } from '@server/models/video/video' 5import { VideoModel } from '@server/models/video/video'
6import { VideoJobInfoModel } from '@server/models/video/video-job-info' 6import { VideoJobInfoModel } from '@server/models/video/video-job-info'
7import { MVideoFullLight, MVideoUUID } from '@server/types/models' 7import { MVideo, MVideoFullLight, MVideoUUID } from '@server/types/models'
8import { VideoState } from '@shared/models' 8import { VideoState } from '@shared/models'
9import { federateVideoIfNeeded } from './activitypub/videos' 9import { federateVideoIfNeeded } from './activitypub/videos'
10import { Notifier } from './notifier' 10import { Notifier } from './notifier'
@@ -79,18 +79,25 @@ async function moveToExternalStorageState (video: MVideoFullLight, isNewVideo: b
79 } 79 }
80} 80}
81 81
82function moveToFailedTranscodingState (video: MVideoFullLight) { 82function moveToFailedTranscodingState (video: MVideo) {
83 if (video.state === VideoState.TRANSCODING_FAILED) return 83 if (video.state === VideoState.TRANSCODING_FAILED) return
84 84
85 return video.setNewState(VideoState.TRANSCODING_FAILED, false, undefined) 85 return video.setNewState(VideoState.TRANSCODING_FAILED, false, undefined)
86} 86}
87 87
88function moveToFailedMoveToObjectStorageState (video: MVideo) {
89 if (video.state === VideoState.TO_MOVE_TO_EXTERNAL_STORAGE_FAILED) return
90
91 return video.setNewState(VideoState.TO_MOVE_TO_EXTERNAL_STORAGE_FAILED, false, undefined)
92}
93
88// --------------------------------------------------------------------------- 94// ---------------------------------------------------------------------------
89 95
90export { 96export {
91 buildNextVideoState, 97 buildNextVideoState,
92 moveToExternalStorageState, 98 moveToExternalStorageState,
93 moveToFailedTranscodingState, 99 moveToFailedTranscodingState,
100 moveToFailedMoveToObjectStorageState,
94 moveToNextState 101 moveToNextState
95} 102}
96 103
diff --git a/server/models/video/video-job-info.ts b/server/models/video/video-job-info.ts
index 6a67a214c..7497addf1 100644
--- a/server/models/video/video-job-info.ts
+++ b/server/models/video/video-job-info.ts
@@ -99,4 +99,19 @@ export class VideoJobInfoModel extends Model<Partial<AttributesOnly<VideoJobInfo
99 99
100 return pendingMove 100 return pendingMove
101 } 101 }
102
103 static async abortAllTasks (videoUUID: string, column: VideoJobInfoColumnType): Promise<void> {
104 const options = { type: QueryTypes.UPDATE as QueryTypes.UPDATE, bind: { videoUUID } }
105
106 await VideoJobInfoModel.sequelize.query(`
107 UPDATE
108 "videoJobInfo"
109 SET
110 "${column}" = 0,
111 "updatedAt" = NOW()
112 FROM "video"
113 WHERE
114 "video"."id" = "videoJobInfo"."videoId" AND "video"."uuid" = $videoUUID
115 `, options)
116 }
102} 117}