Skip to content

Commit e935279

Browse files
author
jeffreykzli
committed
refresh L5 retry
1 parent 22daa14 commit e935279

File tree

5 files changed

+371
-0
lines changed

5 files changed

+371
-0
lines changed

src/main/java/com/qcloud/cos/ClientConfig.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import com.qcloud.cos.endpoint.EndpointResolver;
2525
import com.qcloud.cos.endpoint.RegionEndpointBuilder;
2626
import com.qcloud.cos.endpoint.SuffixEndpointBuilder;
27+
import com.qcloud.cos.http.DefaultHandlerAfterProcess;
28+
import com.qcloud.cos.http.HandlerAfterProcess;
2729
import com.qcloud.cos.http.HttpProtocol;
2830
import com.qcloud.cos.region.Region;
2931
import com.qcloud.cos.retry.BackoffStrategy;
@@ -121,6 +123,10 @@ public class ClientConfig {
121123

122124
private boolean useDefaultDnsResolver = true;
123125

126+
private HandlerAfterProcess handlerAfterProcess = new DefaultHandlerAfterProcess();
127+
128+
private boolean isRefreshEndpointAddr = false;
129+
124130
// 不传入region 用于后续调用List Buckets(获取所有的bucket信息)
125131
public ClientConfig() {
126132
super();
@@ -429,4 +435,20 @@ public void setUseDefaultDnsResolver(boolean useDefaultDnsResolver) {
429435
public boolean isUseDefaultDnsResolver() {
430436
return useDefaultDnsResolver;
431437
}
438+
439+
public void setHandlerAfterProcess(HandlerAfterProcess handler) {
440+
this.handlerAfterProcess = handler;
441+
}
442+
443+
public HandlerAfterProcess getHandlerAfterProcess() {
444+
return handlerAfterProcess;
445+
}
446+
447+
public void turnOnRefreshEndpointAddrSwitch() {
448+
isRefreshEndpointAddr = true;
449+
}
450+
451+
public boolean IsRefreshEndpointAddr() {
452+
return isRefreshEndpointAddr;
453+
}
432454
}

src/main/java/com/qcloud/cos/http/DefaultCosHttpClient.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,11 @@
4848
import com.qcloud.cos.Headers;
4949
import com.qcloud.cos.auth.COSCredentials;
5050
import com.qcloud.cos.auth.COSSigner;
51+
import com.qcloud.cos.endpoint.CIRegionEndpointBuilder;
52+
import com.qcloud.cos.endpoint.CIPicRegionEndpointBuilder;
5153
import com.qcloud.cos.internal.cihandler.HttpEntityEnclosingDelete;
54+
import com.qcloud.cos.internal.CIPicServiceRequest;
55+
import com.qcloud.cos.model.ListBucketsRequest;
5256
import com.qcloud.cos.region.Region;
5357
import com.qcloud.cos.event.ProgressInputStream;
5458
import com.qcloud.cos.event.ProgressListener;
@@ -119,12 +123,14 @@ public class DefaultCosHttpClient implements CosHttpClient {
119123
private BackoffStrategy backoffStrategy;
120124

121125
private CosErrorResponseHandler errorResponseHandler;
126+
private HandlerAfterProcess handlerAfterProcess;
122127
private static final Logger log = LoggerFactory.getLogger(DefaultCosHttpClient.class);
123128

124129
public DefaultCosHttpClient(ClientConfig clientConfig) {
125130
super();
126131
this.errorResponseHandler = new CosErrorResponseHandler();
127132
this.clientConfig = clientConfig;
133+
this.handlerAfterProcess = clientConfig.getHandlerAfterProcess();
128134
DnsResolver dnsResolver = new DnsResolver() {
129135
@Override
130136
public InetAddress[] resolve(String host) throws UnknownHostException {
@@ -557,6 +563,10 @@ public <X, Y extends CosServiceRequest> X exeute(CosHttpRequest<Y> request,
557563
originalContent.mark(readLimit);
558564
}
559565

566+
long startTime = 0;
567+
long endTime = 0;
568+
int response_status = 0;
569+
560570
int retryIndex = 0;
561571
while (true) {
562572
try {
@@ -573,17 +583,24 @@ public <X, Y extends CosServiceRequest> X exeute(CosHttpRequest<Y> request,
573583
originalContent.reset();
574584
}
575585
if (retryIndex != 0) {
586+
response_status = 0;
587+
if (clientConfig.IsRefreshEndpointAddr()) {
588+
refreshEndpointAddr(request);
589+
}
590+
576591
long delay = backoffStrategy.computeDelayBeforeNextRetry(retryIndex);
577592
request.addHeader("x-cos-sdk-retry", "true");
578593
Thread.sleep(delay);
579594
}
580595
HttpContext context = HttpClientContext.create();
581596
httpRequest = buildHttpRequest(request);
582597
httpResponse = null;
598+
startTime = System.currentTimeMillis();
583599
httpResponse = executeRequest(context, httpRequest);
584600
checkResponse(request, httpRequest, httpResponse);
585601
break;
586602
} catch (CosServiceException cse) {
603+
response_status = -1;
587604
closeHttpResponseStream(httpResponse);
588605
String errorMsg = String.format("failed to execute http request due to service exception, request timeStamp %d,"
589606
+ " httpRequest: %s, retryIdx:%d, maxErrorRetry:%d", System.currentTimeMillis(), request,
@@ -601,6 +618,7 @@ public <X, Y extends CosServiceRequest> X exeute(CosHttpRequest<Y> request,
601618
}
602619
changeEndpointForRetry(request, httpResponse, retryIndex);
603620
} catch (CosClientException cce) {
621+
response_status = -1;
604622
closeHttpResponseStream(httpResponse);
605623
String errorMsg = String.format("failed to execute http request due to client exception, request timeStamp %d,"
606624
+ " httpRequest: %s, retryIdx:%d, maxErrorRetry:%d", System.currentTimeMillis(), request,
@@ -612,12 +630,15 @@ public <X, Y extends CosServiceRequest> X exeute(CosHttpRequest<Y> request,
612630
}
613631
changeEndpointForRetry(request, httpResponse, retryIndex);
614632
} catch (Exception exp) {
633+
response_status = -1;
615634
String expName = exp.getClass().getName();
616635
String errorMsg = String.format("httpClient execute occur an unknown exception:%s, httpRequest: %s", expName, request);
617636
closeHttpResponseStream(httpResponse);
618637
log.error(errorMsg, exp);
619638
throw new CosClientException(errorMsg, exp);
620639
} finally {
640+
endTime = System.currentTimeMillis();
641+
handlerAfterProcess.handle(response_status, endTime - startTime);
621642
++retryIndex;
622643
}
623644
}
@@ -766,4 +787,41 @@ private <Y extends CosServiceRequest> void changeEndpointForRetry(CosHttpRequest
766787
}
767788
}
768789
}
790+
791+
private <X extends CosServiceRequest> void refreshEndpointAddr(CosHttpRequest<X> request) throws CosClientException {
792+
boolean isCIRequest = request.getOriginalRequest() instanceof CIServiceRequest;
793+
boolean isServiceRequest = request.getOriginalRequest() instanceof ListBucketsRequest;
794+
String endpoint = "";
795+
String endpointAddr = "";
796+
if (isServiceRequest) {
797+
endpoint = clientConfig.getEndpointBuilder().buildGetServiceApiEndpoint();
798+
endpointAddr =
799+
clientConfig.getEndpointResolver().resolveGetServiceApiEndpoint(endpoint);
800+
} else {
801+
802+
if (request.getOriginalRequest() instanceof CIPicServiceRequest) {
803+
endpoint = new CIPicRegionEndpointBuilder(clientConfig.getRegion()).buildGeneralApiEndpoint(request.getBucketName());
804+
} else if (isCIRequest) {
805+
endpoint = new CIRegionEndpointBuilder(clientConfig.getRegion()).buildGeneralApiEndpoint(request.getBucketName());
806+
} else {
807+
endpoint = clientConfig.getEndpointBuilder().buildGeneralApiEndpoint(request.getBucketName());
808+
}
809+
endpointAddr = clientConfig.getEndpointResolver().resolveGeneralApiEndpoint(endpoint);
810+
}
811+
812+
if (endpoint == null) {
813+
throw new CosClientException("endpoint is null, please check your endpoint builder");
814+
}
815+
if (endpointAddr == null) {
816+
throw new CosClientException(
817+
"endpointAddr is null, please check your endpoint resolver");
818+
}
819+
820+
String fixedEndpointAddr = request.getOriginalRequest().getFixedEndpointAddr();
821+
if (fixedEndpointAddr != null) {
822+
request.setEndpoint(fixedEndpointAddr);
823+
} else {
824+
request.setEndpoint(endpointAddr);
825+
}
826+
}
769827
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.qcloud.cos.http;
2+
3+
public class DefaultHandlerAfterProcess implements HandlerAfterProcess{
4+
@Override
5+
public void handle(int status, long time_cost) {}
6+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.qcloud.cos.http;
2+
3+
public interface HandlerAfterProcess {
4+
public void handle(int status, long time_cost);
5+
}

0 commit comments

Comments
 (0)