确保 RxWorker 永不失败
Ensure an RxWorker never fails
我正在实施我的第一个 WorkManager
与服务器的日常同步,这可能 return 一个 HTTP 错误因此使 createWork()
流程失败并调用 onError()
所以 Result.failure()
在流程的订阅中是 "thrown"。
我想确保永远不会调用 Result.failure()
并始终调用 Result.retry()
。
这是我的 RxWorker
class DailySyncWorker (appContext: Context, workerParams: WorkerParameters): RxWorker(appContext, workerParams) {
private val disposable: CompositeDisposable = CompositeDisposable()
private val httpManager = AppFactory.httpManager()
private val dbManager = AppFactory.dbManager()
private val prefsManager = AppFactory.sharedManager(appContext)
companion object {
const val WORKER_NAME = "com.blabla.blah.DAILY_SYNC_WORKER"
}
override fun createWork(): Single<Result> {
Timber.e("Worker - Executing ${System.currentTimeMillis() - prefsManager.lastMillis}")
prefsManager.lastMillis = System.currentTimeMillis()
return dbManager.alarmDAO.getNewAlarms(prefsManager.lastSyncedAlarm)
.flatMap { alarms -> syncWithServer(alarms)
.doOnSuccess {
if(alarms.size != 0)
prefsManager.lastSyncedAlarm = alarms[0].date // The query is in descending order, the first record is the last recorded alarm
}
}
}
private fun syncWithServer(alarms: MutableList<Alarm>): Single<Result> {
val syncRequestModel = SyncRequestModel(alarms)
return if(alarms.size != 0)
httpManager.service().create(SyncService::class.java).sync(syncRequestModel)
.observeOn(Schedulers.io())
.flatMap { result ->
if(result == "OK") { // TODO - the service has not been created yet
Timber.e("Worker - success")
Single.just(Result.success())
} else {
Timber.e("Worker - failure")
Single.just(Result.retry())
}
}
else {
Timber.e("Worker - no sync is necessary")
Single.just(Result.success())
}
}
}
我尝试在许多不同的 onError()
流程中调用 Result.retry()
,但似乎 Result.failure()
在订阅的 onError()
中被调用,我可以' t覆盖。
那么我怎样才能确保我的工人永远不会失败?
在syncWithServer()
函数中,你只检查flatMap
部分的结果。但是,在到达 flatMap
部分之前可能会发生错误,这意味着 Result.retry()
可能永远不会返回。此外,默认情况下,您不需要在后台线程上将特定线程指定为 workers 运行。这是您的工作人员,其中包含我上面提到的更改:
class DailySyncWorker (appContext: Context, workerParams: WorkerParameters): RxWorker(appContext, workerParams) {
private val disposable: CompositeDisposable = CompositeDisposable()
private val httpManager = AppFactory.httpManager()
private val dbManager = AppFactory.dbManager()
private val prefsManager = AppFactory.sharedManager(appContext)
companion object {
const val WORKER_NAME = "com.blabla.blah.DAILY_SYNC_WORKER"
}
override fun createWork(): Single<Result> {
Timber.e("Worker - Executing ${System.currentTimeMillis() - prefsManager.lastMillis}")
prefsManager.lastMillis = System.currentTimeMillis()
return dbManager.alarmDAO.getNewAlarms(prefsManager.lastSyncedAlarm)
.flatMap { alarms -> syncWithServer(alarms)
.doOnSuccess {
if(alarms.size != 0)
prefsManager.lastSyncedAlarm = alarms[0].date // The query is in descending order, the first record is the last recorded alarm
}
}
.onErrorReturnItem(Result.retry()) // Here is error handling
}
private fun syncWithServer(alarms: MutableList<Alarm>): Single<Result> {
val syncRequestModel = SyncRequestModel(alarms)
return if(alarms.size != 0)
httpManager.service().create(SyncService::class.java).sync(syncRequestModel)
.flatMap { result ->
if(result == "OK") { // TODO - the service has not been created yet
Timber.e("Worker - success")
Single.just(Result.success())
} else {
Timber.e("Worker - failure")
Single.just(Result.retry())
}
}
else {
Timber.e("Worker - no sync is necessary")
Single.just(Result.success())
}
}
}
我正在实施我的第一个 WorkManager
与服务器的日常同步,这可能 return 一个 HTTP 错误因此使 createWork()
流程失败并调用 onError()
所以 Result.failure()
在流程的订阅中是 "thrown"。
我想确保永远不会调用 Result.failure()
并始终调用 Result.retry()
。
这是我的 RxWorker
class DailySyncWorker (appContext: Context, workerParams: WorkerParameters): RxWorker(appContext, workerParams) {
private val disposable: CompositeDisposable = CompositeDisposable()
private val httpManager = AppFactory.httpManager()
private val dbManager = AppFactory.dbManager()
private val prefsManager = AppFactory.sharedManager(appContext)
companion object {
const val WORKER_NAME = "com.blabla.blah.DAILY_SYNC_WORKER"
}
override fun createWork(): Single<Result> {
Timber.e("Worker - Executing ${System.currentTimeMillis() - prefsManager.lastMillis}")
prefsManager.lastMillis = System.currentTimeMillis()
return dbManager.alarmDAO.getNewAlarms(prefsManager.lastSyncedAlarm)
.flatMap { alarms -> syncWithServer(alarms)
.doOnSuccess {
if(alarms.size != 0)
prefsManager.lastSyncedAlarm = alarms[0].date // The query is in descending order, the first record is the last recorded alarm
}
}
}
private fun syncWithServer(alarms: MutableList<Alarm>): Single<Result> {
val syncRequestModel = SyncRequestModel(alarms)
return if(alarms.size != 0)
httpManager.service().create(SyncService::class.java).sync(syncRequestModel)
.observeOn(Schedulers.io())
.flatMap { result ->
if(result == "OK") { // TODO - the service has not been created yet
Timber.e("Worker - success")
Single.just(Result.success())
} else {
Timber.e("Worker - failure")
Single.just(Result.retry())
}
}
else {
Timber.e("Worker - no sync is necessary")
Single.just(Result.success())
}
}
}
我尝试在许多不同的 onError()
流程中调用 Result.retry()
,但似乎 Result.failure()
在订阅的 onError()
中被调用,我可以' t覆盖。
那么我怎样才能确保我的工人永远不会失败?
在syncWithServer()
函数中,你只检查flatMap
部分的结果。但是,在到达 flatMap
部分之前可能会发生错误,这意味着 Result.retry()
可能永远不会返回。此外,默认情况下,您不需要在后台线程上将特定线程指定为 workers 运行。这是您的工作人员,其中包含我上面提到的更改:
class DailySyncWorker (appContext: Context, workerParams: WorkerParameters): RxWorker(appContext, workerParams) {
private val disposable: CompositeDisposable = CompositeDisposable()
private val httpManager = AppFactory.httpManager()
private val dbManager = AppFactory.dbManager()
private val prefsManager = AppFactory.sharedManager(appContext)
companion object {
const val WORKER_NAME = "com.blabla.blah.DAILY_SYNC_WORKER"
}
override fun createWork(): Single<Result> {
Timber.e("Worker - Executing ${System.currentTimeMillis() - prefsManager.lastMillis}")
prefsManager.lastMillis = System.currentTimeMillis()
return dbManager.alarmDAO.getNewAlarms(prefsManager.lastSyncedAlarm)
.flatMap { alarms -> syncWithServer(alarms)
.doOnSuccess {
if(alarms.size != 0)
prefsManager.lastSyncedAlarm = alarms[0].date // The query is in descending order, the first record is the last recorded alarm
}
}
.onErrorReturnItem(Result.retry()) // Here is error handling
}
private fun syncWithServer(alarms: MutableList<Alarm>): Single<Result> {
val syncRequestModel = SyncRequestModel(alarms)
return if(alarms.size != 0)
httpManager.service().create(SyncService::class.java).sync(syncRequestModel)
.flatMap { result ->
if(result == "OK") { // TODO - the service has not been created yet
Timber.e("Worker - success")
Single.just(Result.success())
} else {
Timber.e("Worker - failure")
Single.just(Result.retry())
}
}
else {
Timber.e("Worker - no sync is necessary")
Single.just(Result.success())
}
}
}