setting push token via background scheduler which will automatically retry

This commit is contained in:
Adam Brown 2022-04-04 20:47:05 +01:00
parent 0aa157b5df
commit 81d88b51fc
5 changed files with 60 additions and 12 deletions

View File

@ -32,6 +32,7 @@ import app.dapk.st.matrix.device.internal.ApiMessage
import app.dapk.st.matrix.http.MatrixHttpClient import app.dapk.st.matrix.http.MatrixHttpClient
import app.dapk.st.matrix.http.ktor.KtorMatrixHttpClientFactory import app.dapk.st.matrix.http.ktor.KtorMatrixHttpClientFactory
import app.dapk.st.matrix.message.* import app.dapk.st.matrix.message.*
import app.dapk.st.matrix.push.PushService
import app.dapk.st.matrix.push.installPushService import app.dapk.st.matrix.push.installPushService
import app.dapk.st.matrix.push.pushService import app.dapk.st.matrix.push.pushService
import app.dapk.st.matrix.room.* import app.dapk.st.matrix.room.*
@ -54,6 +55,7 @@ import app.dapk.st.work.TaskRunnerModule
import app.dapk.st.work.WorkModule import app.dapk.st.work.WorkModule
import app.dapk.st.work.WorkScheduler import app.dapk.st.work.WorkScheduler
import com.squareup.sqldelight.android.AndroidSqliteDriver import com.squareup.sqldelight.android.AndroidSqliteDriver
import io.ktor.client.features.*
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import java.time.Clock import java.time.Clock
@ -118,6 +120,7 @@ internal class AppModule(context: Application, logger: MatrixLogger) {
matrixModules, matrixModules,
domainModules, domainModules,
trackingModule, trackingModule,
workModule,
imageLoaderModule, imageLoaderModule,
context, context,
buildMeta, buildMeta,
@ -131,6 +134,7 @@ internal class FeatureModules internal constructor(
private val matrixModules: MatrixModules, private val matrixModules: MatrixModules,
private val domainModules: DomainModules, private val domainModules: DomainModules,
private val trackingModule: TrackingModule, private val trackingModule: TrackingModule,
private val workModule: WorkModule,
imageLoaderModule: ImageLoaderModule, imageLoaderModule: ImageLoaderModule,
context: Context, context: Context,
buildMeta: BuildMeta, buildMeta: BuildMeta,
@ -187,6 +191,7 @@ internal class FeatureModules internal constructor(
imageLoaderModule.iconLoader(), imageLoaderModule.iconLoader(),
storeModule.value.roomStore(), storeModule.value.roomStore(),
context, context,
workModule.workScheduler(),
) )
} }
@ -395,7 +400,7 @@ internal class DomainModules(
) { ) {
val pushModule by unsafeLazy { PushModule(matrixModules.push, errorTracker) } val pushModule by unsafeLazy { PushModule(matrixModules.push, errorTracker) }
val taskRunnerModule by unsafeLazy { TaskRunnerModule(TaskRunnerAdapter(matrixModules.matrix::run)) } val taskRunnerModule by unsafeLazy { TaskRunnerModule(TaskRunnerAdapter(matrixModules.matrix::run, AppTaskRunner(matrixModules.push))) }
} }
class BackgroundWorkAdapter(private val workScheduler: WorkScheduler) : BackgroundScheduler { class BackgroundWorkAdapter(private val workScheduler: WorkScheduler) : BackgroundScheduler {
@ -410,14 +415,50 @@ class BackgroundWorkAdapter(private val workScheduler: WorkScheduler) : Backgrou
} }
} }
class TaskRunnerAdapter(private val matrixTaskRunner: suspend (MatrixTask) -> MatrixTaskRunner.TaskResult) : TaskRunner { class TaskRunnerAdapter(
private val matrixTaskRunner: suspend (MatrixTask) -> MatrixTaskRunner.TaskResult,
private val appTaskRunner: AppTaskRunner,
) : TaskRunner {
override suspend fun run(tasks: List<TaskRunner.RunnableWorkTask>): List<TaskRunner.TaskResult> { override suspend fun run(tasks: List<TaskRunner.RunnableWorkTask>): List<TaskRunner.TaskResult> {
return tasks.map { return tasks.map {
when (val result = matrixTaskRunner(MatrixTask(it.task.type, it.task.jsonPayload))) { when {
is MatrixTaskRunner.TaskResult.Failure -> TaskRunner.TaskResult.Failure(it.source, canRetry = result.canRetry) it.task.type.startsWith("matrix") -> {
MatrixTaskRunner.TaskResult.Success -> TaskRunner.TaskResult.Success(it.source) when (val result = matrixTaskRunner(MatrixTask(it.task.type, it.task.jsonPayload))) {
is MatrixTaskRunner.TaskResult.Failure -> TaskRunner.TaskResult.Failure(it.source, canRetry = result.canRetry)
MatrixTaskRunner.TaskResult.Success -> TaskRunner.TaskResult.Success(it.source)
}
}
else -> appTaskRunner.run(it)
} }
} }
} }
} }
class AppTaskRunner(
private val pushService: PushService,
) {
suspend fun run(workTask: TaskRunner.RunnableWorkTask): TaskRunner.TaskResult {
return when (val type = workTask.task.type) {
"push_token" -> {
runCatching {
pushService.registerPush(workTask.task.jsonPayload)
}.fold(
onSuccess = { TaskRunner.TaskResult.Success(workTask.source) },
onFailure = {
val canRetry = if (it is ClientRequestException) {
it.response.status.value !in (400 until 500)
} else {
true
}
TaskRunner.TaskResult.Failure(workTask.source, canRetry = canRetry)
}
)
}
else -> throw IllegalArgumentException("Unknown work type: $type")
}
}
}

