1. 程式人生 > >【Soul閘道器探祕】http資料同步-Web端處理變更通知

【Soul閘道器探祕】http資料同步-Web端處理變更通知

[個人知識庫](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