Skip to content

Commit 5495244

Browse files
committed
cache UploadId
1 parent 11b942a commit 5495244

File tree

7 files changed

+299
-84
lines changed

7 files changed

+299
-84
lines changed

demo/demo.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ var getAuthorization = function (options, callback) {
8181
};
8282

8383
var cos = new COS({
84-
UploadIdCacheLimit: 3,
8584
getAuthorization: getAuthorization,
8685
});
8786
var TaskId;

dist/cos-js-sdk-v5.js

Lines changed: 149 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,16 @@ function extend(target, source) {
237237
function isArray(arr) {
238238
return arr instanceof Array;
239239
}
240+
function isInArray(arr, item) {
241+
var flag = false;
242+
for (var i = 0; i < arr.length; i++) {
243+
if (item === arr[i]) {
244+
flag = true;
245+
break;
246+
}
247+
}
248+
return flag;
249+
}
240250
function each(obj, fn) {
241251
for (var i in obj) {
242252
if (obj.hasOwnProperty(i)) {
@@ -464,6 +474,7 @@ var util = {
464474
binaryBase64: binaryBase64,
465475
extend: extend,
466476
isArray: isArray,
477+
isInArray: isInArray,
467478
each: each,
468479
map: map,
469480
filter: filter,
@@ -1461,7 +1472,7 @@ var initTask = function (cos) {
14611472
return;
14621473
}
14631474
task.state = switchToState;
1464-
cos.emit('inner-kill-task', { TaskId: id });
1475+
cos.emit('inner-kill-task', { TaskId: id, toState: switchToState });
14651476
emitListUpdate();
14661477
if (running) {
14671478
uploadingFileCount--;
@@ -8035,28 +8046,36 @@ function sliceUploadFile(params, callback) {
80358046
});
80368047

80378048
// 上传分块完成,开始 uploadSliceComplete 操作
8038-
ep.on('upload_slice_complete', function (data) {
8049+
ep.on('upload_slice_complete', function (UploadData) {
80398050
uploadSliceComplete.call(self, {
80408051
Bucket: Bucket,
80418052
Region: Region,
80428053
Key: Key,
8043-
UploadId: data.UploadId,
8044-
SliceList: data.SliceList
8054+
UploadId: UploadData.UploadId,
8055+
SliceList: UploadData.SliceList
80458056
}, function (err, data) {
80468057
if (!self._isRunningTask(TaskId)) return;
8058+
delete uploadIdUsing[UploadData.UploadId];
80478059
if (err) {
80488060
return ep.emit('error', err);
80498061
}
8062+
removeUploadId.call(self, UploadData.UploadId);
80508063
ep.emit('upload_complete', data);
80518064
});
80528065
});
80538066

80548067
// 获取 UploadId 完成,开始上传每个分片
80558068
ep.on('get_upload_data_finish', function (UploadData) {
8056-
if (UploadData.UploadId) {
8057-
var uuid = getFileUuid(Body, params.ChunkSize);
8058-
uuid && setUploadId.call(self, uuid, UploadData.UploadId);
8059-
}
8069+
8070+
// 处理 UploadId 缓存
8071+
var uuid = getFileUuid(Body, params.ChunkSize);
8072+
uuid && setUploadId.call(self, uuid, UploadData.UploadId); // 缓存 UploadId
8073+
uploadIdUsing[UploadData.UploadId] = true; // 标记 UploadId 为正在使用
8074+
TaskId && self.on('inner-kill-task', function (data) {
8075+
if (data.TaskId === TaskId && data.toState === 'canceled') {
8076+
delete uploadIdUsing[UploadData.UploadId]; // 去除 UploadId 正在使用的标记
8077+
}
8078+
});
80608079

80618080
// 获取 UploadId
80628081
uploadSliceList.call(self, {
@@ -8126,6 +8145,7 @@ function sliceUploadFile(params, callback) {
81268145
params.ChunkSize = params.SliceSize = ChunkSize = Math.max(ChunkSize, AutoChunkSize);
81278146
})();
81288147

8148+
// 开始上传
81298149
if (FileSize === 0) {
81308150
params.Body = '';
81318151
self.putObject(params, callback);
@@ -8135,14 +8155,26 @@ function sliceUploadFile(params, callback) {
81358155
}
81368156

81378157
// 按照文件特征值,缓存 UploadId
8158+
var uploadIdCache;
8159+
var uploadIdUsing = {};
81388160
var uploadIdCacheKey = 'cos_sdk_upload_cache';
8139-
var uploadIdCache = [];
8140-
try {
8141-
uploadIdCache = JSON.parse(localStorage.getItem(uploadIdCacheKey)) || [];
8142-
} catch (e) {}
8143-
function setUploadId(uuid, UploadId) {
8161+
function initUploadId() {
8162+
var cacheLimit = this.options.UploadIdCacheLimit;
8163+
if (!uploadIdCache) {
8164+
if (cacheLimit) {
8165+
try {
8166+
uploadIdCache = JSON.parse(localStorage.getItem(uploadIdCacheKey)) || [];
8167+
} catch (e) {}
8168+
}
8169+
if (!uploadIdCache) {
8170+
uploadIdCache = [];
8171+
}
8172+
}
8173+
}
8174+
function setUploadId(uuid, UploadId, isDisabled) {
8175+
initUploadId.call(this);
81448176
for (var i = uploadIdCache.length - 1; i >= 0; i--) {
8145-
if (uploadIdCache[i][0] === uuid) {
8177+
if (uploadIdCache[i][0] === uuid && uploadIdCache[i][1] === UploadId) {
81468178
uploadIdCache.splice(i, 1);
81478179
}
81488180
}
@@ -8157,15 +8189,37 @@ function setUploadId(uuid, UploadId) {
81578189
} catch (e) {}
81588190
});
81598191
}
8192+
function removeUploadId(UploadId) {
8193+
initUploadId.call(this);
8194+
delete uploadIdUsing[UploadId];
8195+
for (var i = uploadIdCache.length - 1; i >= 0; i--) {
8196+
if (uploadIdCache[i][1] === UploadId) {
8197+
uploadIdCache.splice(i, 1);
8198+
}
8199+
}
8200+
var cacheLimit = this.options.UploadIdCacheLimit;
8201+
if (uploadIdCache.length > cacheLimit) {
8202+
uploadIdCache.splice(cacheLimit);
8203+
}
8204+
cacheLimit && setTimeout(function () {
8205+
try {
8206+
if (uploadIdCache.length) {
8207+
localStorage.setItem(uploadIdCacheKey, JSON.stringify(uploadIdCache));
8208+
} else {
8209+
localStorage.removeItem(uploadIdCacheKey);
8210+
}
8211+
} catch (e) {}
8212+
});
8213+
}
81608214
function getUploadId(uuid) {
8161-
var UploadId;
8215+
initUploadId.call(this);
8216+
var CacheUploadIdList = [];
81628217
for (var i = 0; i < uploadIdCache.length; i++) {
81638218
if (uploadIdCache[i][0] === uuid) {
8164-
UploadId = uploadIdCache[i][1];
8165-
break;
8219+
CacheUploadIdList.push(uploadIdCache[i][1]);
81668220
}
81678221
}
8168-
return UploadId;
8222+
return CacheUploadIdList.length ? CacheUploadIdList : null;
81698223
}
81708224
function getFileUuid(file, ChunkSize) {
81718225
// 如果信息不完整,不获取
@@ -8318,14 +8372,23 @@ function getUploadIdAndPartList(params, callback) {
83188372
UploadIdList = UploadIdList.reverse();
83198373
Async.eachLimit(UploadIdList, 1, function (UploadId, asyncCallback) {
83208374
if (!self._isRunningTask(TaskId)) return;
8375+
// 如果正在上传,跳过
8376+
if (uploadIdUsing[UploadId]) {
8377+
asyncCallback(); // 检查下一个 UploadId
8378+
return;
8379+
}
8380+
// 判断 UploadId 是否可用
83218381
wholeMultipartListPart.call(self, {
83228382
Bucket: Bucket,
83238383
Region: Region,
83248384
Key: Key,
83258385
UploadId: UploadId
83268386
}, function (err, PartListData) {
83278387
if (!self._isRunningTask(TaskId)) return;
8328-
if (err) return ep.emit('error', err);
8388+
if (err) {
8389+
removeUploadId.call(self, UploadId);
8390+
return ep.emit('error', err);
8391+
}
83298392
var PartList = PartListData.PartList;
83308393
PartList.forEach(function (item) {
83318394
item.PartNumber *= 1;
@@ -8356,24 +8419,58 @@ function getUploadIdAndPartList(params, callback) {
83568419
});
83578420
});
83588421

8359-
// 获取缓存的 UploadId
8360-
var uuid = getFileUuid(params.Body, params.ChunkSize),
8361-
UploadId;
8362-
if (uuid && (UploadId = getUploadId(uuid))) {
8363-
wholeMultipartListPart.call(self, {
8364-
Bucket: Bucket,
8365-
Region: Region,
8366-
Key: Key,
8367-
UploadId: UploadId
8368-
}, function (err, PartListData) {
8369-
if (!self._isRunningTask(TaskId)) return;
8370-
if (err) return ep.emit('error', err);
8371-
ep.emit('upload_id_ready', {
8372-
UploadId: UploadId,
8373-
PartList: PartListData.PartList
8374-
});
8375-
});
8376-
} else {
8422+
// 在本地缓存找可用的 UploadId
8423+
ep.on('seek_local_avail_upload_id', function (RemoteUploadIdList) {
8424+
// 在本地找可用的 UploadId
8425+
var uuid = getFileUuid(params.Body, params.ChunkSize),
8426+
LocalUploadIdList;
8427+
if (uuid && (LocalUploadIdList = getUploadId.call(self, uuid))) {
8428+
var next = function (index) {
8429+
// 如果找不到,到线上列出 UploadId
8430+
if (index >= LocalUploadIdList.length) {
8431+
ep.emit('has_upload_id', RemoteUploadIdList);
8432+
return;
8433+
}
8434+
var UploadId = LocalUploadIdList[index];
8435+
// 如果不在远端 UploadId 列表里,跳过并删除
8436+
if (!util.isInArray(RemoteUploadIdList, UploadId)) {
8437+
removeUploadId.call(self, UploadId);
8438+
next(index + 1);
8439+
return;
8440+
}
8441+
// 如果正在上传,跳过
8442+
if (uploadIdUsing[UploadId]) {
8443+
next(index + 1);
8444+
return;
8445+
}
8446+
// 判断 UploadId 是否存在线上
8447+
wholeMultipartListPart.call(self, {
8448+
Bucket: Bucket,
8449+
Region: Region,
8450+
Key: Key,
8451+
UploadId: UploadId
8452+
}, function (err, PartListData) {
8453+
if (!self._isRunningTask(TaskId)) return;
8454+
if (err) {
8455+
removeUploadId.call(self, UploadId);
8456+
next(index + 1);
8457+
} else {
8458+
// 找到可用 UploadId
8459+
ep.emit('upload_id_ready', {
8460+
UploadId: UploadId,
8461+
PartList: PartListData.PartList
8462+
});
8463+
}
8464+
});
8465+
};
8466+
next(0);
8467+
} else {
8468+
ep.emit('has_upload_id', RemoteUploadIdList);
8469+
}
8470+
});
8471+
8472+
// 获取线上 UploadId 列表
8473+
ep.on('get_remote_upload_id_list', function (RemoteUploadIdList) {
83778474
// 获取符合条件的 UploadId 列表,因为同一个文件可以有多个上传任务。
83788475
wholeMultipartList.call(self, {
83798476
Bucket: Bucket,
@@ -8384,18 +8481,29 @@ function getUploadIdAndPartList(params, callback) {
83848481
if (err) {
83858482
return ep.emit('error', err);
83868483
}
8387-
var UploadIdList = data.UploadList.filter(function (item) {
8484+
// 整理远端 UploadId 列表
8485+
var RemoteUploadIdList = data.UploadList.filter(function (item) {
83888486
return item.Key === Key && (!StorageClass || item.StorageClass.toUpperCase() === StorageClass.toUpperCase());
83898487
}).reverse().map(function (item) {
83908488
return item.UploadId || item.UploadID;
83918489
});
8392-
if (UploadIdList.length) {
8393-
ep.emit('has_upload_id', UploadIdList);
8490+
if (RemoteUploadIdList.length) {
8491+
ep.emit('seek_local_avail_upload_id', RemoteUploadIdList);
83948492
} else {
8493+
var uuid = getFileUuid(params.Body, params.ChunkSize),
8494+
LocalUploadIdList;
8495+
if (uuid && (LocalUploadIdList = getUploadId.call(self, uuid))) {
8496+
util.each(LocalUploadIdList, function (UploadId) {
8497+
removeUploadId.call(self, UploadId);
8498+
});
8499+
}
83958500
ep.emit('no_available_upload_id');
83968501
}
83978502
});
8398-
}
8503+
});
8504+
8505+
// 开始找可用 UploadId
8506+
ep.emit('get_remote_upload_id_list');
83998507
}
84008508

84018509
// 获取符合条件的全部上传任务 (条件包括 Bucket, Region, Prefix)

dist/cos-js-sdk-v5.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/sts.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ function getTempKeys() {
5151
array(
5252
'action'=> array(
5353
// // 这里可以从临时密钥的权限上控制前端允许的操作
54-
// 'name/cos:*', // 这样写可以包含下面所有权限
54+
'name/cos:*', // 这样写可以包含下面所有权限
5555

5656
// // 列出所有允许的操作
5757
// // ACL 读写

0 commit comments

Comments
 (0)