Skip to content

Commit

Permalink
Remote runner upload success file using external url
Browse files Browse the repository at this point in the history
Remote runner can now upload a success file using directly to
a given url instead to the server. It avoids the server to have to
download the file and upload it again, thus reducing resources
usage.
  • Loading branch information
polyhb committed Dec 21, 2023
1 parent 00e0d15 commit 29af130
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 4 deletions.
28 changes: 27 additions & 1 deletion apps/peertube-runner/src/server/process/shared/process-vod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,37 @@ export async function processHLSTranscoding (options: ProcessOptions<RunnerJobVO
videoFile: videoPath
}

if (payload.output.videoFileUrl) {
logger.info(`Uploading video file to ${payload.output.videoFileUrl.url} for HLS transcoding job ${job.jobToken}`)
await server.runnerJobs.uploadTranscodeResult({
uploadResultUrl: payload.output.videoFileUrl,
file: videoPath,
runnerToken,
jobToken: job.jobToken,
payload: successBody
})
}

if (payload.output.playlistFileUrl) {
logger.info(`Uploading playlist file to ${payload.output.playlistFileUrl.url} for HLS transcoding job ${job.jobToken}`)
await server.runnerJobs.uploadTranscodeResult({
uploadResultUrl: payload.output.playlistFileUrl,
file: outputPath,
runnerToken,
jobToken: job.jobToken,
payload: successBody
})
}

await server.runnerJobs.success({
jobToken: job.jobToken,
jobUUID: job.uuid,
runnerToken,
payload: successBody
payload: successBody,
uploadedFiles: {
videoFile: !!payload.output.videoFileUrl,
resolutionPlaylistFile: !!payload.output.videoFileUrl
}
})
} finally {
if (inputPath) await remove(inputPath)
Expand Down
7 changes: 7 additions & 0 deletions packages/models/src/runners/runner-job-payload.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,19 @@ export interface RunnerJobVODWebVideoTranscodingPayload {
}
}

export interface UploadUrlTransodingResultPayload {
url: string
fields: { [key: string]: any } | undefined
}

export interface RunnerJobVODHLSTranscodingPayload {
input: {
videoFileUrl: string
}

output: {
videoFileUrl?: UploadUrlTransodingResultPayload
playlistFileUrl?: UploadUrlTransodingResultPayload
resolution: number
fps: number
}
Expand Down
4 changes: 4 additions & 0 deletions packages/models/src/runners/runner-job-success-body.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ export interface RunnerJobSuccessBody {
jobToken: string

payload: RunnerJobSuccessPayload
uploadedFiles?: {
videoFile?: boolean
resolutionPlaylistFile?: boolean
}
}

// ---------------------------------------------------------------------------
Expand Down
30 changes: 27 additions & 3 deletions packages/server-commands/src/runners/runner-jobs-command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
RunnerJobType,
RunnerJobUpdateBody,
RunnerJobVODPayload,
UploadUrlTransodingResultPayload,
VODHLSTranscodingSuccess,
VODWebVideoTranscodingSuccess
} from '@peertube/peertube-models'
Expand Down Expand Up @@ -178,19 +179,21 @@ export class RunnerJobsCommand extends AbstractCommand {
}

success (options: OverrideCommandOptions & RunnerJobSuccessBody & { jobUUID: string }) {
const { payload } = options
const { payload, uploadedFiles } = options

const path = '/api/v1/runners/jobs/' + options.jobUUID + '/success'
const attaches: { [id: string]: any } = {}
let payloadWithoutFiles = payload

if ((isWebVideoOrAudioMergeTranscodingPayloadSuccess(payload) || isHLSTranscodingPayloadSuccess(payload)) && payload.videoFile) {
if (
(isWebVideoOrAudioMergeTranscodingPayloadSuccess(payload) || isHLSTranscodingPayloadSuccess(payload)) &&
payload.videoFile && !uploadedFiles?.videoFile) {
attaches[`payload[videoFile]`] = payload.videoFile

payloadWithoutFiles = omit(payloadWithoutFiles as VODWebVideoTranscodingSuccess, [ 'videoFile' ])
}

if (isHLSTranscodingPayloadSuccess(payload) && payload.resolutionPlaylistFile) {
if (isHLSTranscodingPayloadSuccess(payload) && payload.resolutionPlaylistFile && !uploadedFiles?.resolutionPlaylistFile) {
attaches[`payload[resolutionPlaylistFile]`] = payload.resolutionPlaylistFile

payloadWithoutFiles = omit(payloadWithoutFiles as VODHLSTranscodingSuccess, [ 'resolutionPlaylistFile' ])
Expand All @@ -211,6 +214,27 @@ export class RunnerJobsCommand extends AbstractCommand {
})
}

uploadTranscodeResult (options: RunnerJobSuccessBody & { uploadResultUrl: UploadUrlTransodingResultPayload, file: string }) {
const { uploadResultUrl, file } = options
const parsedUrl = new URL(uploadResultUrl.url)
const attaches: { [id: string]: any } = {
file
}

return this.postUploadRequest({
url: parsedUrl.origin,
path: parsedUrl.pathname,
fields: {
...uploadResultUrl.fields,
...pick(options, [ 'jobToken', 'runnerToken' ]),
file
},
attaches,
implicitToken: false,
defaultExpectedStatus: HttpStatusCode.NO_CONTENT_204
})
}

getJobFile (options: OverrideCommandOptions & { url: string, jobToken: string, runnerToken: string }) {
const { host, protocol, pathname } = new URL(options.url)

Expand Down

0 comments on commit 29af130

Please sign in to comment.