Skip to content

Review of RxJava 2 usage in the project #130

@akarnokd

Description

@akarnokd

Hi. I was asked to review the library's RxJava 2 usage for potential logical or concurrency issues.

Review @ commit: 0147484b

Main issues:

  • AutoDisposingCompletableObserverImpl.java#L45: The DisposableMaybeObserver could be created and setOnce'd before the call to lifecycle.subscribe().
  • AutoDisposingCompletableObserverImpl.java#L52: The mainDisposable could be already set and the delegate currently executing one of its onXXX methods which violates the contract unless it is guaranteed both the lifecycle signal and the onXXX calls happen on the same thread (i.e., forced observeOn(AndroidSchedulers.mainThread())). Possible solution: always call delegate.onSubscribe(this) first, mutually exclude the onXXX signals via an AtomicBoolean once.
  • AutoDisposingCompletableObserverImpl.java#L58: May not be a good idea to leave the delegate non-terminated in this case, if the lifecycle actually can get onComplete.
  • AutoDisposingCompletableObserverImpl.java#L73: synchronized is pointless here.
  • AutoDisposingCompletableObserverImpl.java#L80: synchronized is pointless here. If the purpose was to mutually exclude with #L73 then it is not worth it. If lazySet wins then dispose(ref) will do nothing, if they race, both cases could win probabilistically.
  • AutoDisposingMaybeObserverImpl.java: Same problems as with the CompletableObserver implementation.
  • AutoDisposingObserverImpl.java: Same problems as with the CompletableObserver implementation. Here one would need a HalfSerializer to mutually exclude the onXXX events (as there could be multiple onNext calls).
  • AutoDisposingSingleObserverImpl.java: Same problems as with the CompletableObserver implementation.
  • AutoDisposingSubscriberImpl.java: Same problems as with the CompletableObserver implementation and then some.
  • AutoDisposingSubscriberImpl.java#L80: There is no onStart provided by the API and the delegate.onSubscribe is called after mainSubscription is definitely set: the null check should always pass and thus unnecessary. Note though that if one does the setOnce(mainSubscription) before the lifecycle is attached, one may need to use deferred requesting to not trigger the upstream emission while the code is setting up other things in onSubscribe.
  • ViewAttachEventsObservable.java#L41 If the call is not on the main thread, onSubscribe is not called which can lead to a NullPointerException in the dowstream. The no-op Disposable should be sent to the Observer first.
  • ViewAttachEventsObservable.java#L51: The Observer may cancel immediately and since the listener is not registered with the view yet, it won't get removed but then added unconditionally. Assuming the events also come from the main thread, one could add the listener first, and call onSubscribe next. If adding the listener triggers an event emission immediately, keep the current order and after adding the listener, check if the listener has been disposed in the meantime and remove the listener.
  • LifecycleEventsObservable.java#L78: Same problems as with the ViewAttachEventsObservable.

Minor issues:

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions