Observable calls can now be retried, previously all retries were failing

This commit is contained in:
len 2016-07-10 12:14:30 +02:00
parent e08e41ae0d
commit e6190683dd
2 changed files with 37 additions and 14 deletions

View file

@ -5,25 +5,50 @@ import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import rx.Observable import rx.Observable
import rx.subscriptions.Subscriptions import rx.Producer
import java.io.IOException import rx.Subscription
import java.util.concurrent.atomic.AtomicBoolean
fun Call.asObservable(): Observable<Response> { fun Call.asObservable(): Observable<Response> {
return Observable.create { subscriber -> return Observable.create { subscriber ->
subscriber.add(Subscriptions.create { cancel() }) // Since Call is a one-shot type, clone it for each new subscriber.
val call = if (!isExecuted) this else {
// TODO use clone method in OkHttp 3.5
val field = javaClass.getDeclaredField("client").apply { isAccessible = true }
val client = field.get(this) as OkHttpClient
client.newCall(request())
}
// Wrap the call in a helper which handles both unsubscription and backpressure.
val requestArbiter = object : AtomicBoolean(), Producer, Subscription {
override fun request(n: Long) {
if (n == 0L || !compareAndSet(false, true)) return
try { try {
val response = execute() val response = call.execute()
if (!subscriber.isUnsubscribed) { if (!subscriber.isUnsubscribed) {
subscriber.onNext(response) subscriber.onNext(response)
subscriber.onCompleted() subscriber.onCompleted()
} }
} catch (error: IOException) { } catch (error: Exception) {
if (!subscriber.isUnsubscribed) { if (!subscriber.isUnsubscribed) {
subscriber.onError(error) subscriber.onError(error)
} }
} }
} }
override fun unsubscribe() {
call.cancel()
}
override fun isUnsubscribed(): Boolean {
return call.isCanceled
}
}
subscriber.add(requestArbiter)
subscriber.setProducer(requestArbiter)
}
} }
fun OkHttpClient.newCallWithProgress(request: Request, listener: ProgressListener): Call { fun OkHttpClient.newCallWithProgress(request: Request, listener: ProgressListener): Call {

View file

@ -39,8 +39,7 @@ class ReaderSettingsDialog : DialogFragment() {
override fun onViewCreated(view: View, savedState: Bundle?) = with(view) { override fun onViewCreated(view: View, savedState: Bundle?) = with(view) {
viewer.onItemSelectedListener = IgnoreFirstSpinnerListener { position -> viewer.onItemSelectedListener = IgnoreFirstSpinnerListener { position ->
subscriptions += Observable.timer(250, MILLISECONDS) subscriptions += Observable.timer(250, MILLISECONDS, AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { .subscribe {
(activity as ReaderActivity).presenter.updateMangaViewer(position) (activity as ReaderActivity).presenter.updateMangaViewer(position)
activity.recreate() activity.recreate()
@ -50,7 +49,6 @@ class ReaderSettingsDialog : DialogFragment() {
rotation_mode.onItemSelectedListener = IgnoreFirstSpinnerListener { position -> rotation_mode.onItemSelectedListener = IgnoreFirstSpinnerListener { position ->
subscriptions += Observable.timer(250, MILLISECONDS) subscriptions += Observable.timer(250, MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe { .subscribe {
preferences.rotation().set(position + 1) preferences.rotation().set(position + 1)
} }