Skip to content

Commit 3012014

Browse files
authored
优化缓存调用逻辑 (#512)
1 parent 71b1482 commit 3012014

File tree

4 files changed

+64
-37
lines changed

4 files changed

+64
-37
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "qiniu-js",
33
"jsName": "qiniu",
4-
"version": "3.2.0",
4+
"version": "3.3.0",
55
"private": false,
66
"description": "Javascript SDK for Qiniu Resource (Cloud) Storage AP",
77
"main": "lib/index.js",
@@ -43,7 +43,7 @@
4343
"@babel/plugin-proposal-object-rest-spread": "^7.10.1",
4444
"@babel/plugin-transform-runtime": "^7.10.1",
4545
"@babel/preset-env": "^7.10.2",
46-
"@qiniu/eslint-config": "0.0.6-beta.7",
46+
"@qiniu/eslint-config": "^0.0.6-beta.7",
4747
"@types/jest": "^26.0.23",
4848
"@types/node": "^15.3.1",
4949
"@types/spark-md5": "^3.0.2",

src/upload/base.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,8 +330,8 @@ export default abstract class Base {
330330
return {
331331
size,
332332
loaded,
333-
fromCache,
334-
percent: loaded / size * 100
333+
percent: loaded / size * 100,
334+
...(fromCache == null ? {} : { fromCache })
335335
}
336336
}
337337
}

src/upload/index.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ describe('test upload', () => {
3737
})
3838