View File

@ -5,8 +5,6 @@ import app.dapk.st.domain.ApplicationPreferences
import app.dapk.st.domain.ApplicationVersion import app.dapk.st.domain.ApplicationVersion
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
private const val FIRST_VERSION_TO_START_COUNTING_FROM = 3
class BetaVersionUpgradeUseCase( class BetaVersionUpgradeUseCase(
private val applicationPreferences: ApplicationPreferences, private val applicationPreferences: ApplicationPreferences,
private val buildMeta: BuildMeta, private val buildMeta: BuildMeta,
@ -17,7 +15,7 @@ class BetaVersionUpgradeUseCase(
val previousVersion = applicationPreferences.readVersion()?.value val previousVersion = applicationPreferences.readVersion()?.value
val currentVersion = buildMeta.versionCode val currentVersion = buildMeta.versionCode
when (previousVersion) { when (previousVersion) {
null -> currentVersion == FIRST_VERSION_TO_START_COUNTING_FROM null -> false
else -> currentVersion > previousVersion else -> currentVersion > previousVersion
}.also { }.also {
applicationPreferences.setVersion(ApplicationVersion(currentVersion)) applicationPreferences.setVersion(ApplicationVersion(currentVersion))

View File

@ -4,6 +4,7 @@ dependencies {
implementation project(":matrix:services:push") implementation project(":matrix:services:push")
implementation project(":matrix:services:sync") implementation project(":matrix:services:sync")
implementation project(':domains:store') implementation project(':domains:store')
implementation project(":domains:android:work")
implementation project(':domains:android:push') implementation project(':domains:android:push')
implementation project(":domains:android:core") implementation project(":domains:android:core")
implementation project(":core") implementation project(":core")

View File

@ -9,6 +9,7 @@ import app.dapk.st.matrix.push.PushService
import app.dapk.st.matrix.sync.RoomStore import app.dapk.st.matrix.sync.RoomStore
import app.dapk.st.matrix.sync.SyncService import app.dapk.st.matrix.sync.SyncService
import app.dapk.st.push.RegisterFirebasePushTokenUseCase import app.dapk.st.push.RegisterFirebasePushTokenUseCase
import app.dapk.st.work.WorkScheduler
class NotificationsModule( class NotificationsModule(
private val pushService: PushService, private val pushService: PushService,
@ -18,6 +19,7 @@ class NotificationsModule(
private val iconLoader: IconLoader, private val iconLoader: IconLoader,
private val roomStore: RoomStore, private val roomStore: RoomStore,
private val context: Context, private val context: Context,
private val workScheduler: WorkScheduler,
) : ProvidableModule { ) : ProvidableModule {
fun pushUseCase() = pushService fun pushUseCase() = pushService
@ -31,4 +33,6 @@ class NotificationsModule(
) )
private fun notificationManager() = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager private fun notificationManager() = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
fun workScheduler() = workScheduler
} }

View File

@ -7,6 +7,7 @@ import app.dapk.st.core.log
import app.dapk.st.core.module import app.dapk.st.core.module
import app.dapk.st.matrix.common.EventId import app.dapk.st.matrix.common.EventId
import app.dapk.st.matrix.common.RoomId import app.dapk.st.matrix.common.RoomId
import app.dapk.st.work.WorkScheduler
import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage import com.google.firebase.messaging.RemoteMessage
import kotlinx.coroutines.* import kotlinx.coroutines.*
@ -29,10 +30,13 @@ class PushAndroidService : FirebaseMessagingService() {
override fun onNewToken(token: String) { override fun onNewToken(token: String) {
log(PUSH, "new push token received") log(PUSH, "new push token received")
GlobalScope.launch { module.workScheduler().schedule(
module.pushUseCase().registerPush(token) WorkScheduler.WorkTask(
log(PUSH, "token registered") type = "push_token",
} jobId = 2,
jsonPayload = token
)
)
} }
override fun onMessageReceived(message: RemoteMessage) { override fun onMessageReceived(message: RemoteMessage) {