英文:
Ensure an RxWorker never fails
问题
Here is the translated portion of your text:
"我正在实现我的第一个WorkManager
,用于与服务器进行每日同步,可能会返回HTTP错误,因此使createWork()
流失败并调用onError()
,所以在流的订阅中会"抛出" Result.failure()
。
我想确保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())
}
}
}"
If you have any specific questions or need further assistance with your code, please feel free to ask.
英文:
I'm implementing my first WorkManager
for daily sync with the server which could return an HTTP error hence make the createWork()
flow to fail and to call onError()
so a Result.failure()
is "thrown" in the flow's subscription.
I would like to make sure Result.failure()
is never called and always call Result.retry()
.
Here is my 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())
}
}
}
I tried calling Result.retry()
in many different onError()
of the flow but it seems that Result.failure()
is being called in the onError()
of the subscription which I can't override.
So how can I make sure my worker never fails?
答案1
得分: 1
In syncWithServer()
function, you only check result in flatMap
part. However, there might be cases that error might happen before reaching flatMap
part which means Result.retry()
might never be returned. Also, you do not need to specify specific thread as workers run on background thread by default. Here is your worker with changes I mentioned above:
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())
}
}
}
英文:
In syncWithServer()
function, you only check result in flatMap
part. However, there might be cases that error might happen before reaching flatMap
part which means Result.retry()
might never be returned. Also, you do not need to specify specific thread as workers run on background thread by default. Here is your worker with changes I mentioned above:
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())
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论