Skip to content

"Gate" operator #4210

@ghost

Description

I've written a custom RxJava operator and wanted to check whether this was the best way to do what I want and also to make sure it is implemented correctly. Code is here.

My use case for this operator is an Android RecyclerView backed by an Observable, in my case the Observable reads from the local database and might do some network calls. The issue is a user could have hundreds of items produced by this Observable, and each one might require its own network call. Since I don't want to make hundreds of network calls at once, I want the RecyclerView to lazily load the values. Think an inifinitely-scrolling RecyclerView.

What this operator does is it takes an Observable<Long> and whenever that produces a value it will request that many values from the Producer for the actual Observable. For example:

class RecyclerViewGate {
  PublishRelay<Long> relay = PublishRelay.create();
  AtomicBoolean isLoadingBatch = new AtomicBoolean(false);
}


RecyclerViewGate gate = new RecyclerViewGate();


readFromDatabase()
    .buffer(batchSize)
    .lift(GateObservable.blockUsingGate(() -> gate.relay.startWith(1L)))
    .doOnNext(x -> gate.isLoadingBatch.set(true))
    .flatMap(doNetworkRequests())
    .doOnNext(x -> gate.isLoadingBatch.set(false))
    .subscribe(x -> adapter.addItems(x));


void onRecyclerViewScrolled() {
  if (!gate.isLoadingBatch.get() && getLastVisibleItemPosition() + bufferSize > adapter.getItemCount()) {
    gate.relay.call(1L);
  }
}

My implementation seems to work, but I would like an RxJava expert's opinion on whether it's correct (or even if it's a sensible approach) since I've never written an operator before.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions