-
Notifications
You must be signed in to change notification settings - Fork 7.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Upgrading SyncOnSubscribe from experimental to beta #3780
Conversation
👍 |
@akarnokd is this alright with you? |
I'm not seeing why the change before 1.2? |
I think at Netflix we are comfortable using these going forward. Is there any reason to wait? This only communicates our comfort level with this api slightly more strongly. |
I see the value of |
Okay, fair. I would also like to see some usage and feedback on |
Fine, but since this is a promotion, I'd like a majority vote just like before 1.1. I personally would 👍 for SyncOnSubscribe promotion but I'm still not convinced about |
Okay. I still would like it if we cleaned up the prefetching behavior so the request 1 patterns which we know are detrimental to performance are resolved. |
@abersnaze @zsxwing @benjchristensen any concerns with this api upgrade from experimental to beta? |
Could you open a separate issue with the problem description and example code so we can discuss it and not clutter this PR? |
Do you mean the prefetching/batching behavior of observeOn and flatMap? To confirm, you are in agreement that Experimental to Beta is acceptable for both? |
|
Cool, Yes will do! |
So to confirm you do not up vote this PR as is? |
👍 for |
I've used AsyncOnSubcribe in a couple of places with success. One of which made integrating Elasticsearch's pagination api play nicely with Rx while allowing backpressure semantics to just work. Maybe one can use the following real code as an example of AsyncOnSubscribe usage: import java.util.concurrent.TimeUnit;
import org.elasticsearch.action.ActionRequestBuilder;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchScrollRequestBuilder;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.unit.TimeValue;
import rx.Observable;
import rx.Observable.OnSubscribe;
import rx.observables.AsyncOnSubscribe;
public class ScrollObservable {
private static class ElasticsearchRequestState {
private final Client client;
private final ActionRequestBuilder<?, SearchResponse, ?, ?> request;
private final int pageNumber;
private final long hitCount;
private final TimeValue timeout;
private ElasticsearchRequestState nextState;
private ElasticsearchRequestState(Client client, SearchRequestBuilder request, TimeValue timeout) {
this.client = client;
this.request = request.setScroll(timeout);
this.timeout = timeout;
this.pageNumber = 0;
this.hitCount = 0;
}
private ElasticsearchRequestState(Client client, SearchScrollRequestBuilder request, TimeValue timeout, int pageNumber, long hitCount) {
this.client = client;
this.request = request.setScroll(timeout);
this.timeout = timeout;
this.pageNumber = pageNumber;
this.hitCount = hitCount;
}
public Observable<SearchResponse> getResponse() {
return Observable.defer(() -> Observable.just(request.execute().actionGet()))
.retryWhen(errors -> errors.flatMap(error -> {
if (error instanceof InterruptedException || error.getCause() instanceof InterruptedException) {
return Observable.just(null);
} else {
return Observable.error(error);
}
}))
.doOnNext(r -> {
long currentCount = hitCount + r.getHits().getHits().length;
if (r.getHits().getHits().length > 0 && currentCount < r.getHits().getTotalHits()) {
nextState = new ElasticsearchRequestState(client, client.prepareSearchScroll(r.getScrollId()), timeout, pageNumber + 1, currentCount);
}
});
}
public boolean hasNext() {
return nextState != null;
}
public ElasticsearchRequestState next() {
return nextState;
}
}
public static Observable<SearchResponse> from(final Client client, final SearchRequestBuilder request, final TimeValue timeout) {
OnSubscribe<SearchResponse> os = AsyncOnSubscribe.createStateful(() ->
new ElasticsearchRequestState(client, request, timeout),
(state, requested, observer) -> {
observer.onNext(state.getResponse());
if (state.hasNext()) {
return state.next();
} else {
observer.onCompleted();
return null;
}
});
return Observable.create(os);
}
public static Observable<SearchResponse> from(Client client, SearchRequestBuilder request, long duration, TimeUnit timeUnit) {
return from(client, request, new TimeValue(duration, timeUnit));
}
public static Observable<SearchResponse> from(Client client, SearchRequestBuilder request) {
return from(client, request, new TimeValue(1, TimeUnit.MINUTES));
}
} |
@kurzweil interesting. It seems like you don't actually use the requested amount in producing an observable to return. I'd recommend changing |
@stealthcode It was some time ago, but last time I checked I couldn't find a detailed documentation on how to use these onSubscribe, other than the javadoc, after a quick search. Can you suggest a pointer to such resources if they exist? If they don't exist, could promoting these to BETA include some detailed piece of documentation, like a wiki page giving examples on how and when to use the |
@simonbasle Right now the documentation is pretty sparse on these topics. I would certainly welcome more documentation but don't currently have the time myself. @DavidMGross would you have some cycles to work on detailed documentation for the Here is one relevant SO post. |
thanks @stealthcode |
To add some color here, there's currently no stable APIs for creating observables that do backpressure-aware work deferring. Even just for wrapping a synchronous method that returns a scalar value. This make RxJava use in libraries very challenging since |
What do you mean by
? |
A common pattern for deferring work is |
@JakeWharton would be nice to support this strict deferral of work formally in the API and |
Sure! On Thu, Mar 31, 2016 at 3:35 PM Dave Moten [email protected] wrote:
|
953c483
to
f33873e
Compare
I have taken out |
👍 |
👍 |
I'm currently in a holding pattern waiting to see where Netflix wants me to On Mon, Mar 28, 2016 at 4:28 PM, Aaron Tull [email protected]
David M. Gross |
No description provided.