3939
test('base Direct.', async () => {
40-
// 文件小于等于 4M 使用直传
40+
// 文件小于 4M 使用直传
4141
const result1 = await observablePromisify(upload(File3M, null, testToken))
4242
expect(result1).toStrictEqual((await mockApi.direct()).data)
4343

@@ -58,7 +58,7 @@ describe('test upload', () => {
5858
})
5959

6060
test('Resume: base.', async () => {
61-
// 文件大于等于 4M 使用分片
61+
// 文件大于 4M 使用分片
6262
const result = await observablePromisify(upload(File5M, null, testToken))
6363
expect(result).toStrictEqual((await mockApi.uploadComplete()).data)
6464
})

src/upload/resume.ts

Lines changed: 58 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ import Base, { Progress, UploadInfo, Extra } from './base'
66

77
export interface UploadedChunkStorage extends UploadChunkData {
88
size: number
9-
10-
fromCache?: boolean
119
}
1210

1311
export interface ChunkLoaded {
@@ -41,11 +39,34 @@ function isPositiveInteger(n: number) {
4139
}
4240

4341
export default class Resume extends Base {
42+
/**
43+
* @description 文件的分片 chunks
44+
*/
4445
private chunks: Blob[]
45-
/** 当前上传过程中已完成的上传信息 */
46+
47+
/**
48+
* @description 使用缓存的 chunks
49+
*/
50+
private usedCacheList: boolean[]
51+
52+
/**
53+
* @description 来自缓存的上传信息
54+
*/
55+
private cachedUploadedList: UploadedChunkStorage[]
56+
57+
/**
58+
* @description 当前上传过程中已完成的上传信息
59+
*/
4660
private uploadedList: UploadedChunkStorage[]
47-
/** 当前上传片进度信息 */
61+
62+
/**
63+
* @description 当前上传片进度信息
64+
*/
4865
private loaded: ChunkLoaded
66+
67+
/**
68+
* @description 当前上传任务的 id
69+
*/
4970
private uploadId: string
5071

5172
/**
@@ -98,33 +119,33 @@ export default class Resume extends Base {
98119

99120
private async uploadChunk(chunkInfo: ChunkInfo) {
100121
const { index, chunk } = chunkInfo
101-
const info = this.uploadedList[index]
102-
this.logger.info(`upload part ${index}.`, info)
122+
const cachedInfo = this.cachedUploadedList[index]
123+
this.logger.info(`upload part ${index}, cache:`, cachedInfo)
103124

104125
const shouldCheckMD5 = this.config.checkByMD5
105126
const reuseSaved = () => {
106-
info.fromCache = true
127+
this.usedCacheList[index] = true
107128
this.updateChunkProgress(chunk.size, index)
129+
this.uploadedList[index] = cachedInfo
130+
this.updateLocalCache()
108131
}
109132

110133
// FIXME: 至少判断一下 size
111-
if (info && !shouldCheckMD5) {
134+
if (cachedInfo && !shouldCheckMD5) {
112135
reuseSaved()
113136
return
114137
}
115138

116139
const md5 = await utils.computeMd5(chunk)
117140
this.logger.info('computed part md5.', md5)
118141

119-
if (info && md5 === info.md5) {
142+
if (cachedInfo && md5 === cachedInfo.md5) {
120143
reuseSaved()
121144
return
122145
}
123146

124-
// 有缓存但是没有使用则调整标记
125-
if (info) {
126-
info.fromCache = false
127-
}
147+
// 没有使用缓存设置标记为 false
148+
this.usedCacheList[index] = false
128149

129150
const onProgress = (data: Progress) => {
130151
this.updateChunkProgress(data.loaded, index)
@@ -158,16 +179,14 @@ export default class Resume extends Base {
158179
size: chunk.size
159180
}
160181

161-
utils.setLocalFileInfo(this.getLocalKey(), {
162-
id: this.uploadId,
163-
data: this.uploadedList
164-
}, this.logger)
182+
this.updateLocalCache()
165183
}
166184

167185
private async mkFileReq() {
168186
const data: UploadChunkBody = {
169187
parts: this.uploadedList.map((value, index) => ({
170188
etag: value.etag,
189+
// 接口要求 index 需要从 1 开始,所以需要整体 + 1
171190
partNumber: index + 1
172191
})),
173192
fname: this.putExtra.fname,
@@ -193,31 +212,33 @@ export default class Resume extends Base {
193212
}
194213

195214
private async initBeforeUploadChunks() {
196-
const localInfo = utils.getLocalFileInfo(this.getLocalKey(), this.logger)
215+
this.uploadedList = []
216+
this.usedCacheList = []
217+
const cachedInfo = utils.getLocalFileInfo(this.getLocalKey(), this.logger)
197218

198219
// 分片必须和当时使用的 uploadId 配套,所以断点续传需要把本地存储的 uploadId 拿出来
199-
// 假如没有 localInfo 本地信息并重新获取 uploadId
200-
if (!localInfo) {
201-
this.logger.info('resume upload parts from api.')
220+
// 假如没有 cachedInfo 本地信息并重新获取 uploadId
221+
if (!cachedInfo) {
222+
this.logger.info('init upload parts from api.')
202223
const res = await initUploadParts(
203224
this.token,
204225
this.bucketName,
205226
this.key,
206227
this.uploadHost!.getUrl()
207228
)
208-
this.logger.info(`resume upload parts of id: ${res.data.uploadId}.`)
229+
this.logger.info(`initd upload parts of id: ${res.data.uploadId}.`)
209230
this.uploadId = res.data.uploadId
210-
this.uploadedList = []
231+
this.cachedUploadedList = []
211232
} else {
212233
const infoMessage = [
213-
'resume upload parts from local cache',
214-
`total ${localInfo.data.length} part`,
215-
`id is ${localInfo.id}.`
234+
'resume upload parts from local cache,',
235+
`total ${cachedInfo.data.length} part,`,
236+
`id is ${cachedInfo.id}.`
216237
]
217238

218-
this.logger.info(infoMessage.join(', '))
219-
this.uploadedList = localInfo.data
220-
this.uploadId = localInfo.id
239+
this.logger.info(infoMessage.join(' '))
240+
this.cachedUploadedList = cachedInfo.data
241+
this.uploadId = cachedInfo.id
221242
}
222243

223244
this.chunks = utils.getChunks(this.file, this.config.chunkSize)
@@ -239,6 +260,13 @@ export default class Resume extends Base {
239260
return utils.createLocalKey(this.file.name, this.key, this.file.size)
240261
}
241262

263+
private updateLocalCache() {
264+
utils.setLocalFileInfo(this.getLocalKey(), {
265+
id: this.uploadId,
266+
data: this.uploadedList
267+
}, this.logger)
268+
}
269+
242270
private updateChunkProgress(loaded: number, index: number) {
243271
this.loaded.chunks[index] = loaded
244272
this.notifyResumeProgress()
@@ -257,8 +285,7 @@ export default class Resume extends Base {
257285
this.file.size + 1 // 防止在 complete 未调用的时候进度显示 100%
258286
),
259287
chunks: this.chunks.map((chunk, index) => {
260-
const info = this.uploadedList[index]
261-
const fromCache = info && info.fromCache
288+
const fromCache = this.usedCacheList[index]
262289
return this.getProgressInfoItem(this.loaded.chunks[index], chunk.size, fromCache)
263290
}),
264291
uploadInfo: {

0 commit comments

Comments
 (0)