From eb3f32922ab9cd2f9fbef4860b93fec759a7054d Mon Sep 17 00:00:00 2001 From: HFO4 <912394456@qq.com> Date: Mon, 28 Feb 2022 17:47:01 +0800 Subject: [PATCH] Feat: send chunk uploading request to slave server --- src/component/Uploader/core/api/index.ts | 34 ++++++++++++++++++- src/component/Uploader/core/errors/index.ts | 16 ++++++++- src/component/Uploader/core/types.ts | 2 ++ src/component/Uploader/core/uploader/local.ts | 4 +-- .../Uploader/core/uploader/remote.ts | 7 ++-- 5 files changed, 56 insertions(+), 7 deletions(-) diff --git a/src/component/Uploader/core/api/index.ts b/src/component/Uploader/core/api/index.ts index e07bd535..cd032bf1 100644 --- a/src/component/Uploader/core/api/index.ts +++ b/src/component/Uploader/core/api/index.ts @@ -4,6 +4,7 @@ import { CreateUploadSessionError, DeleteUploadSessionError, LocalChunkUploadError, + SlaveChunkUploadError, } from "../errors"; import { ChunkInfo } from "../uploader/chunk"; import { Progress } from "../uploader/base"; @@ -38,7 +39,7 @@ export async function deleteUploadSession(id: string): Promise { return res.data.data; } -export async function loadUploadChunk( +export async function localUploadChunk( sessionID: string, chunk: ChunkInfo, onProgress: (p: Progress) => void, @@ -66,3 +67,34 @@ export async function loadUploadChunk( return res.data.data; } + +export async function slaveUploadChunk( + url: string, + credential: string, + chunk: ChunkInfo, + onProgress: (p: Progress) => void, + cancel: CancelToken +): Promise { + const res = await requestAPI(`${url}?chunk=${chunk.index}`, { + method: "post", + headers: { + "content-type": "application/octet-stream", + Authorization: credential, + }, + data: chunk.chunk, + onUploadProgress: (progressEvent) => { + onProgress({ + loaded: progressEvent.loaded, + total: progressEvent.total, + }); + }, + cancelToken: cancel, + withCredentials: false, + }); + + if (res.data.code !== 0) { + throw new SlaveChunkUploadError(res.data, chunk.index); + } + + return res.data.data; +} diff --git a/src/component/Uploader/core/errors/index.ts b/src/component/Uploader/core/errors/index.ts index c4665859..93b9c760 100644 --- a/src/component/Uploader/core/errors/index.ts +++ b/src/component/Uploader/core/errors/index.ts @@ -9,6 +9,7 @@ export enum UploaderErrorName { FailedDeleteUploadSession = "FailedDeleteUploadSession", HTTPRequestFailed = "HTTPRequestFailed", LocalChunkUploadFailed = "LocalChunkUploadFailed", + SlaveChunkUploadFailed = "SlaveChunkUploadFailed", WriteCtxFailed = "WriteCtxFailed", RemoveCtxFailed = "RemoveCtxFailed", ReadCtxFailed = "ReadCtxFailed", @@ -21,6 +22,7 @@ const RETRY_ERROR_LIST = [ UploaderErrorName.FailedCreateUploadSession, UploaderErrorName.HTTPRequestFailed, UploaderErrorName.LocalChunkUploadFailed, + UploaderErrorName.SlaveChunkUploadFailed, UploaderErrorName.RequestCanceled, ]; @@ -142,7 +144,7 @@ export class HTTPError extends UploaderError { } } -// 无法创建上传会话 +// 本地分块上传失败 export class LocalChunkUploadError extends APIError { constructor(response: Response, protected chunkIndex: number) { super(UploaderErrorName.LocalChunkUploadFailed, "", response); @@ -160,3 +162,15 @@ export class RequestCanceledError extends UploaderError { super(UploaderErrorName.RequestCanceled, "Request canceled"); } } + +// 从机分块上传失败 +export class SlaveChunkUploadError extends APIError { + constructor(response: Response, protected chunkIndex: number) { + super(UploaderErrorName.SlaveChunkUploadFailed, "", response); + } + + public Message(i18n: string): string { + this.message = `分片 [${this.chunkIndex}] 上传失败`; + return super.Message(i18n); + } +} diff --git a/src/component/Uploader/core/types.ts b/src/component/Uploader/core/types.ts index b1af5244..f662a71b 100644 --- a/src/component/Uploader/core/types.ts +++ b/src/component/Uploader/core/types.ts @@ -54,4 +54,6 @@ export interface UploadCredential { sessionID: string; expires: number; chunkSize: number; + uploadURLs: string[]; + credential: string; } diff --git a/src/component/Uploader/core/uploader/local.ts b/src/component/Uploader/core/uploader/local.ts index 403370b6..7917d157 100644 --- a/src/component/Uploader/core/uploader/local.ts +++ b/src/component/Uploader/core/uploader/local.ts @@ -1,9 +1,9 @@ import Chunk, { ChunkInfo } from "./chunk"; -import { loadUploadChunk } from "../api"; +import { localUploadChunk } from "../api"; export default class Local extends Chunk { protected async uploadChunk(chunkInfo: ChunkInfo) { - return loadUploadChunk( + return localUploadChunk( this.task.session?.sessionID!, chunkInfo, (p) => { diff --git a/src/component/Uploader/core/uploader/remote.ts b/src/component/Uploader/core/uploader/remote.ts index 1af9cb3c..8f13243b 100644 --- a/src/component/Uploader/core/uploader/remote.ts +++ b/src/component/Uploader/core/uploader/remote.ts @@ -1,10 +1,11 @@ import Chunk, { ChunkInfo } from "./chunk"; -import { loadUploadChunk } from "../api"; +import { slaveUploadChunk } from "../api"; export default class Remote extends Chunk { protected async uploadChunk(chunkInfo: ChunkInfo) { - return loadUploadChunk( - this.task.session?.sessionID!, + return slaveUploadChunk( + `${this.task.session?.uploadURLs[0]!}`, + this.task.session?.credential!, chunkInfo, (p) => { this.updateChunkProgress(p.loaded, chunkInfo.index);