【Soul閘道器探祕】http資料同步-Web端處理變更通知
阿新 • • 發佈:2021-01-31
[個人知識庫](https://www.yuque.com/tengye/vtss9i)
## 引言
上一篇,梳理http 資料同步策略的變更通知機制,本篇開始探究配置變更通知到達後, `soul-web` 端的處理響應。
不同資料變更的通知機制應當是一致的,故本篇以 selector 配置變更通知為切入點進行深入。
## 通知處理入口
上回我們說到 HttpSyncDataService 的 doLongPolling,在其內部發起通知訂閱並接收響應通知:
```java
private void doLongPolling(final String server) {
...
String listenerUrl = server + "/configs/listener";
...
try {
// 發起監聽請求
String json = this.httpClient.postForEntity(listenerUrl, httpEntity, String.class).getBody();
log.debug("listener result: [{}]", json);
groupJson = GSON.fromJson(json, JsonObject.class).getAsJsonArray("data");
} catch (RestClientException e) {
...
}
// 處理變更通知
if (groupJson != null) {
// fetch group configuration async.
ConfigGroupEnum[] changedGroups = GSON.fromJson(groupJson, ConfigGroupEnum[].class);
if (ArrayUtils.isNotEmpty(changedGroups)) {
log.info("Group config changed: {}", Arrays.toString(changedGroups));
// 獲取組配置
this.doFetchGroupConfig(server, changedGroups);
}
}
}
```
在收到變更通知時,若存在配置組變更,則按變更組獲取相應配置。
## 獲取配置
獲取組配置處理如下:
```java
private void doFetchGroupConfig(final String server, final ConfigGroupEnum... groups) {
...
String url = server + "/configs/fetch?" + StringUtils.removeEnd(params.toString(), "&");
...
try {
json = this.httpClient.getForObject(url, String.class);
} catch (RestClientException e) {
...
}
// update local cache
boolean updated = this.updateCacheWithJson(json);
...
}
```
內部發起配置獲取請求並更新本地快取。
## 更新配置組快取
由 HttpSyncDataService 實現本地快取更新:
```java
private boolean updateCacheWithJson(final String json) {
JsonObject jsonObject = GSON.fromJson(json, JsonObject.class);
JsonObject data = jsonObject.getAsJsonObject("data");
// if the config cache will be updated?
return factory.executor(data);
}
```
轉成 Json 物件後交由 DataRefreshFactory 進行處理。
DataRefreshFactory 處理如下:
```java
public boolean executor(final JsonObject data) {
final boolean[] success = {false};
ENUM_MAP.values().parallelStream().forEach(dataRefresh -> success[0] = dataRefresh.refresh(data));
return success[0];
}
```
呼叫相應資料重新整理類重新整理資料。
統一由 AbstractDataRefresh 的 refresh 進行處理:
```java
public Boolean refresh(final JsonObject data) {
boolean updated = false;
JsonObject jsonObject = convert(data);
if (null != jsonObject) {
Co