From 8b53cbfbfe2415c105ccf8ba5f55b75427fc99a3 Mon Sep 17 00:00:00 2001 From: Shubham Goyal Date: Thu, 26 Dec 2024 15:18:51 +0530 Subject: [PATCH] Uses datum id to track progress instead of detail as a detail can potentially be associated with more than one case lists in the app --- .../activities/EntitySelectActivity.java | 2 +- .../entity/AndroidAsyncNodeEntityFactory.kt | 8 ++++-- .../EntitySubnodeDetailFragment.java | 7 +++--- .../org/commcare/tasks/EntityLoaderHelper.kt | 4 ++- .../org/commcare/tasks/EntityLoaderTask.java | 13 ++++++++-- .../commcare/tasks/PrimeEntityCacheHelper.kt | 25 ++++++++++--------- 6 files changed, 37 insertions(+), 22 deletions(-) diff --git a/app/src/org/commcare/activities/EntitySelectActivity.java b/app/src/org/commcare/activities/EntitySelectActivity.java index 3b396ea02..60506a940 100755 --- a/app/src/org/commcare/activities/EntitySelectActivity.java +++ b/app/src/org/commcare/activities/EntitySelectActivity.java @@ -480,7 +480,7 @@ public boolean loadEntities() { if (loader == null && !EntityLoaderTask.attachToActivity(this)) { setProgressText(StringUtils.getStringRobust(this, R.string.entity_list_initializing)); - EntityLoaderTask entityLoader = new EntityLoaderTask(shortSelect, evalContext()); + EntityLoaderTask entityLoader = new EntityLoaderTask(shortSelect, selectDatum, evalContext()); entityLoader.attachListener(this); entityLoader.executeParallel(selectDatum.getNodeset()); return true; diff --git a/app/src/org/commcare/entity/AndroidAsyncNodeEntityFactory.kt b/app/src/org/commcare/entity/AndroidAsyncNodeEntityFactory.kt index 6a4e96ef1..23ce31fa8 100644 --- a/app/src/org/commcare/entity/AndroidAsyncNodeEntityFactory.kt +++ b/app/src/org/commcare/entity/AndroidAsyncNodeEntityFactory.kt @@ -8,6 +8,7 @@ import org.commcare.cases.entity.AsyncNodeEntityFactory import org.commcare.cases.entity.Entity import org.commcare.cases.entity.EntityStorageCache import org.commcare.suite.model.Detail +import org.commcare.suite.model.EntityDatum import org.commcare.tasks.PrimeEntityCacheHelper import org.commcare.util.LogTypes import org.javarosa.core.model.condition.EvaluationContext @@ -20,6 +21,7 @@ import org.javarosa.core.services.Logger */ class AndroidAsyncNodeEntityFactory( d: Detail, + private val entityDatum: EntityDatum?, ec: EvaluationContext?, entityStorageCache: EntityStorageCache? ) : AsyncNodeEntityFactory(d, ec, entityStorageCache) { @@ -37,10 +39,11 @@ class AndroidAsyncNodeEntityFactory( val primeEntityCacheHelper = PrimeEntityCacheHelper.getInstance() if (primeEntityCacheHelper.isInProgress()) { // if we are priming something else at the moment, expedite the current detail - if (!primeEntityCacheHelper.isDetailInProgress(detail.id)) { + if (!primeEntityCacheHelper.isDatumInProgress(detail.id)) { primeEntityCacheHelper.expediteDetailWithId( getCurrentCommandId(), detail, + entityDatum!!, entities, progressListener ) @@ -54,6 +57,7 @@ class AndroidAsyncNodeEntityFactory( primeEntityCacheHelper.primeEntityCacheForDetail( getCurrentCommandId(), detail, + entityDatum!!, entities, progressListener ) @@ -85,7 +89,7 @@ class AndroidAsyncNodeEntityFactory( "Timeout while waiting for the prime cache worker to finish" ) if (primeEntityCacheHelper.isInProgress() && - primeEntityCacheHelper.isDetailInProgress(detail.id) + primeEntityCacheHelper.isDatumInProgress(detail.id) ) { // keep observing observePrimeCacheWork(primeEntityCacheHelper, entities) diff --git a/app/src/org/commcare/fragments/EntitySubnodeDetailFragment.java b/app/src/org/commcare/fragments/EntitySubnodeDetailFragment.java index f8abe5244..e29c35f5c 100755 --- a/app/src/org/commcare/fragments/EntitySubnodeDetailFragment.java +++ b/app/src/org/commcare/fragments/EntitySubnodeDetailFragment.java @@ -53,7 +53,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa if (this.adapter == null && this.loader == null && !EntityLoaderTask.attachToActivity(this)) { // Set up task to fetch entity data EntityLoaderTask theLoader = - new EntityLoaderTask(detailToDisplay, getFactoryContextForRef(referenceToDisplay)); + new EntityLoaderTask(detailToDisplay, null, getFactoryContextForRef(referenceToDisplay)); theLoader.attachListener(this); theLoader.executeParallel(detailToDisplay.getNodeset().contextualize(referenceToDisplay)); @@ -79,9 +79,8 @@ public void attachLoader(EntityLoaderTask task) { } @Override - public void deliverLoadResult(List> entities, - List references, - NodeEntityFactory factory, int focusTargetIndex) { + public void deliverLoadResult(List> entities, List references, + NodeEntityFactory factory, int focusTargetIndex) { Bundle args = getArguments(); Detail detail = asw.getSession().getDetail(args.getString(DETAIL_ID)); final int thisIndex = args.getInt(CHILD_DETAIL_INDEX, -1); diff --git a/app/src/org/commcare/tasks/EntityLoaderHelper.kt b/app/src/org/commcare/tasks/EntityLoaderHelper.kt index 089df279e..65670553a 100644 --- a/app/src/org/commcare/tasks/EntityLoaderHelper.kt +++ b/app/src/org/commcare/tasks/EntityLoaderHelper.kt @@ -11,11 +11,13 @@ import org.commcare.entity.AndroidAsyncNodeEntityFactory import org.commcare.models.database.user.models.CommCareEntityStorageCache import org.commcare.preferences.DeveloperPreferences import org.commcare.suite.model.Detail +import org.commcare.suite.model.EntityDatum import org.javarosa.core.model.condition.EvaluationContext import org.javarosa.core.model.instance.TreeReference class EntityLoaderHelper( detail: Detail, + sessionDatum: EntityDatum?, evalCtx: EvaluationContext, ) : Cancellable { @@ -27,7 +29,7 @@ class EntityLoaderHelper( evalCtx.addFunctionHandler(EntitySelectActivity.getHereFunctionHandler()) if (detail.useAsyncStrategy() || detail.shouldCache()) { val entityStorageCache: EntityStorageCache = CommCareEntityStorageCache("case") - factory = AndroidAsyncNodeEntityFactory(detail, evalCtx, entityStorageCache) + factory = AndroidAsyncNodeEntityFactory(detail, sessionDatum, evalCtx, entityStorageCache) } else { factory = NodeEntityFactory(detail, evalCtx) if (DeveloperPreferences.collectAndDisplayEntityTraces()) { diff --git a/app/src/org/commcare/tasks/EntityLoaderTask.java b/app/src/org/commcare/tasks/EntityLoaderTask.java index 3dd206a69..3cecf32b3 100644 --- a/app/src/org/commcare/tasks/EntityLoaderTask.java +++ b/app/src/org/commcare/tasks/EntityLoaderTask.java @@ -7,6 +7,7 @@ import org.commcare.cases.entity.EntityLoadingProgressListener; import org.commcare.logging.XPathErrorLogger; import org.commcare.suite.model.Detail; +import org.commcare.suite.model.EntityDatum; import org.commcare.tasks.templates.ManagedAsyncTask; import org.javarosa.core.model.condition.EvaluationContext; import org.javarosa.core.model.instance.TreeReference; @@ -15,6 +16,8 @@ import java.util.List; +import javax.annotation.Nullable; + /** * @author ctsims */ @@ -29,8 +32,14 @@ public class EntityLoaderTask private final EntityLoaderHelper entityLoaderHelper; private Exception mException = null; - public EntityLoaderTask(Detail detail, EvaluationContext evalCtx) { - entityLoaderHelper = new EntityLoaderHelper(detail, evalCtx); + /** + * Creates a new instance + * @param detail detail we want to load + * @param entityDatum entity datum corresponding to the entity list, null for entity detail screens + * @param evalCtx evaluation context + */ + public EntityLoaderTask(Detail detail, @Nullable EntityDatum entityDatum, EvaluationContext evalCtx) { + entityLoaderHelper = new EntityLoaderHelper(detail, entityDatum , evalCtx); } @Override diff --git a/app/src/org/commcare/tasks/PrimeEntityCacheHelper.kt b/app/src/org/commcare/tasks/PrimeEntityCacheHelper.kt index 74680770f..29586b8e7 100644 --- a/app/src/org/commcare/tasks/PrimeEntityCacheHelper.kt +++ b/app/src/org/commcare/tasks/PrimeEntityCacheHelper.kt @@ -28,7 +28,7 @@ class PrimeEntityCacheHelper private constructor() : Cancellable { private var entityLoaderHelper: EntityLoaderHelper? = null private var inProgress = false - private var currentDetailInProgress: String? = null + private var currentDatumInProgress: String? = null private var listener: EntityLoadingProgressListener? = null private val _cachedEntitiesState = MutableStateFlow>?>(null) @@ -86,11 +86,12 @@ class PrimeEntityCacheHelper private constructor() : Cancellable { fun primeEntityCacheForDetail( commandId: String, detail: Detail, + entityDatum: EntityDatum, entities: MutableList>, progressListener: EntityLoadingProgressListener ) { checkPreConditions() - primeCacheForDetail(commandId, detail,null, entities, progressListener) + primeCacheForDetail(commandId, detail, entityDatum, entities, progressListener) clearState() } @@ -101,16 +102,17 @@ class PrimeEntityCacheHelper private constructor() : Cancellable { fun expediteDetailWithId( commandId: String, detail: Detail, + entityDatum: EntityDatum, entities: MutableList>, progressListener: EntityLoadingProgressListener ) { cancel() - primeEntityCacheForDetail(commandId, detail, entities, progressListener) + primeEntityCacheForDetail(commandId, detail, entityDatum, entities, progressListener) schedulePrimeEntityCacheWorker() } - fun isDetailInProgress(detailId: String): Boolean { - return currentDetailInProgress?.contentEquals(detailId) ?: false + fun isDatumInProgress(datumId: String): Boolean { + return currentDatumInProgress?.contentEquals(datumId) ?: false } private fun primeEntityCacheForApp(commCarePlatform: AndroidCommCarePlatform) { @@ -143,26 +145,25 @@ class PrimeEntityCacheHelper private constructor() : Cancellable { private fun primeCacheForDetail( commandId: String, detail: Detail, - sessionDatum: EntityDatum? = null, + entityDatum: EntityDatum, entities: MutableList>? = null, progressListener: EntityLoadingProgressListener? = null ) { if (!detail.shouldCache()) return - currentDetailInProgress = detail.id - entityLoaderHelper = EntityLoaderHelper(detail, evalCtx(commandId)).also { + currentDatumInProgress = entityDatum.dataId + entityLoaderHelper = EntityLoaderHelper(detail, entityDatum, evalCtx(commandId)).also { it.factory.setEntityProgressListener(progressListener) } // Handle the cache operation based on the available input val cachedEntities = when { - sessionDatum != null -> entityLoaderHelper!!.cacheEntities(sessionDatum.nodeset).first entities != null -> { entityLoaderHelper!!.cacheEntities(entities) entities } - else -> return + else -> entityLoaderHelper!!.cacheEntities(entityDatum.nodeset).first } _cachedEntitiesState.value = cachedEntities - currentDetailInProgress = null + currentDatumInProgress = null } private fun evalCtx(commandId: String): EvaluationContext { @@ -176,7 +177,7 @@ class PrimeEntityCacheHelper private constructor() : Cancellable { entityLoaderHelper = null inProgress = false listener = null - currentDetailInProgress = null + currentDatumInProgress = null instance = null }