Skip to content

Commit

Permalink
Merge pull request #561 from YangSen-qn/resume-check-ctx-expire
Browse files Browse the repository at this point in the history
Resume check ctx expire
  • Loading branch information
bachue authored Oct 25, 2022
2 parents 701a4e3 + 870186c commit cf2ea94
Show file tree
Hide file tree
Showing 11 changed files with 110 additions and 27 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
# Changelog
## 7.12.0(2022-10-25)
* 增加亚太-首尔区域固定 Region
* 移除雾存储区域:华东一区
* 升级 gson 版本至 2.8.9
* 表单上传支持主备域名
* 优化私有云使用姿势,不再单独配置 rs api uc域名
* 优化分片上传 ctx 超时检测

## 7.11.0(2022-06-08)
* 对象存储,管理类 API 发送请求时增加 [X-Qiniu-Date](https://developer.qiniu.com/kodo/3924/common-request-headers) (生成请求的时间) header
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>[7.11.0, 7.11.99]</version>
<version>[7.12.0, 7.12.99]</version>
</dependency>
```
或者 Gradle:
```groovy
compile 'com.qiniu:qiniu-java-sdk:7.11.+'
compile 'com.qiniu:qiniu-java-sdk:7.12.+'
```

## 运行环境
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/qiniu/common/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public final class Constants {
/**
* 版本号
*/
public static final String VERSION = "7.11.0";
public static final String VERSION = "7.12.0";
/**
* 块大小,不能改变
*/
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/com/qiniu/http/Response.java
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,11 @@ public boolean isServerError() {
return (statusCode >= 500 && statusCode < 600 && statusCode != 579) || statusCode == 996;
}

public boolean isContextExpiredError() {
return statusCode == 701 || (statusCode == 612 && error.contains("no such uploadId"));
}


public boolean needSwitchServer() {
return isNetworkBroken() || (statusCode >= 500 && statusCode < 600 && statusCode != 579);
}
Expand Down
36 changes: 26 additions & 10 deletions src/main/java/com/qiniu/storage/BaseUploader.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,38 @@ public Response upload() throws QiniuException {

private Response uploadWithRegionRetry() throws QiniuException {
Response response = null;
QiniuException exception = null;
while (true) {
response = null;
exception = null;

try {
response = uploadFlows();
if (!Retry.shouldSwitchRegionAndRetry(response, null)
|| !couldReloadSource() || !reloadSource()
|| config.region == null || !config.region.switchRegion(new UploadToken(upToken))) {
break;
}
} catch (QiniuException e) {
if (!Retry.shouldSwitchRegionAndRetry(null, e)
|| !couldReloadSource() || !reloadSource()
|| config.region == null || !config.region.switchRegion(new UploadToken(upToken))) {
throw e;
}
exception = e;
}

if (!Retry.shouldUploadAgain(response, exception)
|| !couldReloadSource() || !reloadSource()) {
break;
}

// context 过期,不需要切换 region
if (response != null && response.isContextExpiredError() ||
exception != null && exception.response != null && exception.response.isContextExpiredError()) {
continue;
}

// 切换 region
if (config.region == null || !config.region.switchRegion(new UploadToken(upToken))) {
break;
}
}

if (exception != null) {
throw exception;
}

return response;
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/qiniu/storage/FormUploader.java
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ private void asyncRetryUploadBetweenRegion(final UpCompletionHandler handler) {
asyncRetryUploadBetweenHosts(0, new UpCompletionHandler() {
@Override
public void complete(String key, Response r) {
if (!Retry.shouldSwitchRegionAndRetry(r, null)
if (!Retry.shouldUploadAgain(r, null)
|| !couldReloadSource() || !reloadSource()
|| config.region == null || !config.region.switchRegion(finalToken)) {
handler.complete(key, r);
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/com/qiniu/storage/ResumeUploadPerformerV1.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ private Response makeBlock(String host, ResumeUploadSource.Block block) throws Q
throw new QiniuException(new Exception("block's ctx is empty"));
}
block.context = ctx;

Long expiredAt = response.getExpiredAt();
if (expiredAt == null) {
throw new QiniuException(new Exception("block's expiredAt is empty"));
}
block.expiredAt = expiredAt;

block.data = null;
}

Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/qiniu/storage/ResumeUploadSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,10 @@ static class Block {

// context: 块上传上下文信息 【resume v1 特有】
String context;

// expiredAt: 上传有效期 【resume v1 特有】
long expiredAt;

// etag: 块etag【resume v2 特有】
String etag;

Expand Down
24 changes: 20 additions & 4 deletions src/main/java/com/qiniu/storage/ResumeUploadSourceFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,29 @@ boolean recoverFromRecordInfo(ResumeUploadSource source) {
}

boolean needRecovered = true;
if (source.resumableUploadAPIVersion == Configuration.ResumableUploadAPIVersion.V2) {

long currentTimestamp = new Date().getTime() / 1000;
if (source.resumableUploadAPIVersion == Configuration.ResumableUploadAPIVersion.V1) {
if (source.blockList == null || source.blockList.size() == 0) {
return false;
}

for (int i = 0; i < source.blockList.size(); i++) {
Block block = source.blockList.get(i);
// 服务端是 7 天,此处有效期少 2h
long expireAtTimestamp = block.expiredAt - 2 * 3600;
needRecovered = expireAtTimestamp > currentTimestamp;
if (!needRecovered) {
break;
}
}
} else if (source.resumableUploadAPIVersion == Configuration.ResumableUploadAPIVersion.V2) {
if (StringUtils.isNullOrEmpty(source.uploadId)) {
return false;
}
// 服务端是 7 天,此处有效期少 1 天,为 6 天
long currentTimestamp = new Date().getTime() / 1000;
long expireAtTimestamp = source.expireAt - 24 * 3600;

// 服务端是 7 天,此处有效期少 2h
long expireAtTimestamp = source.expireAt - 2 * 3600;
needRecovered = expireAtTimestamp > currentTimestamp;
}

Expand Down
5 changes: 2 additions & 3 deletions src/main/java/com/qiniu/storage/ResumeUploader.java
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public Response upload() throws QiniuException {
try {
recoverUploadProgressFromLocal();
Response response = super.upload();
if (response != null && response.isOK()) {
if (response != null && (response.isOK() || response.isContextExpiredError())) {
removeUploadProgressFromLocal();
}
return response;
Expand Down Expand Up @@ -278,8 +278,7 @@ void recoverUploadProgressFromLocal() {
return;
}

boolean isCopy = source.recoverFromRecordInfo(uploadSource);
if (!isCopy) {
if (!source.recoverFromRecordInfo(uploadSource)) {
removeUploadProgressFromLocal();
return;
}
Expand Down
41 changes: 35 additions & 6 deletions src/main/java/com/qiniu/storage/Retry.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

class Retry {

static boolean shouldSwitchRegionAndRetry(Response response, QiniuException exception) {
static boolean shouldUploadAgain(Response response, QiniuException exception) {
Response checkResponse = response;
if (checkResponse == null && exception != null) {
checkResponse = exception.response;
Expand All @@ -23,19 +23,41 @@ static boolean shouldSwitchRegionAndRetry(Response response, QiniuException exce
}

static Boolean requestShouldRetry(Response response, QiniuException exception) {
if (exception != null && !exception.isUnrecoverable() && (exception.response == null || exception.response.needRetry())) {
if (response != null && response.needRetry()) {
return true;
}

if (exception == null || exception.isUnrecoverable()) {
return false;
}

if (exception.response != null && exception.response.needRetry()) {
// 异常需可恢复
return true;
}
return response == null || response.needRetry();

return false;
}

static Boolean requestShouldSwitchHost(Response response, QiniuException exception) {
if (exception != null && !exception.isUnrecoverable() && (exception.response == null || exception.response.needSwitchServer())) {
if (response != null && response.needSwitchServer()) {
return true;
}

if (exception == null) {
return true;
}

if (exception.isUnrecoverable()) {
return false;
}

if (exception.response == null || exception.response.needSwitchServer()) {
// 异常需可恢复
return true;
}
return response == null || response.needSwitchServer();

return false;
}

static Response retryRequestAction(RequestRetryConfig config, RequestRetryAction action) throws QiniuException {
Expand All @@ -48,12 +70,15 @@ static Response retryRequestAction(RequestRetryConfig config, RequestRetryAction
}

Response response = null;
QiniuException exception = null;

int retryCount = 0;

do {
boolean shouldSwitchHost = false;
boolean shouldRetry = false;
QiniuException exception = null;

exception = null;
String host = action.getRequestHost();
try {
response = action.doRequest(host);
Expand Down Expand Up @@ -90,6 +115,10 @@ static Response retryRequestAction(RequestRetryConfig config, RequestRetryAction

} while (true);

if (exception != null) {
throw exception;
}

return response;
}

Expand Down

0 comments on commit cf2ea94

Please sign in to comment.