NSCv3: react to 304 response

This commit is contained in:
Milos Kozak 2023-01-09 23:27:46 +01:00
parent 65f0d17105
commit adbe4e880a
7 changed files with 42 additions and 26 deletions

View file

@ -12,6 +12,7 @@ import dagger.android.HasAndroidInjector
import info.nightscout.core.graph.OverviewData import info.nightscout.core.graph.OverviewData
import info.nightscout.core.utils.fabric.FabricPrivacy import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.core.utils.receivers.DataWorkerStorage import info.nightscout.core.utils.receivers.DataWorkerStorage
import info.nightscout.core.utils.worker.then
import info.nightscout.core.workflow.CalculationWorkflow import info.nightscout.core.workflow.CalculationWorkflow
import info.nightscout.core.workflow.CalculationWorkflow.Companion.JOB import info.nightscout.core.workflow.CalculationWorkflow.Companion.JOB
import info.nightscout.core.workflow.CalculationWorkflow.Companion.MAIN_CALCULATION import info.nightscout.core.workflow.CalculationWorkflow.Companion.MAIN_CALCULATION
@ -221,9 +222,6 @@ class CalculationWorkflowImpl @Inject constructor(
.enqueue() .enqueue()
} }
fun WorkContinuation.then(shouldAdd: Boolean, work: OneTimeWorkRequest): WorkContinuation =
if (shouldAdd) then(work) else this
private fun runOnEventTherapyEventChange() { private fun runOnEventTherapyEventChange() {
WorkManager.getInstance(context) WorkManager.getInstance(context)
.beginUniqueWork( .beginUniqueWork(

View file

@ -110,11 +110,11 @@ class NSAndroidClientImpl(
} }
} }
override suspend fun getSgvs(): List<NSSgvV3> = callWrapper(dispatcher) { override suspend fun getSgvs(): NSAndroidClient.ReadResponse<List<NSSgvV3>> = callWrapper(dispatcher) {
val response = api.getSgvs() val response = api.getSgvs()
if (response.isSuccessful) { if (response.isSuccessful) {
return@callWrapper response.body()?.result?.map(RemoteEntry::toSgv).toNotNull() return@callWrapper NSAndroidClient.ReadResponse(code = response.raw().networkResponse?.code ?: response.code(), lastServerModified = 0, values = response.body()?.result?.map(RemoteEntry::toSgv).toNotNull())
} else { } else {
throw UnsuccessfullNightscoutException() throw UnsuccessfullNightscoutException()
} }
@ -126,17 +126,17 @@ class NSAndroidClientImpl(
if (response.isSuccessful) { if (response.isSuccessful) {
val eTagString = response.headers()["ETag"] val eTagString = response.headers()["ETag"]
val eTag = eTagString?.substring(3, eTagString.length - 1)?.toLong() val eTag = eTagString?.substring(3, eTagString.length - 1)?.toLong()
return@callWrapper NSAndroidClient.ReadResponse(eTag, response.body()?.result?.map(RemoteEntry::toSgv).toNotNull()) return@callWrapper NSAndroidClient.ReadResponse(code = response.raw().networkResponse?.code ?: response.code(), lastServerModified = eTag, values = response.body()?.result?.map(RemoteEntry::toSgv).toNotNull())
} else { } else {
throw UnsuccessfullNightscoutException() throw UnsuccessfullNightscoutException()
} }
} }
override suspend fun getSgvsNewerThan(from: Long, limit: Long): List<NSSgvV3> = callWrapper(dispatcher) { override suspend fun getSgvsNewerThan(from: Long, limit: Long): NSAndroidClient.ReadResponse<List<NSSgvV3>> = callWrapper(dispatcher) {
val response = api.getSgvsNewerThan(from, limit) val response = api.getSgvsNewerThan(from, limit)
if (response.isSuccessful) { if (response.isSuccessful) {
return@callWrapper response.body()?.result?.map(RemoteEntry::toSgv).toNotNull() return@callWrapper NSAndroidClient.ReadResponse(code = response.raw().networkResponse?.code ?: response.code(), lastServerModified = 0, values = response.body()?.result?.map(RemoteEntry::toSgv).toNotNull())
} else { } else {
throw UnsuccessfullNightscoutException() throw UnsuccessfullNightscoutException()
} }
@ -208,11 +208,11 @@ class NSAndroidClientImpl(
} }
} }
override suspend fun getTreatmentsNewerThan(createdAt: String, limit: Long): List<NSTreatment> = callWrapper(dispatcher) { override suspend fun getTreatmentsNewerThan(createdAt: String, limit: Long): NSAndroidClient.ReadResponse<List<NSTreatment>> = callWrapper(dispatcher) {
val response = api.getTreatmentsNewerThan(createdAt, limit) val response = api.getTreatmentsNewerThan(createdAt, limit)
if (response.isSuccessful) { if (response.isSuccessful) {
return@callWrapper response.body()?.result?.map(RemoteTreatment::toTreatment).toNotNull() return@callWrapper NSAndroidClient.ReadResponse(code = response.raw().networkResponse?.code ?: response.code(), lastServerModified = 0, values = response.body()?.result?.map(RemoteTreatment::toTreatment).toNotNull())
} else { } else {
throw UnsuccessfullNightscoutException() throw UnsuccessfullNightscoutException()
} }
@ -224,7 +224,8 @@ class NSAndroidClientImpl(
if (response.isSuccessful) { if (response.isSuccessful) {
val eTagString = response.headers()["ETag"] val eTagString = response.headers()["ETag"]
val eTag = eTagString?.substring(3, eTagString.length - 1)?.toLong() val eTag = eTagString?.substring(3, eTagString.length - 1)?.toLong()
return@callWrapper NSAndroidClient.ReadResponse(eTag, response.body()?.result?.map(RemoteTreatment::toTreatment).toNotNull()) return@callWrapper NSAndroidClient.ReadResponse(code = response.raw().networkResponse?.code ?: response.code(), lastServerModified = eTag, values = response.body()?.result?.map
(RemoteTreatment::toTreatment).toNotNull())
} else { } else {
throw UnsuccessfullNightscoutException() throw UnsuccessfullNightscoutException()
} }
@ -333,11 +334,11 @@ class NSAndroidClientImpl(
} }
} }
override suspend fun getFoods(limit: Long): List<NSFood> = callWrapper(dispatcher) { override suspend fun getFoods(limit: Long): NSAndroidClient.ReadResponse<List<NSFood>> = callWrapper(dispatcher) {
val response = api.getFoods(limit) val response = api.getFoods(limit)
if (response.isSuccessful) { if (response.isSuccessful) {
return@callWrapper response.body()?.result?.map(RemoteFood::toNSFood).toNotNull() return@callWrapper NSAndroidClient.ReadResponse(code = response.raw().networkResponse?.code ?: response.code(), lastServerModified = 0, values = response.body()?.result?.map(RemoteFood::toNSFood).toNotNull())
} else { } else {
throw UnsuccessfullNightscoutException() throw UnsuccessfullNightscoutException()
} }
@ -441,7 +442,7 @@ class NSAndroidClientImpl(
if (response.isSuccessful) { if (response.isSuccessful) {
val eTagString = response.headers()["ETag"] val eTagString = response.headers()["ETag"]
val eTag = eTagString?.substring(3, eTagString.length - 1)?.toLong() val eTag = eTagString?.substring(3, eTagString.length - 1)?.toLong()
return@callWrapper NSAndroidClient.ReadResponse(eTag, response.body()?.result.toNotNull()) return@callWrapper NSAndroidClient.ReadResponse(code = response.raw().networkResponse?.code ?: response.code(), lastServerModified = eTag, values = response.body()?.result.toNotNull())
} else { } else {
throw UnsuccessfullNightscoutException() throw UnsuccessfullNightscoutException()
} }

View file

@ -12,6 +12,7 @@ import org.json.JSONObject
interface NSAndroidClient { interface NSAndroidClient {
class ReadResponse<T>( class ReadResponse<T>(
val code: Int,
val lastServerModified: Long?, val lastServerModified: Long?,
val values: T val values: T
) )
@ -21,13 +22,13 @@ interface NSAndroidClient {
suspend fun getStatus(): Status suspend fun getStatus(): Status
suspend fun getLastModified(): LastModified suspend fun getLastModified(): LastModified
suspend fun getSgvs(): List<NSSgvV3> suspend fun getSgvs(): ReadResponse<List<NSSgvV3>>
suspend fun getSgvsModifiedSince(from: Long, limit: Long): ReadResponse<List<NSSgvV3>> suspend fun getSgvsModifiedSince(from: Long, limit: Long): ReadResponse<List<NSSgvV3>>
suspend fun getSgvsNewerThan(from: Long, limit: Long): List<NSSgvV3> suspend fun getSgvsNewerThan(from: Long, limit: Long): ReadResponse<List<NSSgvV3>>
suspend fun createSvg(nsSgvV3: NSSgvV3): CreateUpdateResponse suspend fun createSvg(nsSgvV3: NSSgvV3): CreateUpdateResponse
suspend fun updateSvg(nsSgvV3: NSSgvV3): CreateUpdateResponse suspend fun updateSvg(nsSgvV3: NSSgvV3): CreateUpdateResponse
suspend fun getTreatmentsNewerThan(createdAt: String, limit: Long): List<NSTreatment> suspend fun getTreatmentsNewerThan(createdAt: String, limit: Long): ReadResponse<List<NSTreatment>>
suspend fun getTreatmentsModifiedSince(from: Long, limit: Long): ReadResponse<List<NSTreatment>> suspend fun getTreatmentsModifiedSince(from: Long, limit: Long): ReadResponse<List<NSTreatment>>
suspend fun createDeviceStatus(nsDeviceStatus: NSDeviceStatus): CreateUpdateResponse suspend fun createDeviceStatus(nsDeviceStatus: NSDeviceStatus): CreateUpdateResponse
@ -38,7 +39,7 @@ interface NSAndroidClient {
suspend fun createTreatment(nsTreatment: NSTreatment): CreateUpdateResponse suspend fun createTreatment(nsTreatment: NSTreatment): CreateUpdateResponse
suspend fun updateTreatment(nsTreatment: NSTreatment): CreateUpdateResponse suspend fun updateTreatment(nsTreatment: NSTreatment): CreateUpdateResponse
suspend fun getFoods(limit: Long): List<NSFood> suspend fun getFoods(limit: Long): ReadResponse<List<NSFood>>
//suspend fun getFoodsModifiedSince(from: Long, limit: Long): ReadResponse<List<NSFood>> //suspend fun getFoodsModifiedSince(from: Long, limit: Long): ReadResponse<List<NSFood>>
suspend fun createFood(nsFood: NSFood): CreateUpdateResponse suspend fun createFood(nsFood: NSFood): CreateUpdateResponse

View file

@ -0,0 +1,8 @@
package info.nightscout.core.utils.worker
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkContinuation
fun WorkContinuation.then(runIf: Boolean, work: OneTimeWorkRequest): WorkContinuation =
if (runIf) then(work) else this

View file

@ -8,6 +8,7 @@ import androidx.work.WorkerParameters
import androidx.work.workDataOf import androidx.work.workDataOf
import info.nightscout.core.utils.receivers.DataWorkerStorage import info.nightscout.core.utils.receivers.DataWorkerStorage
import info.nightscout.core.utils.worker.LoggingWorker import info.nightscout.core.utils.worker.LoggingWorker
import info.nightscout.core.utils.worker.then
import info.nightscout.interfaces.sync.NsClient import info.nightscout.interfaces.sync.NsClient
import info.nightscout.interfaces.workflow.WorkerClasses import info.nightscout.interfaces.workflow.WorkerClasses
import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl import info.nightscout.plugins.sync.nsShared.StoreDataForDbImpl
@ -51,14 +52,14 @@ class LoadBgWorker(
try { try {
val sgvs: List<NSSgvV3> val sgvs: List<NSSgvV3>
val response: NSAndroidClient.ReadResponse<List<NSSgvV3>>? val response: NSAndroidClient.ReadResponse<List<NSSgvV3>>?
if (isFirstLoad) sgvs = nsAndroidClient.getSgvsNewerThan(lastLoaded, 500) if (isFirstLoad) response = nsAndroidClient.getSgvsNewerThan(lastLoaded, 500)
else { else {
response = nsAndroidClient.getSgvsModifiedSince(lastLoaded, 500) response = nsAndroidClient.getSgvsModifiedSince(lastLoaded, 500)
sgvs = response.values
response.lastServerModified?.let { nsClientV3Plugin.lastLoadedSrvModified.collections.entries = it } response.lastServerModified?.let { nsClientV3Plugin.lastLoadedSrvModified.collections.entries = it }
nsClientV3Plugin.storeLastLoadedSrvModified() nsClientV3Plugin.storeLastLoadedSrvModified()
nsClientV3Plugin.scheduleIrregularExecution() // Idea is to run after 5 min after last BG nsClientV3Plugin.scheduleIrregularExecution() // Idea is to run after 5 min after last BG
} }
sgvs = response.values
aapsLogger.debug("SGVS: $sgvs") aapsLogger.debug("SGVS: $sgvs")
if (sgvs.isNotEmpty()) { if (sgvs.isNotEmpty()) {
val action = if (isFirstLoad) "RCV-FIRST" else "RCV" val action = if (isFirstLoad) "RCV-FIRST" else "RCV"
@ -70,7 +71,11 @@ class LoadBgWorker(
JOB_NAME, JOB_NAME,
ExistingWorkPolicy.APPEND_OR_REPLACE, ExistingWorkPolicy.APPEND_OR_REPLACE,
OneTimeWorkRequest.Builder(workerClasses.nsClientSourceWorker).setInputData(dataWorkerStorage.storeInputData(sgvs)).build() OneTimeWorkRequest.Builder(workerClasses.nsClientSourceWorker).setInputData(dataWorkerStorage.storeInputData(sgvs)).build()
).then(OneTimeWorkRequest.Builder(LoadBgWorker::class.java).build()).enqueue() )
// response 304 == Not modified (happens when date > srvModified => bad time on phone or server during upload
.then(response.code != 304, OneTimeWorkRequest.Builder(LoadBgWorker::class.java).build())
.then(response.code == 304, OneTimeWorkRequest.Builder(LoadTreatmentsWorker::class.java).build())
.enqueue()
} else { } else {
// End first load // End first load
if (isFirstLoad) { if (isFirstLoad) {

View file

@ -37,7 +37,7 @@ class LoadFoodsWorker(
// Read full collection every 5th attempt // Read full collection every 5th attempt
runBlocking { runBlocking {
if (nsClientV3Plugin.lastLoadedSrvModified.collections.foods++ % 5 == 0L) { if (nsClientV3Plugin.lastLoadedSrvModified.collections.foods++ % 5 == 0L) {
val foods: List<NSFood> = nsAndroidClient.getFoods(1000) val foods: List<NSFood> = nsAndroidClient.getFoods(1000).values
aapsLogger.debug("FOODS: $foods") aapsLogger.debug("FOODS: $foods")
rxBus.send(EventNSClientNewLog("RCV", "${foods.size} FOODs")) rxBus.send(EventNSClientNewLog("RCV", "${foods.size} FOODs"))
// Schedule processing of fetched data // Schedule processing of fetched data

View file

@ -8,6 +8,7 @@ import androidx.work.WorkerParameters
import androidx.work.workDataOf import androidx.work.workDataOf
import info.nightscout.core.utils.receivers.DataWorkerStorage import info.nightscout.core.utils.receivers.DataWorkerStorage
import info.nightscout.core.utils.worker.LoggingWorker import info.nightscout.core.utils.worker.LoggingWorker
import info.nightscout.core.utils.worker.then
import info.nightscout.interfaces.nsclient.StoreDataForDb import info.nightscout.interfaces.nsclient.StoreDataForDb
import info.nightscout.interfaces.sync.NsClient import info.nightscout.interfaces.sync.NsClient
import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin import info.nightscout.plugins.sync.nsclientV3.NSClientV3Plugin
@ -47,15 +48,14 @@ class LoadTreatmentsWorker(
val response: NSAndroidClient.ReadResponse<List<NSTreatment>>? val response: NSAndroidClient.ReadResponse<List<NSTreatment>>?
if (isFirstLoad) { if (isFirstLoad) {
val lastLoadedIso = dateUtil.toISOString(lastLoaded) val lastLoadedIso = dateUtil.toISOString(lastLoaded)
treatments = nsAndroidClient.getTreatmentsNewerThan(lastLoadedIso, 500) response = nsAndroidClient.getTreatmentsNewerThan(lastLoadedIso, 500)
response = NSAndroidClient.ReadResponse(0, treatments)
} }
else { else {
response = nsAndroidClient.getTreatmentsModifiedSince(lastLoaded, 500) response = nsAndroidClient.getTreatmentsModifiedSince(lastLoaded, 500)
treatments = response.values
response.lastServerModified?.let { nsClientV3Plugin.lastLoadedSrvModified.collections.treatments = it } response.lastServerModified?.let { nsClientV3Plugin.lastLoadedSrvModified.collections.treatments = it }
nsClientV3Plugin.storeLastLoadedSrvModified() nsClientV3Plugin.storeLastLoadedSrvModified()
} }
treatments = response.values
aapsLogger.debug("TREATMENTS: $treatments") aapsLogger.debug("TREATMENTS: $treatments")
if (treatments.isNotEmpty()) { if (treatments.isNotEmpty()) {
val action = if (isFirstLoad) "RCV-FIRST" else "RCV" val action = if (isFirstLoad) "RCV-FIRST" else "RCV"
@ -68,7 +68,10 @@ class LoadTreatmentsWorker(
OneTimeWorkRequest.Builder(ProcessTreatmentsWorker::class.java) OneTimeWorkRequest.Builder(ProcessTreatmentsWorker::class.java)
.setInputData(dataWorkerStorage.storeInputData(response)) .setInputData(dataWorkerStorage.storeInputData(response))
.build() .build()
).then(OneTimeWorkRequest.Builder(LoadTreatmentsWorker::class.java).build()) )
// response 304 == Not modified (happens when date > srvModified => bad time on phone or server during upload
.then(response.code != 304, OneTimeWorkRequest.Builder(LoadTreatmentsWorker::class.java).build())
.then(response.code == 304, OneTimeWorkRequest.Builder(LoadFoodsWorker::class.java).build())
.enqueue() .enqueue()
} else { } else {
// End first load // End first load