Skip to content

Commit

Permalink
Add a SyncJobStatus result callback amid Sync retries
Browse files Browse the repository at this point in the history
  • Loading branch information
ndegwamartin committed Aug 23, 2023
1 parent 0cae350 commit bb1f2eb
Showing 1 changed file with 35 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import androidx.work.CoroutineWorker
import androidx.work.Data
import androidx.work.WorkerParameters
import androidx.work.workDataOf
import ca.uhn.fhir.context.FhirContext
import com.google.android.fhir.FhirEngine
import com.google.android.fhir.FhirEngineProvider
import com.google.android.fhir.OffsetDateTimeTypeAdapter
Expand All @@ -29,13 +30,17 @@ import com.google.android.fhir.sync.upload.UploaderImpl
import com.google.gson.ExclusionStrategy
import com.google.gson.FieldAttributes
import com.google.gson.GsonBuilder
import java.nio.charset.StandardCharsets
import java.time.OffsetDateTime
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import org.apache.commons.io.IOUtils
import org.hl7.fhir.r4.model.OperationOutcome
import retrofit2.HttpException
import timber.log.Timber

/** A WorkManager Worker that handles periodic sync. */
Expand Down Expand Up @@ -91,6 +96,9 @@ abstract class FhirSyncWorker(appContext: Context, workerParams: WorkerParameter
)
.apply { subscribe(flow) }
.synchronize()

if (result is SyncJobStatus.Failed) onFailedSyncJobResult(result)

val output = buildWorkData(result)

// await/join is needed to collect states completely
Expand Down Expand Up @@ -118,6 +126,33 @@ abstract class FhirSyncWorker(appContext: Context, workerParams: WorkerParameter
}
}

open fun onFailedSyncJobResult(failedSyncJobStatus: SyncJobStatus.Failed) {
try {
CoroutineScope(Dispatchers.IO).launch {
val jsonParser = FhirContext.forR4().newJsonParser()

(failedSyncJobStatus).exceptions.filterIsInstance<HttpException>().forEach {
resourceSyncHTTPException ->
val operationOutcome =
jsonParser.parseResource(
IOUtils.toString(
resourceSyncHTTPException.response()?.errorBody()?.byteStream(),
StandardCharsets.UTF_8
)
) as OperationOutcome

operationOutcome.issue.forEach { operationOutcome ->
Timber.e(
"SERVER ${operationOutcome.severity} - HTTP ${resourceSyncHTTPException.code()} | Code - ${operationOutcome.code} | Diagnostics - ${operationOutcome.diagnostics}"
)
}
}
}
} catch (e: Exception) {
Timber.e(e)
}
}

private fun buildWorkData(state: SyncJobStatus): Data {
return workDataOf(
// send serialized state and type so that consumer can convert it back
Expand Down

0 comments on commit bb1f2eb

Please sign in to comment.