Skip to content

TCK PublisherVerification does not support publishers of empty streams #198

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

Closed
gnp opened this issue Jan 11, 2015 · 8 comments · Fixed by #199
Closed

TCK PublisherVerification does not support publishers of empty streams #198

gnp opened this issue Jan 11, 2015 · 8 comments · Fixed by #199

Comments

@gnp
Copy link

gnp commented Jan 11, 2015

This code in the PublisherVerification class:

  @Override @Test
  public void required_validate_maxElementsFromPublisher() throws Exception {
    assertTrue(maxElementsFromPublisher() > 0, "maxElementsFromPublisher MUST return a number > 0");
  }

Causes an EmptyPublisher class representing an empty stream to fail conformance testing.

An empty stream may be an edge case but it is a legitimate stream, and a Reactive Streams implementation should be able to have such a Publisher. One use case would be testing that Subscribers operate correctly when subscribed to empty streams.

Therefore, TCK should allow a subclass of PublisherVerification to return zero from maxElemensFromPublisher(), and if it does TCK should test that request()-ing any elements at all from the Publisher results in only a call to the Subscriber's onComplete().

@viktorklang
Copy link
Contributor

@gnp Thanks for opening this Issue, we should definitely fix this.

@viktorklang
Copy link
Contributor

It is important to note that it needs to send both onSubscribe and onComplete.

@ktoso
Copy link
Contributor

ktoso commented Jan 11, 2015

Good catch @gnp, thanks for noticing this! We definitely want to support all kinds of valid publishers (recently made it possible for never-onComplete-calling publishers to be tested as well etc).

I'll draft a PR to address this soon :)

@ktoso
Copy link
Contributor

ktoso commented Jan 11, 2015

While updating the TCK to support this (that's the easy part) I found that the spec is not precise about if calling onComplete "eagerly" is fine or not. I think it's something we wanted to prohibit, but can't seem to find a direct rule about it, i.e. nothing in the spec seems to disallow such impl:

// EagerEmptyStream - I assume the spec intends to not allow these
    return new Publisher<Integer>() {
      @Override
      public void subscribe(Subscriber<? super Integer> s) {
        s.onComplete();
      }
    };

The only rules which talk more or less around this area (yet do not prohibit it) are:

  • 1.9 "Invoking Publisher.subscribe MUST return normally. The only legal way to signal failure (or reject a Subscriber) is via the onError method" - it is not mentioning anything about "completing ASAP" as legal way of "rejecting". It's not really a "failure", because there may be an use case like this: "Publisher: well, I can only produce exactly-one element exactly-once, and then I act as if I'm 'empty', if the second subscriber comes in I tell it I'm completed".
  • rule 1.12 in fact re-states the additional sentence mentioned in 1.9: "A Publisher MAY reject calls to its subscribe method if it is unable or unwilling to serve them [1]. If rejecting it MUST do this by calling onError on the Subscriber passed to Publisher.subscribe instead of calling onSubscribe", so also no rules about completing here - only "failing".
  • 2.9 "A Subscriber MUST be prepared to receive an onComplete signal with or without a preceding Subscription.request(long n) call" - so finally some words about onComplete, however not in relation to subscribing (and not requesting).

So the wording of 1.9 more or less seems to imply that we can only "early onError", and not "early onComplete", although it is not stated explicitly, and since completion is not really "failing" I'd say that the onComplete being eager is not specified - and I'm not sure according to the spec if the above Publisher is legal.

Currently the TCK assumed that an onComplete coming in before an onSubscribe is NOT legal, thus I bumped into this case. I can update the TCK to be OK with this in the "empty stream" case of course, but it should be backed by some spec rule I think.

Of course a fully legal and "complete" way to signal this completion is via "complete only once demand is signalled":

    return new Publisher<Integer>() {
      @Override
      public void subscribe(final Subscriber<? super Integer> s) {
        s.onSubscribe(new Subscription() {
          @Override
          public void request(long n) {
            s.onComplete();
          }

          @Override
          public void cancel() {
            // noop
          }
        });
      }
    };

Which does not have any ambiguity problems with the spec AFAICS.

TL;DR: I think we should include some wording in the spec which that explicitly states an onComplete may only be signalled an onSubscribe has been signalled. The current wording does not seem to be precise enough about this I think.

// cc @viktorklang

ktoso added a commit to ktoso/reactive-streams that referenced this issue Jan 12, 2015
@viktorklang
Copy link
Contributor

I find that it is best illustrated in the readme just before the spec:

In response to a call to Publisher.subscribe(Subscriber) the possible invocation sequences for methods on the Subscriber are given by the following protocol:

`onError | (onSubscribe onNext* (onError | onComplete)?)`

I'll answer more in detail later :)

@ktoso
Copy link
Contributor

ktoso commented Jan 12, 2015

Yeah, I did notice that sequence-of-calls diagram, but it's not really reinforced by the spec rules - thought that it would be perhaps safer to extend wording somewhere (1.9?) to do so as well

@ktoso
Copy link
Contributor

ktoso commented Jan 12, 2015

PR submitted #199

ktoso added a commit to ktoso/reactive-streams that referenced this issue Jan 13, 2015
ktoso added a commit to ktoso/reactive-streams that referenced this issue Jan 13, 2015
ktoso added a commit to ktoso/reactive-streams that referenced this issue Jan 13, 2015
ktoso added a commit to ktoso/reactive-streams that referenced this issue Jan 15, 2015
ktoso added a commit to ktoso/reactive-streams that referenced this issue Jan 15, 2015
ktoso added a commit to ktoso/reactive-streams that referenced this issue Jan 15, 2015
ktoso added a commit to ktoso/reactive-streams that referenced this issue Jan 15, 2015
ktoso added a commit to ktoso/reactive-streams that referenced this issue Jan 15, 2015
@rkuhn
Copy link
Member

rkuhn commented Jan 16, 2015

tracking the onComplete issue in #202

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants