All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cohort.CohortLoader.kt Maven / Gradle / Ivy

package com.amplitude.cohort

import com.amplitude.CohortDescriptionFetch
import com.amplitude.CohortDescriptionFetchFailure
import com.amplitude.CohortDownload
import com.amplitude.CohortDownloadFailure
import com.amplitude.Metrics
import com.amplitude.util.logger
import kotlinx.coroutines.Job
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.joinAll
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock

internal class CohortLoader(
    @Volatile var maxCohortSize: Int,
    private val cohortApi: CohortApi,
    private val cohortStorage: CohortStorage
) {

    companion object {
        val log by logger()
    }
    private val jobsMutex = Mutex()
    private val jobs = mutableMapOf()

    suspend fun loadCohorts(cohortIds: Set) = coroutineScope {
        val jobs = mutableListOf()
        for (cohortId in cohortIds) {
            jobs += launch { loadCohort(cohortId) }
        }
        jobs.joinAll()
    }

    private suspend fun loadCohort(cohortId: String) = coroutineScope {
        log.trace("loadCohort: start - cohortId={}", cohortId)
        val networkCohort = Metrics.with(
            { CohortDescriptionFetch },
            { e -> CohortDescriptionFetchFailure(e) }
        ) {
            cohortApi.getCohortDescription(cohortId)
        }
        val storageCohort = cohortStorage.getCohortDescription(cohortId)
        val shouldDownloadCohort = networkCohort.size <= maxCohortSize &&
            networkCohort.lastComputed > (storageCohort?.lastComputed ?: -1)
        if (shouldDownloadCohort) {
            jobsMutex.withLock {
                jobs.getOrPut(cohortId) {
                    launch {
                        log.info("Downloading cohort. $networkCohort")
                        val cohortMembers = Metrics.with({ CohortDownload }, { e -> CohortDownloadFailure(e) }) {
                            cohortApi.getCohortMembers(networkCohort)
                        }
                        cohortStorage.putCohort(networkCohort, cohortMembers)
                        jobsMutex.withLock { jobs.remove(cohortId) }
                        log.info("Cohort download complete. $networkCohort")
                    }
                }
            }.join()
        }
        log.trace("loadCohort: end - cohortId={}", cohortId)
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy