Advertisement
Guest User

Untitled

a guest
Jul 18th, 2019
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.20 KB | None | 0 0
  1. import com.github.pwittchen.reactivenetwork.library.rx2.Connectivity
  2. import io.reactivex.Completable
  3. import io.reactivex.Flowable
  4. import io.reactivex.FlowableTransformer
  5. import io.reactivex.Observable
  6. import com.rv.user.networkerrorretrier.Result
  7.  
  8. interface NetworkManager {
  9. /**
  10. * Exception used to denote that an operation was performed when network was not available.
  11. */
  12. class NoNetworkException : IllegalStateException()
  13.  
  14. /** @return `true` if is there is an active connection, `false` otherwise.*/
  15. fun isConnected(): Boolean
  16.  
  17. /**
  18. * @return [Observable] that emits whenever there is change in network connection
  19. *
  20. * Note: This observable by default emits item on background thread.
  21. */
  22. fun observeConnectivity(): Observable<Connectivity>
  23.  
  24. /** @return [Observable] emitting true when there is an active connection, false if otherwise
  25. *
  26. * Note: This observable by default emits item on background thread.
  27. */
  28. fun observeNetwork(): Observable<Boolean>
  29.  
  30. /**
  31. * @return [Completable] that completes whenever network connection is reestablished again. If the network
  32. * is available at the time of subscription, then it completes immediately.
  33. */
  34. fun awaitOnline(): Completable {
  35. return observeNetwork()
  36. .filter { isConnected() }
  37. .take(1)
  38. .ignoreElements()
  39. }
  40.  
  41. /**
  42. * [FlowableTransformer] to handle pre and post execution errors caused for limited network access.
  43. *
  44. * 1. Subscribes to `Upstream` directly when network is connected. In case network is
  45. * not available, waits till network is available and retries task by resubscribing to `Upstream`.
  46. * 2. Subscription was already in progress but failed due to missing network error, in that case schedule a retry
  47. * until network is available.
  48. *
  49. * During the wait period, the downstream will initially receive a [Result.Failure] with [NoNetworkException]. By handling
  50. * this exception, you can update UI while the inner upstream waits for network.
  51. */
  52. fun <T> networkAwareResultTransformer(): FlowableTransformer<Result<T>, Result<T>> {
  53. return FlowableTransformer { upstream ->
  54. // Transform the upstream to handle auto retry in case execution failed due to network error.
  55. val networkAwareUpstream = upstream
  56. .switchMap { result ->
  57. // When we have a Failure case due to no network, schedule a resubscription once network is active
  58. if (result is Result.Failure && result.isNetworkError()) {
  59. awaitOnline()
  60. .andThen(upstream)
  61. .startWith(result) // Emit error state so UI can know that network error occurred.
  62. } else {
  63. // Pass source result as is, we don't care about other states.
  64. Flowable.just(result)
  65. }
  66. }
  67.  
  68. return@FlowableTransformer when {
  69. isConnected() -> networkAwareUpstream // Network is connected, pass networkAwareUpstream to handle post execution errors
  70. else -> {
  71. // Emit a Result.Failure<NoNetworkException> initially until network comes back
  72. val initialNetworkErrorPublisher = upstream
  73. .take(1) // Take latest result state alone.
  74. .map {
  75. Result.Failure(it.unSafeValue(), NoNetworkException())
  76. }
  77.  
  78. awaitOnline() // Delay subscription to emission until network comes back
  79. .doOnSubscribe {
  80. println("Waiting for network : $upstream")
  81. }
  82. .doOnComplete {
  83. println("Retrying $upstream after becoming online")
  84. }
  85. .andThen(networkAwareUpstream)
  86. .startWith(initialNetworkErrorPublisher) // Publish initial error state for UI.
  87. }
  88. }
  89. }
  90. }
  91. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement