Skip to content

Commit 40dec93

Browse files
committed
feat: add duplicate check for YunxinApiHttpClient init
1 parent 3b5a113 commit 40dec93

File tree

4 files changed

+29
-10
lines changed

4 files changed

+29
-10
lines changed

src/main/java/com/netease/nim/im/server/sdk/core/YunxinApiHttpClient.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,15 @@
1212
import com.netease.nim.im.server.sdk.core.trace.ApiVersion;
1313

1414
import java.util.Map;
15+
import java.util.concurrent.ConcurrentHashMap;
1516

1617
/**
1718
* Created by caojiajun on 2024/12/9
1819
*/
1920
public class YunxinApiHttpClient {
2021

22+
private static final ConcurrentHashMap<String, YunxinApiHttpClient> clientMap = new ConcurrentHashMap<>();
23+
2124
private final YunxinHttpClient httpClient;
2225

2326
private YunxinApiHttpClient(String appkey, String appsecret, EndpointConfig endpointConfig,
@@ -37,6 +40,11 @@ public static class Builder {
3740
public Builder(String appkey, String appsecret) {
3841
this.appkey = appkey;
3942
this.appsecret = appsecret;
43+
String cacheKey = appkey + "/" + appsecret;
44+
YunxinApiHttpClient client = clientMap.get(cacheKey);
45+
if (client != null) {
46+
throw new IllegalStateException("YunxinApiHttpClient with appkey = [" + appkey + "] duplicate init");
47+
}
4048
}
4149

4250
public Builder retryPolicy(RetryPolicy retryPolicy) {
@@ -105,11 +113,18 @@ public Builder region(Region region) {
105113
}
106114

107115
public YunxinApiHttpClient build() {
116+
String cacheKey = appkey + "/" + appsecret;
117+
YunxinApiHttpClient client = clientMap.get(cacheKey);
118+
if (client != null) {
119+
throw new IllegalStateException("YunxinApiHttpClient with appkey = [" + appkey + "] duplicate init");
120+
}
108121
if (endpointConfig.getEndpointSelector() == null) {
109122
EndpointSelector endpointSelector = new DynamicEndpointSelector(new DynamicEndpointFetcher(appkey, region));
110123
endpointConfig.setEndpointSelector(endpointSelector);
111124
}
112-
return new YunxinApiHttpClient(appkey, appsecret, endpointConfig, httpClientConfig, metricsConfig);
125+
YunxinApiHttpClient yunxinApiHttpClient = new YunxinApiHttpClient(appkey, appsecret, endpointConfig, httpClientConfig, metricsConfig);
126+
clientMap.put(cacheKey, yunxinApiHttpClient);
127+
return yunxinApiHttpClient;
113128
}
114129
}
115130

src/main/java/com/netease/nim/im/server/sdk/core/endpoint/DynamicEndpointFetcher.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.util.Collections;
1919
import java.util.List;
2020
import java.util.concurrent.Executors;
21+
import java.util.concurrent.ScheduledExecutorService;
2122
import java.util.concurrent.TimeUnit;
2223

2324

@@ -28,6 +29,8 @@ public class DynamicEndpointFetcher implements EndpointFetcher {
2829

2930
private static final Logger logger = LoggerFactory.getLogger(DynamicEndpointFetcher.class);
3031

32+
private static final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("yunxin-im-sdk-endpoint-fetch"));
33+
3134
private final String appkey;
3235
private final List<String> lbsList;
3336
private final int reloadIntervalSeconds;
@@ -81,8 +84,7 @@ public void init(OkHttpClient okHttpClient) {
8184
if (endpoints == null) {
8285
throw new EndpointFetchException("init endpoints error");
8386
}
84-
Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("yunxin-im-sdk-endpoint-fetch"))
85-
.scheduleAtFixedRate(() -> {
87+
scheduler.scheduleAtFixedRate(() -> {
8688
for (String lbs : lbsList) {
8789
try {
8890
boolean reload = reload(lbs);

src/main/java/com/netease/nim/im/server/sdk/core/endpoint/DynamicEndpointSelector.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import java.util.*;
1212
import java.util.concurrent.ConcurrentHashMap;
1313
import java.util.concurrent.Executors;
14+
import java.util.concurrent.ScheduledExecutorService;
1415
import java.util.concurrent.TimeUnit;
1516

1617
/**
@@ -20,6 +21,9 @@ public class DynamicEndpointSelector implements EndpointSelector {
2021

2122
private static final Logger logger = LoggerFactory.getLogger(DynamicEndpointSelector.class);
2223

24+
private static final ScheduledExecutorService scheduler1 = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("yunxin-im-sdk-detect"));
25+
private static final ScheduledExecutorService scheduler2 = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("yunxin-im-sdk-schedule"));
26+
2327
private final EndpointFetcher fetcher;
2428
private final int scheduleDetectIntervalSeconds;
2529
private final int scheduleResultIntervalSeconds;
@@ -74,11 +78,9 @@ public void init(OkHttpClient okHttpClient) {
7478
orderedEndpoints.addAll(backupEndpoints);
7579
}
7680
if (detectPath != null) {
77-
Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("yunxin-im-sdk-detect"))
78-
.scheduleAtFixedRate(this::scheduleDetect, scheduleDetectIntervalSeconds, scheduleDetectIntervalSeconds, TimeUnit.SECONDS);
81+
scheduler1.scheduleAtFixedRate(this::scheduleDetect, scheduleDetectIntervalSeconds, scheduleDetectIntervalSeconds, TimeUnit.SECONDS);
7982
}
80-
Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("yunxin-im-sdk-schedule"))
81-
.scheduleAtFixedRate(this::scheduleResult, scheduleResultIntervalSeconds, scheduleResultIntervalSeconds, TimeUnit.SECONDS);
83+
scheduler2.scheduleAtFixedRate(this::scheduleResult, scheduleResultIntervalSeconds, scheduleResultIntervalSeconds, TimeUnit.SECONDS);
8284
}
8385

8486
@Override

src/main/java/com/netease/nim/im/server/sdk/core/metrics/YunxinApiSdkMetricsCollector.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ public class YunxinApiSdkMetricsCollector {
2020

2121
private static final Logger logger = LoggerFactory.getLogger(YunxinApiSdkMetricsCollector.class);
2222

23-
private final ThreadPoolExecutor callbackExecutor = new ThreadPoolExecutor(1, 1,
23+
private static final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("yunxin-im-sdk-metrics-collector"));
24+
private static final ThreadPoolExecutor callbackExecutor = new ThreadPoolExecutor(1, 1,
2425
0, TimeUnit.SECONDS, new LinkedBlockingQueue<>(100), new NamedThreadFactory("yunxin-im-sdk-stats-callback"));
2526

2627
private final ConcurrentHashMap<Key1, Statistics> map1 = new ConcurrentHashMap<>();
@@ -35,8 +36,7 @@ public YunxinApiSdkMetricsCollector(int collectIntervalSeconds, MetricsCallback
3536
throw new IllegalArgumentException("illegal collectIntervalSeconds");
3637
}
3738
this.metricsCallback = metricsCallback;
38-
Executors.newSingleThreadScheduledExecutor()
39-
.scheduleAtFixedRate(this::calc, collectIntervalSeconds, collectIntervalSeconds, TimeUnit.SECONDS);
39+
scheduler.scheduleAtFixedRate(this::calc, collectIntervalSeconds, collectIntervalSeconds, TimeUnit.SECONDS);
4040
}
4141

4242
public void collect(String endpoint, HttpMethod method, ContextType contextType, ApiVersion apiVersion,

0 commit comments

Comments
 (0)