Commit da1bf10b by Kang Donghun

#73114 作業同期 ContentRefresher修正

parent 66f8add0
......@@ -7,6 +7,11 @@ public class FetchDateParameters extends AcmsParameters {
private String lastFetchDate;
/**
* contentVersion応答に serviceOptionList を含めるか(1:含める, 0:含めない)
* 既存互換のためデフォルトは1。
*/
private int includeServiceOptionList = 1;
/**
* {@link AcmsParameters} のインスタンスを初期化します。
*
* @param sid ログインした時のセッションIDです。
......@@ -17,6 +22,12 @@ public class FetchDateParameters extends AcmsParameters {
this.lastFetchDate = lastFetchDate;
}
public FetchDateParameters(String sid, String lastFetchDate, int includeServiceOptionList) {
super(sid);
this.lastFetchDate = lastFetchDate;
this.includeServiceOptionList = includeServiceOptionList;
}
/**
* lastFetchDateを返します。
* @return データ更新日付です。
......@@ -25,4 +36,8 @@ public class FetchDateParameters extends AcmsParameters {
public String getLastFetchDate() {
return this.lastFetchDate;
}
public int getIncludeServiceOptionList() {
return includeServiceOptionList;
}
}
......@@ -18,6 +18,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import jp.agentec.abook.abv.bl.acms.client.AcmsClient;
import jp.agentec.abook.abv.bl.acms.client.json.CategoriesJSON;
import jp.agentec.abook.abv.bl.acms.client.json.ContentVersionsJSON;
import jp.agentec.abook.abv.bl.acms.client.json.MasterDataJSON;
import jp.agentec.abook.abv.bl.acms.client.parameters.ContentDownloadLogParameters;
import jp.agentec.abook.abv.bl.acms.client.parameters.FetchDateParameters;
import jp.agentec.abook.abv.bl.common.ABVEnvironment;
......@@ -35,6 +36,7 @@ import jp.agentec.abook.abv.bl.data.dao.SppDeviceDao;
import jp.agentec.abook.abv.bl.dto.ContentDto;
import jp.agentec.abook.abv.bl.dto.EnqueteDto;
import jp.agentec.abook.abv.bl.dto.GroupDto;
import jp.agentec.abook.abv.bl.dto.OperationGroupMasterDto;
import jp.agentec.abook.abv.bl.dto.ServiceOptionDto;
import jp.agentec.abook.abv.bl.dto.SppDeviceDto;
import jp.agentec.abook.abv.bl.logic.AbstractLogic;
......@@ -62,9 +64,9 @@ public class ContentRefresher {
private static ContentRefresher instance;
/**
* 契約オプション・グループ・カテゴリの ACMS 取得を並列化する(DB 反映は取得完了後に従来順で直列)。
* refresh 中の並列 HTTP 用(契約/グループ/カテゴリ、マスタ+作業種別マスタ、作業一覧+プッシュ等で共有)。
*/
private static final ExecutorService REFRESH_METADATA_FETCH_POOL = Executors.newFixedThreadPool(3, new ThreadFactory() {
private static final ExecutorService REFRESH_METADATA_FETCH_POOL = Executors.newFixedThreadPool(4, new ThreadFactory() {
private final AtomicInteger seq = new AtomicInteger(1);
@Override
public Thread newThread(Runnable r) {
......@@ -195,10 +197,39 @@ public class ContentRefresher {
// CMSでメンテナンスされるHACCPマスタデータをアプリから取得できるようにJSONファイルを生成する。
String fetchDate = null;
//失敗時、3回リトライ処理
//失敗時、3回リトライ処理(初回のみ getMasterData と operationGroupMaster の HTTP を並列化)
for (int i = 0; i < 4; i++) {
try {
if (i == 0) {
final int masterRetry = i;
Future<MasterDataJSON> fMaster = REFRESH_METADATA_FETCH_POOL.submit(new Callable<MasterDataJSON>() {
@Override
public MasterDataJSON call() throws Exception {
return masterDataLogic.fetchMasterDataJson(ABVDataCache.getInstance().tempMasterDataFetchDate, masterRetry);
}
});
Future<List<OperationGroupMasterDto>> fOg = REFRESH_METADATA_FETCH_POOL.submit(new Callable<List<OperationGroupMasterDto>>() {
@Override
public List<OperationGroupMasterDto> call() throws Exception {
return operationGroupMasterLogic.fetchOperationGroupMasterOnly();
}
});
MasterDataJSON mj;
List<OperationGroupMasterDto> ogList;
try {
mj = fMaster.get();
ogList = fOg.get();
} catch (Exception ex) {
fOg.cancel(true);
fMaster.cancel(true);
throw ex;
}
fetchDate = masterDataLogic.applyMasterDataJson(mj);
operationGroupMasterLogic.applyFetchedOperationGroupMaster(ogList);
} else {
fetchDate = masterDataLogic.initializeMasterData(ABVDataCache.getInstance().tempMasterDataFetchDate, i);
operationGroupMasterLogic.setOperationGroupMaster();
}
break;
} catch (Exception e) {
Logger.e(TAG, "initializeMasterData Exception", e);
......@@ -216,9 +247,6 @@ public class ContentRefresher {
ABVDataCache.getInstance().tempMasterDataFetchDate = fetchDate;
}
// 作業種別情報を取得
operationGroupMasterLogic.setOperationGroupMaster();
if (interrupt) { // この時点で停止要求が来た場合先には進まない。(ServiceOption/Group/Categoryの更新は1セットで行う(トランザクションはそれぞれ別))
Logger.d(TAG, "stop refresh worker before content update.");
setFail();
......@@ -355,7 +383,8 @@ public class ContentRefresher {
AcmsDao dao = AbstractDao.getDao(AcmsDao.class);
String lastFetchDate = dao.selectContentVersionLastFetchDate();
FetchDateParameters param = new FetchDateParameters(cache.getMemberInfo().sid, lastFetchDate);
// contentVersion では serviceOptionList を省略し、レスポンスを軽量化する
FetchDateParameters param = new FetchDateParameters(cache.getMemberInfo().sid, lastFetchDate, 0);
ContentVersionsJSON json = AcmsClient.getInstance(cache.getUrlPath(), networkAdapter).contentVersion(param);
if (json == null) {
// 変更なし(304)の場合、FetchDateを更新する必要がないため、tempはクリアする
......@@ -477,12 +506,24 @@ public class ContentRefresher {
if (contentDownloadListener != null) {
if (!isRefreshing() && e == null) {
// 新着処理が終わったら以下の処理が実行
// 新着処理が終わったら以下の処理が実行(作業一覧系とプッシュは独立のため HTTP を並列化)
try {
// サーバー通信でプロジェクト取得
Future<Void> fOp = REFRESH_METADATA_FETCH_POOL.submit(new Callable<Void>() {
@Override
public Void call() throws Exception {
operationLogic.initializeOperations();
//プッシュメッセージ情報を取得
return null;
}
});
Future<Void> fPush = REFRESH_METADATA_FETCH_POOL.submit(new Callable<Void>() {
@Override
public Void call() throws Exception {
pushMessageLogic.initializePushMessage();
return null;
}
});
fOp.get();
fPush.get();
} catch (Exception e1) {
Logger.e(TAG, e1);
e = e1;
......
......@@ -29,18 +29,17 @@ public class MasterDataLogic extends AbstractLogic {
* @throws Exception その他、例外です。
* @since 1.0.0
*/
public String initializeMasterData(String lastFetchDate, int retryCount) throws AcmsException, NetworkDisconnectedException, IOException {
String fetchDate = null;
try {
/** HTTP のみ。refresh 時に operationGroupMaster 等と並列フェッチするために使用。 */
public MasterDataJSON fetchMasterDataJson(String lastFetchDate, int retryCount) throws AcmsException, NetworkDisconnectedException {
FetchDateParameters param = new FetchDateParameters(cache.getMemberInfo().sid, lastFetchDate);
MasterDataJSON masterDataJson = AcmsClient.getInstance(cache.getUrlPath(), networkAdapter).masterData(param, retryCount);
return AcmsClient.getInstance(cache.getUrlPath(), networkAdapter).masterData(param, retryCount);
}
// get MAP
/** {@link #fetchMasterDataJson} の結果をローカル JSON ファイルへ反映し、fetchDate を返す。 */
public String applyMasterDataJson(MasterDataJSON masterDataJson) throws IOException {
Map<String, String> masterDataMap = masterDataJson.masterDataMap;
// Map に保存されたデータをJSONに変換する。
if (masterDataMap != null) {
for (Map.Entry<String, String> entry : masterDataMap.entrySet()) {
// 値は巨大になり得るためキーのみ(デバッグ時は必要に応じてレベル調整)
Logger.d(TAG, "masterData key=" + entry.getKey());
try {
createMasterDataJson(entry.getKey(), entry.getValue());
......@@ -49,13 +48,17 @@ public class MasterDataLogic extends AbstractLogic {
throw e;
}
}
fetchDate = masterDataJson.fetchDate;
}
return masterDataJson.fetchDate;
}
public String initializeMasterData(String lastFetchDate, int retryCount) throws AcmsException, NetworkDisconnectedException, IOException {
try {
return applyMasterDataJson(fetchMasterDataJson(lastFetchDate, retryCount));
} catch (Exception e) {
Logger.e(TAG, "masterDataSend error : ", e);
throw e;
}
// masterData の fetchDateを渡す。
return fetchDate;
}
/**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment