/** * Modify the behavior of the <i>whole chain</i> of operators upstream of this one to * conditionally clean up elements that get <i>discarded</i> by these operators. * <p> * The {@code discardHook} must be idempotent and safe to use on any instance of the desired * type. * Calls to this method are additive, and the order of invocation of the {@code discardHook} * is the same as the order of declaration (calling {@code .filter(...).doOnDiscard(first).doOnDiscard(second)} * will let the filter invoke {@code first} then {@code second} handlers). * <p> * Two main categories of discarding operators exist: * <ul> * <li>filtering operators, dropping some source elements as part of their designed behavior</li> * <li>operators that prefetch a few elements and keep them around pending a request, but get cancelled/in error</li> * </ul> * These operators are identified in the javadoc by the presence of an {@code onDiscard Support} section. * * @param type the {@link Class} of elements in the upstream chain of operators that * this cleanup hook should take into account. * @param discardHook a {@link Consumer} of elements in the upstream chain of operators * that performs the cleanup. * @return a {@link Mono} that cleans up matching elements that get discarded upstream of it. */ public final <R> Mono<T> doOnDiscard(final Class<R> type, final Consumer<? super R> discardHook) { return subscriberContext(Operators.discardLocalAdapter(type, discardHook)); }
/** * Modify the behavior of the <i>whole chain</i> of operators upstream of this one to * conditionally clean up elements that get <i>discarded</i> by these operators. * <p> * The {@code discardHook} must be idempotent and safe to use on any instance of the desired * type. * Calls to this method are additive, and the order of invocation of the {@code discardHook} * is the same as the order of declaration (calling {@code .filter(...).doOnDiscard(first).doOnDiscard(second)} * will let the filter invoke {@code first} then {@code second} handlers). * <p> * Two main categories of discarding operators exist: * <ul> * <li>filtering operators, dropping some source elements as part of their designed behavior</li> * <li>operators that prefetch a few elements and keep them around pending a request, but get cancelled/in error</li> * </ul> * These operators are identified in the javadoc by the presence of an {@code onDiscard Support} section. * * @param type the {@link Class} of elements in the upstream chain of operators that * this cleanup hook should take into account. * @param discardHook a {@link Consumer} of elements in the upstream chain of operators * that performs the cleanup. * @return a {@link Flux} that cleans up matching elements that get discarded upstream of it. */ public final <R> Flux<T> doOnDiscard(final Class<R> type, final Consumer<? super R> discardHook) { return subscriberContext(Operators.discardLocalAdapter(type, discardHook)); }
@Test public void discardAdapterIsAdditive() { List<String> discardOrder = Collections.synchronizedList(new ArrayList<>(2)); Function<Context, Context> first = Operators.discardLocalAdapter(Number.class, i -> discardOrder.add("FIRST")); Function<Context, Context> second = Operators.discardLocalAdapter(Integer.class, i -> discardOrder.add("SECOND")); Context ctx = first.apply(second.apply(Context.empty())); Consumer<Object> test = ctx.getOrDefault(Hooks.KEY_ON_DISCARD, o -> {}); assertThat(test).isNotNull(); test.accept(1); assertThat(discardOrder).as("consumers were combined").containsExactly("FIRST", "SECOND"); }
@Test public void discardAdapterRejectsNull() { assertThatNullPointerException().isThrownBy(() -> Operators.discardLocalAdapter(null, obj -> {})) .as("type null check") .withMessage("onDiscard must be based on a type"); assertThatNullPointerException().isThrownBy(() -> Operators.discardLocalAdapter(String.class, null)) .as("discardHook null check") .withMessage("onDiscard must be provided a discardHook Consumer"); }
/** * Modify the behavior of the <i>whole chain</i> of operators upstream of this one to * conditionally clean up elements that get <i>discarded</i> by these operators. * <p> * The {@code discardHook} must be idempotent and safe to use on any instance of the desired * type. * Calls to this method are additive, and the order of invocation of the {@code discardHook} * is the same as the order of declaration (calling {@code .filter(...).doOnDiscard(first).doOnDiscard(second)} * will let the filter invoke {@code first} then {@code second} handlers). * <p> * Two main categories of discarding operators exist: * <ul> * <li>filtering operators, dropping some source elements as part of their designed behavior</li> * <li>operators that prefetch a few elements and keep them around pending a request, but get cancelled/in error</li> * </ul> * These operators are identified in the javadoc by the presence of an {@code onDiscard Support} section. * * @param type the {@link Class} of elements in the upstream chain of operators that * this cleanup hook should take into account. * @param discardHook a {@link Consumer} of elements in the upstream chain of operators * that performs the cleanup. * @return a {@link Mono} that cleans up matching elements that get discarded upstream of it. */ public final <R> Mono<T> doOnDiscard(final Class<R> type, final Consumer<? super R> discardHook) { return subscriberContext(Operators.discardLocalAdapter(type, discardHook)); }
/** * Modify the behavior of the <i>whole chain</i> of operators upstream of this one to * conditionally clean up elements that get <i>discarded</i> by these operators. * <p> * The {@code discardHook} must be idempotent and safe to use on any instance of the desired * type. * Calls to this method are additive, and the order of invocation of the {@code discardHook} * is the same as the order of declaration (calling {@code .filter(...).doOnDiscard(first).doOnDiscard(second)} * will let the filter invoke {@code first} then {@code second} handlers). * <p> * Two main categories of discarding operators exist: * <ul> * <li>filtering operators, dropping some source elements as part of their designed behavior</li> * <li>operators that prefetch a few elements and keep them around pending a request, but get cancelled/in error</li> * </ul> * These operators are identified in the javadoc by the presence of an {@code onDiscard Support} section. * * @param type the {@link Class} of elements in the upstream chain of operators that * this cleanup hook should take into account. * @param discardHook a {@link Consumer} of elements in the upstream chain of operators * that performs the cleanup. * @return a {@link Flux} that cleans up matching elements that get discarded upstream of it. */ public final <R> Flux<T> doOnDiscard(final Class<R> type, final Consumer<? super R> discardHook) { return subscriberContext(Operators.discardLocalAdapter(type, discardHook)); }