Use coroutines for Workers

This commit is contained in:
Milos Kozak 2023-01-10 12:15:04 +01:00
parent b726f149b4
commit 5306e62f91
50 changed files with 348 additions and 198 deletions

View file

@ -14,7 +14,6 @@ import info.nightscout.androidaps.BuildConfig
import info.nightscout.androidaps.R
import info.nightscout.configuration.maintenance.MaintenancePlugin
import info.nightscout.core.profile.ProfileSealed
import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.core.utils.worker.LoggingWorker
import info.nightscout.database.impl.AppRepository
import info.nightscout.interfaces.Config
@ -35,6 +34,7 @@ import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
import info.nightscout.ui.widget.Widget
import kotlinx.coroutines.Dispatchers
import java.util.concurrent.TimeUnit
import javax.inject.Inject
import kotlin.math.abs
@ -42,7 +42,7 @@ import kotlin.math.abs
class KeepAliveWorker(
private val context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.Default) {
@Inject lateinit var localAlertUtils: LocalAlertUtils
@Inject lateinit var repository: AppRepository
@ -74,7 +74,7 @@ class KeepAliveWorker(
private const val KA_10 = "KeepAlive_10"
}
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
aapsLogger.debug(LTag.CORE, "KeepAlive received from: " + inputData.getString("schedule"))
// 15 min interval is WorkManager minimum so schedule another instances to have 5 min interval

View file

@ -6,11 +6,13 @@ import androidx.work.Data
import androidx.work.ExistingWorkPolicy
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkManager
import info.nightscout.androidaps.annotations.OpenForTesting
import org.json.JSONArray
import org.json.JSONObject
import javax.inject.Inject
import javax.inject.Singleton
@OpenForTesting
@Singleton
class DataWorkerStorage @Inject constructor(
private val context: Context

View file

@ -1,16 +1,18 @@
package info.nightscout.core.utils.worker
import android.content.Context
import androidx.work.Worker
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import androidx.work.workDataOf
import dagger.android.HasAndroidInjector
import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.withContext
import javax.inject.Inject
abstract class LoggingWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
abstract class LoggingWorker(context: Context, workerParams: WorkerParameters, val dispatcher: CoroutineDispatcher) : CoroutineWorker(context, workerParams) {
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var fabricPrivacy: FabricPrivacy
@ -19,16 +21,18 @@ abstract class LoggingWorker(context: Context, workerParams: WorkerParameters) :
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
}
override fun doWork(): Result =
override suspend fun doWork(): Result =
try {
withContext(dispatcher) {
doWorkAndLog().also {
aapsLogger.debug(LTag.WORKER, "Worker result ${it::class.java.simpleName.uppercase()} for ${this::class.java}")
}
}
} catch (e: Exception) {
fabricPrivacy.logException(e)
e.printStackTrace()
Result.failure(workDataOf("Error" to e.localizedMessage))
}
abstract fun doWorkAndLog(): Result
abstract suspend fun doWorkAndLog(): Result
}

View file

@ -59,6 +59,7 @@ import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
import kotlinx.coroutines.Dispatchers
import java.io.File
import java.io.FileNotFoundException
import java.io.IOException
@ -381,7 +382,7 @@ class ImportExportPrefsImpl @Inject constructor(
class CsvExportWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.IO) {
@Inject lateinit var injector: HasAndroidInjector
@Inject lateinit var rh: ResourceHelper
@ -391,7 +392,7 @@ class ImportExportPrefsImpl @Inject constructor(
@Inject lateinit var storage: Storage
@Inject lateinit var persistenceLayer: PersistenceLayer
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
val entries = persistenceLayer.getUserEntryFilteredDataFromTime(MidnightTime.calc() - T.days(90).msecs()).blockingGet()
prefFileList.ensureExportDirExists()
val newFile = prefFileList.newExportCsvFile()

View file

@ -71,6 +71,7 @@ import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.kotlin.plusAssign
import kotlinx.coroutines.Dispatchers
import org.apache.commons.lang3.StringUtils
import org.joda.time.DateTime
import java.text.Normalizer
@ -197,12 +198,12 @@ class SmsCommunicatorPlugin @Inject constructor(
class SmsCommunicatorWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.IO) {
@Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
val bundle = dataWorkerStorage.pickupBundle(inputData.getLong(DataWorkerStorage.STORE_KEY, -1))
?: return Result.failure(workDataOf("Error" to "missing input data"))
val format = bundle.getString("format")

View file

@ -40,6 +40,7 @@ import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import kotlinx.coroutines.Dispatchers
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
@ -432,7 +433,7 @@ class ProfilePlugin @Inject constructor(
class NSProfileWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.Default) {
@Inject lateinit var injector: HasAndroidInjector
@Inject lateinit var rxBus: RxBus
@ -444,7 +445,7 @@ class ProfilePlugin @Inject constructor(
@Inject lateinit var xDripBroadcast: XDripBroadcast
@Inject lateinit var instantiator: Instantiator
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
val profileJson = dataWorkerStorage.pickupJSONObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1))
?: return Result.failure(workDataOf("Error" to "missing input data"))
xDripBroadcast.sendProfile(profileJson)

View file

@ -20,6 +20,7 @@ import info.nightscout.interfaces.source.BgSource
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ResourceHelper
import kotlinx.coroutines.Dispatchers
import javax.inject.Inject
import javax.inject.Singleton
@ -54,13 +55,13 @@ class AidexPlugin @Inject constructor(
class AidexWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.IO) {
@Inject lateinit var aidexPlugin: AidexPlugin
@Inject lateinit var repository: AppRepository
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
var ret = Result.success()
if (!aidexPlugin.isEnabled()) return Result.success(workDataOf("Result" to "Plugin not enabled"))

View file

@ -36,6 +36,7 @@ import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
import info.nightscout.source.activities.RequestDexcomPermissionActivity
import kotlinx.coroutines.Dispatchers
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.math.abs
@ -83,7 +84,7 @@ class DexcomPlugin @Inject constructor(
class DexcomWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.IO) {
@Inject lateinit var injector: HasAndroidInjector
@Inject lateinit var dexcomPlugin: DexcomPlugin
@ -94,7 +95,7 @@ class DexcomPlugin @Inject constructor(
@Inject lateinit var repository: AppRepository
@Inject lateinit var uel: UserEntryLogger
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
var ret = Result.success()
if (!dexcomPlugin.isEnabled()) return Result.success(workDataOf("Result" to "Plugin not enabled"))

View file

@ -22,6 +22,7 @@ import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import kotlinx.coroutines.Dispatchers
import java.util.Arrays
import javax.inject.Inject
import javax.inject.Singleton
@ -53,7 +54,7 @@ class EversensePlugin @Inject constructor(
class EversenseWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.IO) {
@Inject lateinit var injector: HasAndroidInjector
@Inject lateinit var eversensePlugin: EversensePlugin
@ -62,7 +63,7 @@ class EversensePlugin @Inject constructor(
@Inject lateinit var repository: AppRepository
@Inject lateinit var xDripBroadcast: XDripBroadcast
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
var ret = Result.success()
if (!eversensePlugin.isEnabled()) return Result.success(workDataOf("Result" to "Plugin not enabled"))

View file

@ -19,6 +19,7 @@ import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import kotlinx.coroutines.Dispatchers
import javax.inject.Inject
import javax.inject.Singleton
@ -44,14 +45,14 @@ class GlimpPlugin @Inject constructor(
class GlimpWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.IO) {
@Inject lateinit var injector: HasAndroidInjector
@Inject lateinit var glimpPlugin: GlimpPlugin
@Inject lateinit var repository: AppRepository
@Inject lateinit var xDripBroadcast: XDripBroadcast
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
var ret = Result.success()
if (!glimpPlugin.isEnabled()) return Result.success(workDataOf("Result" to "Plugin not enabled"))

View file

@ -20,6 +20,7 @@ import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import kotlinx.coroutines.Dispatchers
import org.json.JSONArray
import org.json.JSONException
import javax.inject.Inject
@ -45,7 +46,7 @@ class MM640gPlugin @Inject constructor(
class MM640gWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.IO) {
@Inject lateinit var mM640gPlugin: MM640gPlugin
@Inject lateinit var injector: HasAndroidInjector
@ -54,7 +55,7 @@ class MM640gPlugin @Inject constructor(
@Inject lateinit var repository: AppRepository
@Inject lateinit var xDripBroadcast: XDripBroadcast
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
var ret = Result.success()
if (!mM640gPlugin.isEnabled()) return Result.success()

View file

@ -30,6 +30,7 @@ import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
import kotlinx.coroutines.Dispatchers
import org.json.JSONArray
import org.json.JSONObject
import java.security.InvalidParameterException
@ -85,8 +86,7 @@ class NSClientSourcePlugin @Inject constructor(
class NSClientSourceWorker(
context: Context,
params: WorkerParameters
) :
LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.IO) {
@Inject lateinit var nsClientSourcePlugin: NSClientSourcePlugin
@Inject lateinit var injector: HasAndroidInjector
@ -127,7 +127,7 @@ class NSClientSourcePlugin @Inject constructor(
}
@Suppress("SpellCheckingInspection")
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
var ret = Result.success()
val sgvs = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1))
?: return Result.failure(workDataOf("Error" to "missing input data"))

View file

@ -20,6 +20,7 @@ import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import kotlinx.coroutines.Dispatchers
import org.json.JSONArray
import org.json.JSONException
import javax.inject.Inject
@ -46,14 +47,14 @@ class PoctechPlugin @Inject constructor(
class PoctechWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.IO) {
@Inject lateinit var injector: HasAndroidInjector
@Inject lateinit var poctechPlugin: PoctechPlugin
@Inject lateinit var repository: AppRepository
@Inject lateinit var xDripBroadcast: XDripBroadcast
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
var ret = Result.success()
if (!poctechPlugin.isEnabled()) return Result.success(workDataOf("Result" to "Plugin not enabled"))

View file

@ -18,6 +18,7 @@ import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import kotlinx.coroutines.Dispatchers
import javax.inject.Inject
import javax.inject.Singleton
@ -43,7 +44,7 @@ class TomatoPlugin @Inject constructor(
class TomatoWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.IO) {
@Inject lateinit var injector: HasAndroidInjector
@Inject lateinit var tomatoPlugin: TomatoPlugin
@ -52,7 +53,7 @@ class TomatoPlugin @Inject constructor(
@Inject lateinit var xDripBroadcast: XDripBroadcast
@Suppress("SpellCheckingInspection")
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
var ret = Result.success()
if (!tomatoPlugin.isEnabled()) return Result.success(workDataOf("Result" to "Plugin not enabled"))

View file

@ -20,6 +20,7 @@ import info.nightscout.interfaces.source.XDrip
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ResourceHelper
import kotlinx.coroutines.Dispatchers
import javax.inject.Inject
import javax.inject.Singleton
@ -60,13 +61,13 @@ class XdripPlugin @Inject constructor(
class XdripWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.IO) {
@Inject lateinit var xdripPlugin: XdripPlugin
@Inject lateinit var repository: AppRepository
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
var ret = Result.success()
if (!xdripPlugin.isEnabled()) return Result.success(workDataOf("Result" to "Plugin not enabled"))

View file

@ -61,6 +61,7 @@ import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import kotlinx.coroutines.Dispatchers
import java.util.concurrent.Executors
import java.util.concurrent.ScheduledFuture
import java.util.concurrent.TimeUnit
@ -123,11 +124,11 @@ class StoreDataForDbImpl @Inject constructor(
class StoreBgWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.Default) {
@Inject lateinit var storeDataForDb: StoreDataForDb
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
storeDataForDb.storeGlucoseValuesToDb()
return Result.success()
}
@ -136,11 +137,11 @@ class StoreDataForDbImpl @Inject constructor(
class StoreFoodWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.Default) {
@Inject lateinit var storeDataForDb: StoreDataForDb
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
storeDataForDb.storeFoodsToDb()
return Result.success()
}

View file

@ -28,12 +28,13 @@ import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventNSClientNewLog
import info.nightscout.shared.sharedPreferences.SP
import kotlinx.coroutines.Dispatchers
import javax.inject.Inject
class NSClientAddAckWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.Default) {
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
@Inject lateinit var repository: AppRepository
@ -43,7 +44,7 @@ class NSClientAddAckWorker(
@Inject lateinit var sp: SP
@Inject lateinit var storeDataForDb: StoreDataForDb
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
val ack = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as NSAddAck?
?: return Result.failure(workDataOf("Error" to "missing input data"))

View file

@ -29,12 +29,13 @@ import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import kotlinx.coroutines.Dispatchers
import javax.inject.Inject
class NSClientAddUpdateWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.Default) {
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
@Inject lateinit var config: Config
@ -46,7 +47,7 @@ class NSClientAddUpdateWorker(
@Inject lateinit var xDripBroadcast: XDripBroadcast
@Inject lateinit var storeDataForDb: StoreDataForDb
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
val treatments = dataWorkerStorage.pickupJSONArray(inputData.getLong(DataWorkerStorage.STORE_KEY, -1))
?: return Result.failure(workDataOf("Error" to "missing input data"))

View file

@ -10,19 +10,20 @@ import info.nightscout.interfaces.nsclient.StoreDataForDb
import info.nightscout.plugins.sync.nsclient.data.NSMbg
import info.nightscout.plugins.sync.nsclient.extensions.therapyEventFromNsMbg
import info.nightscout.shared.sharedPreferences.SP
import kotlinx.coroutines.Dispatchers
import javax.inject.Inject
class NSClientMbgWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.IO) {
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
@Inject lateinit var sp: SP
@Inject lateinit var config: Config
@Inject lateinit var storeDataForDb: StoreDataForDb
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
val ret = Result.success()
val acceptNSData = sp.getBoolean(info.nightscout.core.utils.R.string.key_ns_receive_therapy_events, false) || config.NSCLIENT

View file

@ -23,12 +23,13 @@ import info.nightscout.plugins.sync.nsclient.acks.NSUpdateAck
import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventNSClientNewLog
import kotlinx.coroutines.Dispatchers
import javax.inject.Inject
class NSClientUpdateRemoveAckWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.Default) {
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
@Inject lateinit var repository: AppRepository
@ -36,7 +37,7 @@ class NSClientUpdateRemoveAckWorker(
@Inject lateinit var dataSyncSelector: DataSyncSelector
@Inject lateinit var aapsSchedulers: AapsSchedulers
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
var ret = Result.success()
val ack = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as NSUpdateAck?

View file

@ -14,6 +14,7 @@ import androidx.work.WorkManager
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.annotations.OpenForTesting
import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.core.validators.ValidatingEditTextPreference
import info.nightscout.database.ValueWrapper
@ -85,6 +86,7 @@ import java.util.concurrent.TimeUnit
import javax.inject.Inject
import javax.inject.Singleton
@OpenForTesting
@Singleton
class NSClientV3Plugin @Inject constructor(
injector: HasAndroidInjector,

View file

@ -9,18 +9,19 @@ import info.nightscout.interfaces.sync.DataSyncSelector
import info.nightscout.plugins.sync.nsShared.events.EventNSClientUpdateGUI
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventNSClientNewLog
import kotlinx.coroutines.Dispatchers
import javax.inject.Inject
@OpenForTesting
class DataSyncWorker(
context: Context, params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.IO) {
@Inject lateinit var dataSyncSelector: DataSyncSelector
@Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var rxBus: RxBus
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
if (activePlugin.activeNsClient?.hasWritePermission == true) {
rxBus.send(EventNSClientNewLog("UPL", "Start"))
dataSyncSelector.doUpload()

View file

@ -19,13 +19,13 @@ import info.nightscout.sdk.interfaces.NSAndroidClient
import info.nightscout.sdk.localmodel.entry.NSSgvV3
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.Dispatchers
import javax.inject.Inject
import kotlin.math.max
class LoadBgWorker(
context: Context, params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.IO) {
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
@Inject lateinit var rxBus: RxBus
@ -35,21 +35,13 @@ class LoadBgWorker(
@Inject lateinit var nsClientV3Plugin: NSClientV3Plugin
@Inject lateinit var workerClasses: WorkerClasses
companion object {
val JOB_NAME: String = this::class.java.simpleName
}
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null"))
var ret = Result.success()
val isFirstLoad = nsClientV3Plugin.isFirstLoad(NsClient.Collection.ENTRIES)
val lastLoaded =
if (isFirstLoad) max(nsClientV3Plugin.firstLoadContinueTimestamp.collections.entries, dateUtil.now() - nsClientV3Plugin.maxAge)
else max(nsClientV3Plugin.lastLoadedSrvModified.collections.entries, dateUtil.now() - nsClientV3Plugin.maxAge)
runBlocking {
if ((nsClientV3Plugin.newestDataOnServer?.collections?.entries ?: Long.MAX_VALUE) > lastLoaded)
try {
if ((nsClientV3Plugin.newestDataOnServer?.collections?.entries ?: Long.MAX_VALUE) > lastLoaded) {
val sgvs: List<NSSgvV3>
val response: NSAndroidClient.ReadResponse<List<NSSgvV3>>?
if (isFirstLoad) response = nsAndroidClient.getSgvsNewerThan(lastLoaded, 500)
@ -68,7 +60,7 @@ class LoadBgWorker(
sp.putBoolean(info.nightscout.core.utils.R.string.key_objectives_bg_is_available_in_ns, true)
// Schedule processing of fetched data and continue of loading
WorkManager.getInstance(context).beginUniqueWork(
JOB_NAME,
NSClientV3Plugin.JOB_NAME,
ExistingWorkPolicy.APPEND_OR_REPLACE,
OneTimeWorkRequest.Builder(workerClasses.nsClientSourceWorker).setInputData(dataWorkerStorage.storeInputData(sgvs)).build()
)
@ -92,9 +84,6 @@ class LoadBgWorker(
.then(OneTimeWorkRequest.Builder(LoadTreatmentsWorker::class.java).build())
.enqueue()
}
} catch (error: Exception) {
aapsLogger.error("Error: ", error)
ret = Result.failure(workDataOf("Error" to error.toString()))
}
else {
// End first load
@ -112,7 +101,6 @@ class LoadBgWorker(
.then(OneTimeWorkRequest.Builder(LoadTreatmentsWorker::class.java).build())
.enqueue()
}
}
return ret
return Result.success()
}
}

View file

@ -14,13 +14,14 @@ import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventNSClientNewLog
import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import javax.inject.Inject
class LoadDeviceStatusWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.IO) {
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
@Inject lateinit var rxBus: RxBus
@ -29,7 +30,7 @@ class LoadDeviceStatusWorker(
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var nsDeviceStatusHandler: NSDeviceStatusHandler
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null"))
var ret = Result.success()

View file

@ -15,13 +15,14 @@ import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventNSClientNewLog
import info.nightscout.sdk.localmodel.food.NSFood
import info.nightscout.shared.utils.DateUtil
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import javax.inject.Inject
class LoadFoodsWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.IO) {
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
@Inject lateinit var rxBus: RxBus
@ -30,7 +31,7 @@ class LoadFoodsWorker(
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var storeDataForDb: StoreDataForDb
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null"))
// Food database doesn't provide last record modification

View file

@ -5,16 +5,17 @@ import androidx.work.WorkerParameters
import androidx.work.workDataOf
import info.nightscout.core.utils.worker.LoggingWorker
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import javax.inject.Inject
class LoadLastModificationWorker(
context: Context, params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.IO) {
@Inject lateinit var nsClientV3Plugin: NSClientV3Plugin
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null"))
var ret = Result.success()

View file

@ -15,6 +15,7 @@ import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventNSClientNewLog
import info.nightscout.sdk.interfaces.NSAndroidClient
import info.nightscout.shared.utils.DateUtil
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import org.json.JSONObject
import javax.inject.Inject
@ -23,7 +24,7 @@ import kotlin.math.max
class LoadProfileStoreWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.IO) {
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
@Inject lateinit var rxBus: RxBus
@ -32,7 +33,7 @@ class LoadProfileStoreWorker(
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var workerClasses: WorkerClasses
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null"))
var ret = Result.success()

View file

@ -5,16 +5,17 @@ import androidx.work.WorkerParameters
import androidx.work.workDataOf
import info.nightscout.core.utils.worker.LoggingWorker
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import javax.inject.Inject
class LoadStatusWorker(
context: Context, params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.IO) {
@Inject lateinit var nsClientV3Plugin: NSClientV3Plugin
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null"))
var ret = Result.success()

View file

@ -17,6 +17,7 @@ import info.nightscout.rx.events.EventNSClientNewLog
import info.nightscout.sdk.interfaces.NSAndroidClient
import info.nightscout.sdk.localmodel.treatment.NSTreatment
import info.nightscout.shared.utils.DateUtil
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import javax.inject.Inject
import kotlin.math.max
@ -24,7 +25,7 @@ import kotlin.math.max
class LoadTreatmentsWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.IO) {
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
@Inject lateinit var rxBus: RxBus
@ -33,7 +34,7 @@ class LoadTreatmentsWorker(
@Inject lateinit var dateUtil: DateUtil
@Inject lateinit var storeDataForDb: StoreDataForDb
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
val nsAndroidClient = nsClientV3Plugin.nsAndroidClient ?: return Result.failure(workDataOf("Error" to "AndroidClient is null"))
var ret = Result.success()

View file

@ -15,6 +15,7 @@ import info.nightscout.plugins.sync.nsclientV3.extensions.toFood
import info.nightscout.rx.logging.LTag
import info.nightscout.sdk.localmodel.food.NSFood
import info.nightscout.shared.sharedPreferences.SP
import kotlinx.coroutines.Dispatchers
import org.json.JSONArray
import org.json.JSONObject
import javax.inject.Inject
@ -22,7 +23,7 @@ import javax.inject.Inject
class ProcessFoodWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.Default) {
@Inject lateinit var injector: HasAndroidInjector
@Inject lateinit var repository: AppRepository
@ -30,7 +31,7 @@ class ProcessFoodWorker(
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
@Inject lateinit var storeDataForDb: StoreDataForDb
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
val data = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1))
?: return Result.failure(workDataOf("Error" to "missing input data"))
aapsLogger.debug(LTag.DATABASE, "Received Food Data: $data")

View file

@ -39,12 +39,13 @@ import info.nightscout.sdk.localmodel.treatment.NSTherapyEvent
import info.nightscout.sdk.localmodel.treatment.NSTreatment
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import kotlinx.coroutines.Dispatchers
import javax.inject.Inject
class ProcessTreatmentsWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.Default) {
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
@Inject lateinit var config: Config
@ -57,7 +58,7 @@ class ProcessTreatmentsWorker(
@Inject lateinit var xDripBroadcast: XDripBroadcast
@Inject lateinit var storeDataForDb: StoreDataForDb
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
@Suppress("UNCHECKED_CAST")
val treatments = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as NSAndroidClient.ReadResponse<List<NSTreatment>>?
?: return Result.failure(workDataOf("Error" to "missing input data"))

View file

@ -1,10 +1,18 @@
package info.nightscout.androidaps
import android.content.Context
import android.util.Log
import androidx.work.Configuration
import androidx.work.testing.SynchronousExecutor
import androidx.work.testing.WorkManagerTestInitHelper
import dagger.android.HasAndroidInjector
import info.nightscout.rx.AapsSchedulers
import info.nightscout.rx.TestAapsSchedulers
import info.nightscout.rx.logging.AAPSLoggerTest
import org.junit.Before
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.extension.ExtendWith
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.junit.jupiter.MockitoExtension
import org.mockito.junit.jupiter.MockitoSettings
@ -13,15 +21,30 @@ import java.util.Locale
@ExtendWith(MockitoExtension::class)
@MockitoSettings(strictness = Strictness.LENIENT)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
open class TestBase {
abstract class ContextWithInjector : Context(), HasAndroidInjector
@Mock lateinit var context: ContextWithInjector
val aapsLogger = AAPSLoggerTest()
val aapsSchedulers: AapsSchedulers = TestAapsSchedulers()
@Before
@BeforeEach
fun setupLocale() {
Locale.setDefault(Locale.ENGLISH)
System.setProperty("disableFirebase", "true")
// Initialize WorkManager for instrumentation tests.
WorkManagerTestInitHelper.initializeTestWorkManager(
context,
Configuration.Builder()
.setMinimumLoggingLevel(Log.DEBUG)
.setExecutor(SynchronousExecutor())
.build()
)
}
// Workaround for Kotlin nullability.

View file

@ -1,6 +1,5 @@
package info.nightscout.androidaps
import android.content.Context
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.core.extensions.pureProfileFromJson
@ -41,7 +40,6 @@ open class TestBaseWithProfile : TestBase() {
@Mock lateinit var iobCobCalculator: IobCobCalculator
@Mock lateinit var fabricPrivacy: FabricPrivacy
@Mock lateinit var config: Config
@Mock lateinit var context: Context
@Mock lateinit var sp: SP
@Mock lateinit var repository: AppRepository
@Mock lateinit var hardLimits: HardLimits

View file

@ -1,6 +1,5 @@
package info.nightscout.plugins.sync.nsclient
import android.content.Context
import info.nightscout.androidaps.TestBase
import info.nightscout.interfaces.receivers.ReceiverStatusStore
import info.nightscout.plugins.sync.R
@ -17,7 +16,6 @@ import org.mockito.Mockito.`when`
class NsClientReceiverDelegateTest : TestBase() {
@Mock lateinit var context: Context
@Mock lateinit var sp: SP
@Mock lateinit var rh: ResourceHelper
val rxBus = RxBus(aapsSchedulers, aapsLogger)

View file

@ -1,6 +1,5 @@
package info.nightscout.plugins.sync.nsclientV3.workers
import android.content.Context
import androidx.work.ListenableWorker.Result.Success
import androidx.work.testing.TestListenableWorkerBuilder
import dagger.android.AndroidInjector
@ -11,6 +10,8 @@ import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.sync.DataSyncSelector
import info.nightscout.interfaces.sync.NsClient
import info.nightscout.rx.bus.RxBus
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
@ -18,13 +19,11 @@ import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.`when`
@ExperimentalCoroutinesApi
internal class DataSyncWorkerTest : TestBase() {
abstract class ContextWithInjector : Context(), HasAndroidInjector
@Mock lateinit var fabricPrivacy: FabricPrivacy
@Mock lateinit var dataSyncSelector: DataSyncSelector
@Mock lateinit var context: ContextWithInjector
@Mock lateinit var activePlugin: ActivePlugin
@Mock lateinit var nsClient: NsClient
@Mock lateinit var rxBus: RxBus
@ -51,7 +50,7 @@ internal class DataSyncWorkerTest : TestBase() {
}
@Test
fun doWorkAndLog() {
fun doWorkAndLog() = runTest {
sut = TestListenableWorkerBuilder<DataSyncWorker>(context).build()
`when`(nsClient.hasWritePermission).thenReturn(false)
sut.doWorkAndLog()
@ -61,6 +60,5 @@ internal class DataSyncWorkerTest : TestBase() {
val result = sut.doWorkAndLog()
Mockito.verify(dataSyncSelector, Mockito.times(1)).doUpload()
Assertions.assertTrue(result is Success)
}
}

View file

@ -0,0 +1,99 @@
package info.nightscout.plugins.sync.nsclientV3.workers
import androidx.work.ListenableWorker
import androidx.work.testing.TestListenableWorkerBuilder
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.TestBase
import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.core.utils.receivers.DataWorkerStorage
import info.nightscout.database.impl.AppRepository
import info.nightscout.interfaces.Config
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.receivers.ReceiverStatusStore
import info.nightscout.interfaces.sync.DataSyncSelector
import info.nightscout.interfaces.ui.UiInteraction
import info.nightscout.interfaces.workflow.WorkerClasses
import info.nightscout.plugins.sync.nsclient.NsClientReceiverDelegate
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
import info.nightscout.rx.bus.RxBus
import info.nightscout.sdk.interfaces.NSAndroidClient
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.ArgumentMatchers.anyLong
import org.mockito.Mock
import org.mockito.Mockito
@OptIn(ExperimentalCoroutinesApi::class)
internal class LoadBgWorkerTest : TestBase() {
@Mock lateinit var dataWorkerStorage: DataWorkerStorage
@Mock lateinit var workerClasses: WorkerClasses
@Mock lateinit var sp: SP
@Mock lateinit var fabricPrivacy: FabricPrivacy
@Mock lateinit var rxBus: RxBus
@Mock lateinit var dateUtil: DateUtil
@Mock lateinit var nsAndroidClient: NSAndroidClient
@Mock lateinit var rh: ResourceHelper
@Mock lateinit var profileFunction: ProfileFunction
@Mock lateinit var config: Config
@Mock lateinit var uiInteraction: UiInteraction
@Mock lateinit var dataSyncSelector: DataSyncSelector
@Mock lateinit var repository: AppRepository
@Mock lateinit var receiverStatusStore: ReceiverStatusStore
private lateinit var nsClientV3Plugin: NSClientV3Plugin
private lateinit var nsClientReceiverDelegate: NsClientReceiverDelegate
private lateinit var sut: LoadBgWorker
private val injector = HasAndroidInjector {
AndroidInjector {
if (it is LoadBgWorker) {
it.aapsLogger = aapsLogger
it.fabricPrivacy = fabricPrivacy
it.dataWorkerStorage = dataWorkerStorage
it.sp = sp
it.rxBus = rxBus
it.context = context
it.dateUtil = dateUtil
it.nsClientV3Plugin = nsClientV3Plugin
it.workerClasses = workerClasses
}
}
}
@BeforeEach
fun setUp() {
Mockito.`when`(context.applicationContext).thenReturn(context)
Mockito.`when`(context.androidInjector()).thenReturn(injector.androidInjector())
nsClientReceiverDelegate = NsClientReceiverDelegate(rxBus, rh, sp, receiverStatusStore)
nsClientV3Plugin = NSClientV3Plugin(
injector, aapsLogger, aapsSchedulers, rxBus, rh, context, fabricPrivacy, sp, nsClientReceiverDelegate, config, dateUtil, uiInteraction, dataSyncSelector,
profileFunction, repository
)
}
@Test
fun notInitializedAndroidClient() = runTest {
sut = TestListenableWorkerBuilder<LoadBgWorker>(context).build()
val result = sut.doWorkAndLog()
Assertions.assertTrue(result is ListenableWorker.Result.Failure)
}
@Test
fun doWork() = runTest {
nsClientV3Plugin.nsAndroidClient = nsAndroidClient
sut = TestListenableWorkerBuilder<LoadBgWorker>(context).build()
Mockito.`when`(nsAndroidClient.getSgvsNewerThan(anyLong(), anyLong())).thenReturn(NSAndroidClient.ReadResponse(200, 0, emptyList()))
var result = sut.doWorkAndLog()
Assertions.assertTrue(result is ListenableWorker.Result.Success)
}
}

View file

@ -3,11 +3,12 @@ package info.nightscout.workflow
import android.content.Context
import androidx.work.WorkerParameters
import info.nightscout.core.utils.worker.LoggingWorker
import kotlinx.coroutines.Dispatchers
class DummyWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.IO) {
override fun doWorkAndLog(): Result = Result.success()
override suspend fun doWorkAndLog(): Result = Result.success()
}

View file

@ -9,12 +9,13 @@ import info.nightscout.interfaces.aps.Loop
import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.rx.events.Event
import info.nightscout.rx.events.EventNewBG
import kotlinx.coroutines.Dispatchers
import javax.inject.Inject
class InvokeLoopWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.Default) {
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
@Inject lateinit var iobCobCalculator: IobCobCalculator
@ -31,7 +32,7 @@ class InvokeLoopWorker(
the event causing the calculation is not EventNewBg.
<p>
*/
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
val data = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as InvokeLoopData?
?: return Result.failure(workDataOf("Error" to "missing input data"))

View file

@ -15,12 +15,13 @@ import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
import kotlinx.coroutines.Dispatchers
import javax.inject.Inject
class LoadBgDataWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.Default) {
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
@Inject lateinit var dateUtil: DateUtil
@ -57,7 +58,7 @@ class LoadBgDataWorker(
}
}
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
val data = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as LoadBgData?
?: return Result.failure(workDataOf("Error" to "missing input data"))

View file

@ -16,18 +16,20 @@ import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.rx.bus.RxBus
import info.nightscout.shared.interfaces.ResourceHelper
import kotlinx.coroutines.Dispatchers
import javax.inject.Inject
class PrepareBasalDataWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.Default) {
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var rh: ResourceHelper
@Inject lateinit var rxBus: RxBus
private var ctx: Context
init {
ctx = rh.getThemedCtx(context)
}
@ -37,7 +39,7 @@ class PrepareBasalDataWorker(
val overviewData: OverviewData
)
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
val data = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as PrepareBasalData?
?: return Result.failure(workDataOf("Error" to "missing input data"))

View file

@ -17,12 +17,13 @@ import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.interfaces.utils.Round
import info.nightscout.shared.interfaces.ResourceHelper
import kotlinx.coroutines.Dispatchers
import javax.inject.Inject
class PrepareBgDataWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.Default) {
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
@Inject lateinit var profileFunction: ProfileFunction
@ -35,7 +36,7 @@ class PrepareBgDataWorker(
val overviewData: OverviewData
)
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
val data = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as PrepareBgData?
?: return Result.failure(workDataOf("Error" to "missing input data"))

View file

@ -13,12 +13,13 @@ import info.nightscout.interfaces.iob.IobCobCalculator
import info.nightscout.interfaces.profile.DefaultValueHelper
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.shared.interfaces.ResourceHelper
import kotlinx.coroutines.Dispatchers
import javax.inject.Inject
class PrepareBucketedDataWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.Default) {
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
@Inject lateinit var profileFunction: ProfileFunction
@ -30,7 +31,7 @@ class PrepareBucketedDataWorker(
val overviewData: OverviewData
)
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
val data = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as PrepareBucketedData?
?: return Result.failure(workDataOf("Error" to "missing input data"))

View file

@ -34,6 +34,7 @@ import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.utils.DateUtil
import kotlinx.coroutines.Dispatchers
import javax.inject.Inject
import kotlin.math.abs
import kotlin.math.max
@ -42,7 +43,7 @@ import kotlin.math.min
class PrepareIobAutosensGraphDataWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.Default) {
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
@Inject lateinit var dateUtil: DateUtil
@ -114,7 +115,7 @@ class PrepareIobAutosensGraphDataWorker(
}
}
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
val data = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as PrepareIobAutosensData?
?: return Result.failure(workDataOf("Error" to "missing input data"))

View file

@ -20,6 +20,7 @@ import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.rx.bus.RxBus
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.utils.T
import kotlinx.coroutines.Dispatchers
import java.util.Calendar
import javax.inject.Inject
import kotlin.math.ceil
@ -29,7 +30,7 @@ import kotlin.math.min
class PreparePredictionsWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.Default) {
@Inject lateinit var injector: HasAndroidInjector
@Inject lateinit var overviewData: OverviewData
@ -48,7 +49,7 @@ class PreparePredictionsWorker(
val overviewData: OverviewData
)
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
val data = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as PreparePredictionsData?
?: return Result.failure(workDataOf("Error" to "missing input data"))

View file

@ -18,13 +18,14 @@ import info.nightscout.interfaces.profile.Profile
import info.nightscout.interfaces.profile.ProfileFunction
import info.nightscout.rx.bus.RxBus
import info.nightscout.shared.interfaces.ResourceHelper
import kotlinx.coroutines.Dispatchers
import javax.inject.Inject
import kotlin.math.max
class PrepareTemporaryTargetDataWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.Default) {
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
@Inject lateinit var profileFunction: ProfileFunction
@ -33,6 +34,7 @@ class PrepareTemporaryTargetDataWorker(
@Inject lateinit var loop: Loop
@Inject lateinit var rxBus: RxBus
private var ctx: Context
init {
ctx = rh.getThemedCtx(context)
}
@ -41,7 +43,7 @@ class PrepareTemporaryTargetDataWorker(
val overviewData: OverviewData
)
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
val data = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as PrepareTemporaryTargetData?
?: return Result.failure(workDataOf("Error" to "missing input data"))

View file

@ -28,12 +28,13 @@ import info.nightscout.interfaces.utils.Round
import info.nightscout.rx.bus.RxBus
import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.utils.T
import kotlinx.coroutines.Dispatchers
import javax.inject.Inject
class PrepareTreatmentsDataWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.Default) {
@Inject lateinit var dataWorkerStorage: DataWorkerStorage
@Inject lateinit var profileFunction: ProfileFunction
@ -48,7 +49,7 @@ class PrepareTreatmentsDataWorker(
val overviewData: OverviewData
)
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
val data = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as PrepareTreatmentsData?
?: return Result.failure(workDataOf("Error" to "missing input data"))

View file

@ -8,17 +8,18 @@ import info.nightscout.core.workflow.CalculationWorkflow
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventUpdateOverviewGraph
import kotlinx.coroutines.Dispatchers
import javax.inject.Inject
class UpdateGraphWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.IO) {
@Inject lateinit var rxBus: RxBus
@Inject lateinit var activePlugin: ActivePlugin
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
if (inputData.getString(CalculationWorkflow.JOB) == CalculationWorkflow.MAIN_CALCULATION)
activePlugin.activeOverview.overviewBus.send(EventUpdateOverviewGraph("UpdateGraphWorker"))
else

View file

@ -7,17 +7,18 @@ import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventUpdateOverviewIobCob
import info.nightscout.rx.events.EventUpdateOverviewSensitivity
import kotlinx.coroutines.Dispatchers
import javax.inject.Inject
class UpdateIobCobSensWorker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.IO) {
@Inject lateinit var rxBus: RxBus
@Inject lateinit var activePlugin: ActivePlugin
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
activePlugin.activeOverview.overviewBus.send(EventUpdateOverviewIobCob("UpdateIobCobSensWorker"))
activePlugin.activeOverview.overviewBus.send(EventUpdateOverviewSensitivity("UpdateIobCobSensWorker"))
return Result.success()

View file

@ -7,7 +7,6 @@ import androidx.work.workDataOf
import dagger.android.HasAndroidInjector
import info.nightscout.core.events.EventIobCalculationProgress
import info.nightscout.core.extensions.target
import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.core.utils.receivers.DataWorkerStorage
import info.nightscout.core.utils.worker.LoggingWorker
import info.nightscout.core.workflow.CalculationWorkflow
@ -31,6 +30,7 @@ import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
import kotlinx.coroutines.Dispatchers
import java.util.Calendar
import java.util.GregorianCalendar
import javax.inject.Inject
@ -42,7 +42,7 @@ import kotlin.math.roundToLong
class IobCobOref1Worker(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.Default) {
@Inject lateinit var sp: SP
@Inject lateinit var rxBus: RxBus
@ -66,7 +66,7 @@ class IobCobOref1Worker(
val cause: Event?
)
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
val data = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as IobCobOref1WorkerData?
?: return Result.success(workDataOf("Error" to "missing input data"))
@ -85,11 +85,11 @@ class IobCobOref1Worker(
val bucketedData = ads.bucketedData
val autosensDataTable = ads.autosensDataTable
if (bucketedData == null || bucketedData.size < 3) {
aapsLogger.debug(LTag.AUTOSENS, {"Aborting calculation thread (No bucketed data available): ${data.reason}"})
aapsLogger.debug(LTag.AUTOSENS) { "Aborting calculation thread (No bucketed data available): ${data.reason}" }
return Result.success(workDataOf("Error" to "Aborting calculation thread (No bucketed data available): ${data.reason}"))
}
val prevDataTime = ads.roundUpTime(bucketedData[bucketedData.size - 3].timestamp)
aapsLogger.debug(LTag.AUTOSENS, {"Prev data time: " + dateUtil.dateAndTimeString(prevDataTime)})
aapsLogger.debug(LTag.AUTOSENS) { "Prev data time: " + dateUtil.dateAndTimeString(prevDataTime) }
var previous = autosensDataTable[prevDataTime]
// start from oldest to be able sub cob
for (i in bucketedData.size - 4 downTo 0) {
@ -144,12 +144,12 @@ class IobCobOref1Worker(
val hourAgoData = ads.getAutosensDataAtTime(hourAgo)
if (hourAgoData != null) {
val initialIndex = autosensDataTable.indexOfKey(hourAgoData.time)
aapsLogger.debug(LTag.AUTOSENS, { ">>>>> bucketed_data.size()=" + bucketedData.size + " i=" + i + " hourAgoData=" + hourAgoData.toString() })
aapsLogger.debug(LTag.AUTOSENS) { ">>>>> bucketed_data.size()=" + bucketedData.size + " i=" + i + " hourAgoData=" + hourAgoData.toString() }
var past = 1
// try {
while (past < 12) {
val ad = autosensDataTable.valueAt(initialIndex + past)
aapsLogger.debug(LTag.AUTOSENS, { ">>>>> past=" + past + " ad=" + ad?.toString() })
aapsLogger.debug(LTag.AUTOSENS) { ">>>>> past=" + past + " ad=" + ad?.toString() }
/*
if (ad == null) {
aapsLogger.debug(LTag.AUTOSENS, {autosensDataTable.toString()})
@ -185,7 +185,7 @@ class IobCobOref1Worker(
// break
// }
} else {
aapsLogger.debug(LTag.AUTOSENS, ">>>>> bucketed_data.size()=" + bucketedData.size + " i=" + i + " hourAgoData=" + "null")
aapsLogger.debug(LTag.AUTOSENS) { ">>>>> bucketed_data.size()=${bucketedData.size} i=$i hourAgoData=null" }
}
}
val recentCarbTreatments = repository.getCarbsDataFromTimeToTimeExpanded(bgTime - T.mins(5).msecs(), bgTime, true).blockingGet()
@ -291,7 +291,7 @@ class IobCobOref1Worker(
// add an extra negative deviation if a high temp target is running and exercise mode is set
// TODO AS-FIX
@Suppress("SimplifyBooleanWithConstants")
@Suppress("SimplifyBooleanWithConstants", "KotlinConstantConditions")
if (false && sp.getBoolean(info.nightscout.core.utils.R.string.key_high_temptarget_raises_sensitivity, SMBDefaults.high_temptarget_raises_sensitivity)) {
val tempTarget = repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet()
if (tempTarget is ValueWrapper.Existing && tempTarget.value.target() >= 100) {
@ -307,14 +307,13 @@ class IobCobOref1Worker(
if (min in 0..4 && hours % 2 == 0) autosensData.extraDeviation.add(0.0)
previous = autosensData
if (bgTime < dateUtil.now()) autosensDataTable.put(bgTime, autosensData)
aapsLogger.debug(
LTag.AUTOSENS,
{"Running detectSensitivity from: " + dateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + dateUtil.dateAndTimeString(bgTime) + " lastDataTime:" + ads.lastDataTime(dateUtil)}
)
aapsLogger.debug(LTag.AUTOSENS) {
"Running detectSensitivity from: " + dateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + dateUtil.dateAndTimeString(bgTime) + " lastDataTime:" + ads.lastDataTime(dateUtil)
}
val sensitivity = activePlugin.activeSensitivity.detectSensitivity(ads, oldestTimeWithData, bgTime)
aapsLogger.debug(LTag.AUTOSENS, "Sensitivity result: $sensitivity")
autosensData.autosensResult = sensitivity
aapsLogger.debug(LTag.AUTOSENS, {autosensData.toString()})
aapsLogger.debug(LTag.AUTOSENS) { autosensData.toString() }
}
data.iobCobCalculator.ads = ads
Thread {
@ -323,7 +322,7 @@ class IobCobOref1Worker(
}.start()
} finally {
rxBus.send(EventIobCalculationProgress(CalculationWorkflow.ProgressData.IOB_COB_OREF, 100, data.cause))
aapsLogger.debug(LTag.AUTOSENS, {"AUTOSENSDATA thread ended: ${data.reason}"})
aapsLogger.debug(LTag.AUTOSENS) { "AUTOSENSDATA thread ended: ${data.reason}" }
profiler.log(LTag.AUTOSENS, "IobCobOref1Thread", start)
}
return Result.success()

View file

@ -28,6 +28,7 @@ import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP
import info.nightscout.shared.utils.DateUtil
import info.nightscout.shared.utils.T
import kotlinx.coroutines.Dispatchers
import javax.inject.Inject
import kotlin.math.abs
import kotlin.math.max
@ -37,7 +38,7 @@ import kotlin.math.roundToLong
class IobCobOrefWorker @Inject internal constructor(
context: Context,
params: WorkerParameters
) : LoggingWorker(context, params) {
) : LoggingWorker(context, params, Dispatchers.Default) {
@Inject lateinit var sp: SP
@Inject lateinit var rxBus: RxBus
@ -61,15 +62,15 @@ class IobCobOrefWorker @Inject internal constructor(
val cause: Event?
)
override fun doWorkAndLog(): Result {
override suspend fun doWorkAndLog(): Result {
val data = dataWorkerStorage.pickupObject(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) as IobCobOrefWorkerData?
?: return Result.success(workDataOf("Error" to "missing input data"))
val start = dateUtil.now()
try {
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA thread started: ${data.reason}")
aapsLogger.debug(LTag.AUTOSENS) { "AUTOSENSDATA thread started: ${data.reason}" }
if (!profileFunction.isProfileValid("IobCobThread")) {
aapsLogger.debug(LTag.AUTOSENS, "Aborting calculation thread (No profile): ${data.reason}")
aapsLogger.debug(LTag.AUTOSENS) { "Aborting calculation thread (No profile): ${data.reason}" }
return Result.success(workDataOf("Error" to "app still initializing"))
}
//log.debug("Locking calculateSensitivityData");
@ -79,17 +80,17 @@ class IobCobOrefWorker @Inject internal constructor(
val bucketedData = ads.bucketedData
val autosensDataTable = ads.autosensDataTable
if (bucketedData == null || bucketedData.size < 3) {
aapsLogger.debug(LTag.AUTOSENS, "Aborting calculation thread (No bucketed data available): ${data.reason}")
aapsLogger.debug(LTag.AUTOSENS) { "Aborting calculation thread (No bucketed data available): ${data.reason}" }
return Result.success(workDataOf("Error" to "Aborting calculation thread (No bucketed data available): ${data.reason}"))
}
val prevDataTime = ads.roundUpTime(bucketedData[bucketedData.size - 3].timestamp)
aapsLogger.debug(LTag.AUTOSENS, "Prev data time: " + dateUtil.dateAndTimeString(prevDataTime))
aapsLogger.debug(LTag.AUTOSENS) { "Prev data time: " + dateUtil.dateAndTimeString(prevDataTime) }
var previous = autosensDataTable[prevDataTime]
// start from oldest to be able sub cob
for (i in bucketedData.size - 4 downTo 0) {
rxBus.send(EventIobCalculationProgress(CalculationWorkflow.ProgressData.IOB_COB_OREF, 100 - (100.0 * i / bucketedData.size).toInt(), data.cause))
if (isStopped) {
aapsLogger.debug(LTag.AUTOSENS, "Aborting calculation thread (trigger): ${data.reason}")
aapsLogger.debug(LTag.AUTOSENS) { "Aborting calculation thread (trigger): ${data.reason}" }
return Result.failure(workDataOf("Error" to "Aborting calculation thread (trigger): ${data.reason}"))
}
// check if data already exists
@ -103,10 +104,10 @@ class IobCobOrefWorker @Inject internal constructor(
}
val profile = profileFunction.getProfile(bgTime)
if (profile == null) {
aapsLogger.debug(LTag.AUTOSENS, "Aborting calculation thread (no profile): ${data.reason}")
aapsLogger.debug(LTag.AUTOSENS) { "Aborting calculation thread (no profile): ${data.reason}" }
continue // profile not set yet
}
aapsLogger.debug(LTag.AUTOSENS, "Processing calculation thread: ${data.reason} ($i/${bucketedData.size})")
aapsLogger.debug(LTag.AUTOSENS) { "Processing calculation thread: ${data.reason} ($i/${bucketedData.size})" }
val sens = profile.getIsfMgdl(bgTime)
val autosensData = instantiator.provideAutosensDataObject()
autosensData.time = bgTime
@ -138,12 +139,12 @@ class IobCobOrefWorker @Inject internal constructor(
val hourAgoData = ads.getAutosensDataAtTime(hourAgo)
if (hourAgoData != null) {
val initialIndex = autosensDataTable.indexOfKey(hourAgoData.time)
aapsLogger.debug(LTag.AUTOSENS, ">>>>> bucketed_data.size()=" + bucketedData.size + " i=" + i + " hourAgoData=" + hourAgoData.toString())
aapsLogger.debug(LTag.AUTOSENS) { ">>>>> bucketed_data.size()=" + bucketedData.size + " i=" + i + " hourAgoData=" + hourAgoData.toString() }
var past = 1
// try {
while (past < 12) {
val ad = autosensDataTable.valueAt(initialIndex + past)
aapsLogger.debug(LTag.AUTOSENS, ">>>>> past=" + past + " ad=" + ad?.toString())
aapsLogger.debug(LTag.AUTOSENS) { ">>>>> past=" + past + " ad=" + ad?.toString() }
// if (ad == null) {
// aapsLogger.debug(LTag.AUTOSENS, autosensDataTable.toString())
// aapsLogger.debug(LTag.AUTOSENS, bucketedData.toString())
@ -177,7 +178,7 @@ class IobCobOrefWorker @Inject internal constructor(
// break
// }
} else {
aapsLogger.debug(LTag.AUTOSENS, ">>>>> bucketed_data.size()=" + bucketedData.size + " i=" + i + " hourAgoData=" + "null")
aapsLogger.debug(LTag.AUTOSENS) { ">>>>> bucketed_data.size()=${bucketedData.size} i=$i hourAgoData=null" }
}
}
val recentCarbTreatments = repository.getCarbsDataFromTimeToTimeExpanded(bgTime - T.mins(5).msecs(), bgTime, true).blockingGet()
@ -247,12 +248,11 @@ class IobCobOrefWorker @Inject internal constructor(
}
previous = autosensData
if (bgTime < dateUtil.now()) autosensDataTable.put(bgTime, autosensData)
aapsLogger.debug(
LTag.AUTOSENS,
"Running detectSensitivity from: " + dateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + dateUtil.dateAndTimeString(bgTime) + " lastDataTime:" + ads.lastDataTime(dateUtil)
)
aapsLogger.debug(LTag.AUTOSENS) {
"Running detectSensitivity from: ${dateUtil.dateAndTimeString(oldestTimeWithData)} to: ${dateUtil.dateAndTimeString(bgTime)} lastDataTime:${ads.lastDataTime(dateUtil)}"
}
val sensitivity = activePlugin.activeSensitivity.detectSensitivity(ads, oldestTimeWithData, bgTime)
aapsLogger.debug(LTag.AUTOSENS, "Sensitivity result: $sensitivity")
aapsLogger.debug(LTag.AUTOSENS) { "Sensitivity result: $sensitivity" }
autosensData.autosensResult = sensitivity
aapsLogger.debug(LTag.AUTOSENS, autosensData.toString())
}
@ -263,7 +263,7 @@ class IobCobOrefWorker @Inject internal constructor(
}.start()
} finally {
rxBus.send(EventIobCalculationProgress(CalculationWorkflow.ProgressData.IOB_COB_OREF, 100, data.cause))
aapsLogger.debug(LTag.AUTOSENS, "AUTOSENSDATA thread ended: ${data.reason}")
aapsLogger.debug(LTag.AUTOSENS) { "AUTOSENSDATA thread ended: ${data.reason}" }
profiler.log(LTag.AUTOSENS, "IobCobThread", start)
}
return Result.success()