Skip to content
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

Question on validity of SubscriberBlackboxVerification.required_spec201_blackbox_mustSignalDemandViaSubscriptionRequest #233

Closed
purplefox opened this issue Mar 3, 2015 · 21 comments · Fixed by #252

Comments

@purplefox
Copy link

Hi folks,

This test is currently failing when run against Vert.x.

The test appears to expect Subscription.request(..) to be called sometime shortly after the onSubscribe method of the Subscriber is called.

From the docs, it appears this is trying to validate Subscriber requirement 2.1:

https://github.com/reactive-streams/reactive-streams-jvm#2.1

"A Subscriber MUST signal demand via Subscription.request(long n) to receive onNext signals."

However, I can't see anything in the above that says request() must be invoked when the onSubscribe method is called.

The Vert.x subscriber implementation won't call Subscription.request until some time later when the user has actually set a handler on the subscriber.

So I would like to question the validity of this test.

@ktoso
Copy link
Contributor

ktoso commented Mar 3, 2015

We never force anyone to synchronously call things, in fact in Akka all these things are asynchronous as well, so I don't think this is the problem here.

This test contains:

        final long n = stage.expectRequest();// assuming subscriber wants to consume elements...

the expectRequest uses a timeout, more specifically - the timeout you provide to TestEnvironment as constructor argument. The error message you got probably when this test failed should have included the timeout as well, so you can adjust it to what suits your impls.

Unless you're stating the TCK can't require people to request()... but then I mean, it can't do anything without this.. :-)

Sources:

@purplefox
Copy link
Author

I'm not claiming the test requires subscription.request() to be called synchronously after onSubscribe is called.
But it does require it to be called sometime afterwards, without any other interactions going on. This does not appear to be a valid requirement - at least I can't see anywhere in the spec that says "onSubscribe should cause subscription.requestMore" to be called, but I could be missing something.

@purplefox
Copy link
Author

Let me explain this with some more detail...

The Vert.x Subscriber implementation is called ReactiveReadStream:
https://github.com/vert-x3/vertx-reactive-streams/blob/master/src/main/java/io/vertx/ext/reactivestreams/ReactiveReadStream.java

It would be used something like this:

ReactiveReadStream rrs = ReactiveReadStream.create();
MyPublisher publisher = new MyPublisher();
publisher.subscribe(rrs); // Position A
rrs.handler(buffer -> System.out.println("Got some data")); // Position B

The TCK seems to assume that requestMore is called at position A in the above code, whereas with Vert.x it's called at position B.

It seems to be that it is implementation dependent exactly when requestMore gets called, but the TCK is assuming otherwise.

@purplefox
Copy link
Author

On the basis that when requestMore gets called is implementation dependent, then one way of fixing the TCK test would be to provide a new method on SubscriberBlackboxVerification which can be implemented by me which calls the implementation specific method that ensures the initial requestMore gets called, e.g. I would implement this on my class that extends SubscriberBlackboxVerification:

@OverRide
public void callInitialRequestMore() {
myimplementation.handler(buff -> });
}

@drewhk
Copy link
Contributor

drewhk commented Mar 3, 2015

This seems reasonable, the spec does not require when to call request().

@purplefox
Copy link
Author

(BTW, sorry about the crappy formatting in the above comments)

@ktoso
Copy link
Contributor

ktoso commented Mar 3, 2015

Thanks for the code example, this explained a bit.
Seems like we indeed might have to provide such hook - I'll give it a shot today in the evening.

Thanks for the excellent feedback; It's very interesting how differently each impl has tackled the smaller nuances of the spec :-)

@purplefox
Copy link
Author

No problem! Thanks for helping me with this :)

@viktorklang
Copy link
Contributor

@ktoso what's the status here?

@ktoso
Copy link
Contributor

ktoso commented Mar 14, 2015

Need to re-attack this one, hoping to PR over the weekend.

@ktoso
Copy link
Contributor

ktoso commented Mar 24, 2015

Been trying to get to it, but under some pressure in other project.
Hoping to get to it soon, it's important and non-trivial (tried once and failed, was tired though), I consider this a must for 1.0, so Tim's impl doesn't need to revert to hacks to pass the TCK.

@viktorklang
Copy link
Contributor

@ktoso Let me know if you want me to pull some strings.

@ktoso
Copy link
Contributor

ktoso commented Mar 24, 2015

Would be very cool actually, I'm a bit overloaded right now. Mind giving this one a shot?

@viktorklang
Copy link
Contributor

@ktoso It'll be easier for me to make you less overloaded than to figure out what is left to be fixed here. :)

@rkuhn
Copy link
Member

rkuhn commented Mar 25, 2015

We’ll have to defer this until next Monday unless someone else wants to pick it up—sorry for the NoResourcesRightNowException.

@viktorklang
Copy link
Contributor

@rkuhn @ktoso If it is possible to do a quick writeup what's left to do and how to verify, I can try to allocate more resources with my OCTO-allocator. So we can ship the next RC this week.

@ktoso
Copy link
Contributor

ktoso commented Mar 25, 2015

As much as I'd like to work on this now, there's not enough hours in a day so that I could squeeze it in this week, given other project involvements. Not sure if it would be merged in time for this RC if implemented today btw?

Quick summary is:

  • some impls do not trigger the initial request() call when they get the subscription, they do it after some external signal triggers them
  • we must provide a method called triggerRequest(Subscriber) (the subscriber under test, passing it into the method is preferred as userland does not need a var for it then) in both SubscriberVerifications
  • it must have an empty body by default, users should be able to override it such that they can trigger execution, like for example subscriber.seriouslyRun()
  • this needs to be called whenever we want the subscriber to do requests. I'm assuming this means after handing out a subscription, and when a whitebox probe tries to force requesting (from memory, may be mistaken on whitebox).

@purplefox is using a workaround currently, as seen here:

Goal of this change is to not force Tim to use this hack.

@viktorklang
Copy link
Contributor

@ktoso No need to apologize, I fully understand the predicament.

I'll see if I can free some time to work on this so we can get 1.0.0 out the door sooner.
Of course, any of the @reactive-streams/contributors are encouraged to help out!

@viktorklang
Copy link
Contributor

A good way of implementing this would be to create a simple AsyncSubscriber impl (based off / extending the examples one) and have it request from upstream only by external event, then implement the Blackbox and Whitebox verification and fix all tests that fail by delegating to a method that allows the implementer to call their trigger.

Unless someone else gets to it before me I'll try to get this done either this evening or tomorrow.

@viktorklang
Copy link
Contributor

In case anybody decides to pick this up until I have some more minutes available, here's my WIP-branch which has a commit now with a reproducer that fails the build: https://github.com/reactive-streams/reactive-streams-jvm/tree/wip-233-support-manual-demand-%E2%88%9A

@viktorklang
Copy link
Contributor

Did I get it right?

#252

viktorklang added a commit that referenced this issue Mar 27, 2015
viktorklang added a commit that referenced this issue Mar 29, 2015
viktorklang added a commit that referenced this issue Mar 30, 2015
…demand-√

Fixes #233 by implementing support for triggered demand in in the SubscriberBlackboxVerification
akarnokd added a commit to akarnokd/reactive-streams that referenced this issue Nov 3, 2017
* Repairs formatting issue of tables in spec README

* Modifies rules 1.09 and 2.13 to mandate `java.lang.NullPointerException` be thrown.

Updates the TCK, Spec and example implementations.

* Fixes reactive-streams#211 by clarifying

* Fixes reactive-streams#210 by removing 1.12 and repurposing its TCK checks for 1.09

* Clarifies the signalling sequence in the spec and
 adds TCK verification to ensure signal ordering is proper,
 also amends the examples to reflect the spec change.

* Publish 1.0.0.RC2
fix reactive-streams#215

* Fixes reactive-streams#217 by including the examples project in the publish task

* =tck minor test name fixup, it is a required test

* fix reactive-streams#212 issue on spec 213 testing wrt Processor

*  RC3 release /w reactive-streams#222 fix

* remove rule 1:12 (produce same elements to all Subscribers)

This rule is in conflict with 1:11 which allows a Publisher to treat
multiple Subscribers as either as unicast or multicast recipients. The
verification of proper multicast behavior (which 1:12 specified) has
been retained, the test methods renamed accordingly.

* fix three left-over references to deleted rule 1:12

* Fixed wrong footnote reference in README.md

* Addresses a couple of typos in the examples for AsyncSubscriber and SyncSubscriber

* !TCK clarify what error publisher is
+ add better readme on what this method is
+ add better javadoc on this method
- removes reference to old style spec annotation from readme
+ proposing to change method name to "createFailed..." as it is the
  wording used in the spec and reactive manifesto (footnote 1.1)
+ more info in tck/README that it is not legal to signal on* before sub
Resolves reactive-streams#237, reactive-streams#235

* +tck reactive-streams#236 example subscriber whitebox tested, and whitebox fixed

* add space to javadoc

* +TCK verifyNoAsyncErrors now by default waits, fixes spec111
Resolves reactive-streams#239

* =tck general tck/readme.md cleanup so it matches current code / spec
Resolves reactive-streams#99
Depends on reactive-streams#241

* Addresses PR review comments for reactive-streams#246

* Update CopyrightWaivers.txt

* +tck explains createElement in more useful terms

resolves reactive-streams#231

* +tck reactive-streams#232 explain which tests are mendatory to be "compliant"

* Update SubscriberWhiteboxVerification.java

Fixes Javadoc generation on Java8+ by having to manually qualify nested classes.

* Fixes reactive-streams#233 by implementing support for triggered demand in in the SubscriberBlackboxVerification

* Travis PR validation using both JDK 6 and 8

By validating on both JDKs we know the project even builds on 8,
while not using features (classes) from JDK8 - so it's still usable for JDK6 projects.

Resolves reactive-streams#254

* Small touchups to the TCK README.md

* Release 1.0.0.RC4

* Cancel the subscription after receiving all of the pertinent emissions (reactive-streams#259).

* Test that 'required_spec317_mustNotSignalOnErrorWhenPendingAboveLongMaxValue' completes in a timely manner for fully synchronous publishers (reactive-streams#259).

* =tck untested spec308 rule method name adjusted

* -tck rm undocumented and unused publisherReferenceGCTimeoutMillis method

* update version to 1.0.0.RC5

* Updating documentation to reflect the current version: RC5

* update ref to 1.0.0.final

* change 1.0.0.final to 1.0.0 and make sure OSGI manifest has the bundle version

*  OSGI fix

*  OSGI fix...

* Disambiguate "processing elements"

The document generally refers to "elements" as objects traversing a stream. I initially considered simply editing "processing elements" to read "processing components", but there's a section devoted to the definition of this, so better to link them.

* Added per request of @viktorklang in reactive-streams#269

* add CC0 label to README

* =tck reactive-streams#279 improve completion latch error message

* Rename SyncSybscriber.foreach to whenNext

* Update README.md

Spelling of the company name is Red Hat, not RedHat.

* I hereby represent [...] public domain [...] entirety of my contributions.

Requested by @viktorklang.

* Log test output events to the console

* Remove "preview" qualifier from README.

* Unbreaks TravisCI OpenJDK6 hostname too long crash

* Second attempt at unbreaking the Travis build

* Third attempt at fixing the Travis builds

* +tck reactive-streams#308 allow configuring "no events during N time" separately

* Update to Gradle 2.12

* Reintegrate dangling footnote in Publisher section.

- integrate the footnote in rule 1.9
- sign the Copyright Statement

* Asynchronous vs Synchronous Processing: reword "push-based stream"

* =tck fixes minor misalignment between code and comment, found via .NET port

Semantics remain exacly the same, the error we're testing here is about
signaling one more element if request comes in again (which we'll do
anyway, regardless of status of this flag)

* adjust Subscription.cancel javadoc because cancel command does not have to be called asynchronously

* Updating Typesafe to Lightbend

* Fix a typo in org.reactivestreams.example.unicast.AsyncSubscriber

* Add @seratch to CopyrightWaivers.txt

* Fixes reactive-streams#333 by adding license headers to /examples/*

* Adds a Glossary, Intent-sections and harmonizes verbiage

* Clarifying that object equality is a.equals(b) in Intent for 2.12

* add license header to API directory

* add license header to TCK

* Fix missing cancel() from in tests that don't consume the entire source

* Run with default TestEnvironment settings.

* Update CopyrightWaivers.txt

* =build reactive-streams#349 equal osgi manifest version as real version

To have a tangible PR to talk about.
Probably enough to resolve reactive-streams#349

Would be followed up with change to 1.0.1 eventually.

* Add Javadoc explanation to the TCK test methods about what they do

* Don't import org.reactivestreams.tck.TestEnvironment

* Fix missing Javadoc tags

* TCK: Request -1 in 309 instead of a random non-positive number

* Remove the Random instance as well.

* Keep the randomness.

* Fixing typos in README.md

* Minor rewording of 2.6 to make it easier to understand. (reactive-streams#342)

* Minor rewording of 2.6 to make it easier to understand.

* Fix spelling errors and clarify a couple of sentences

* extra coordination

* Remove vague statements, be more specific in others

* Update javadoc based on ktoso's feedback

* Use the wording eagery for error publisher test 104

* Address feedback, add links to the rules in the javadoc

* SubscriberBlackboxVerificationRules explained

* Non-BC for TCK: Corrects a typo in test method from *Compuatation to *Computation

* Adding a glossary item for external synchronization

* Repointing links to sources in README to current main release

* =tck reactive-streams#362 signal onComplete in 201 blackbox verification

* +tck reactive-streams#362 complete subscriber under test once done in 205

* +tck reactive-streams#362 wait for request signal in 209, and new additional tests

* =tck check isCancelled in 205 blackbox; sample the state sometimes

* =tck reactive-streams#362 blackbox 209 must issue onSubscribe before any other signal

* Clarifies the meaning of "stochastic" for skipStochasticTests()

* add additional test for optional_spec111.

* now test verifies https://github.com/reactive-streams/reactive-streams-jvm#1.11 and
https://github.com/reactive-streams/reactive-streams-jvm#1.5 for publishers, if they support multiple subscribers.

* add delegate to IdentityProcessorVerification.

* add tests for optional_spec111_registeredSubscribersMustReceiveOnNextOrOnCompleteSignals.

* additional happy and the failure cases.
* clear typos and change comments.
* add new PublisherVerification for multi-subscribers tests.

* removed onSubscribe constructor call.

renamed Demand -> CancelableSubscription.

* Change subscription remove logic.

* add myself to CopyrightWaivers.

* fix tests by using proxied subscriber,
thanks Viktor for helping push this fix

* Be consistent in reference style

We use the `#.##` style in referring to rules everywhere, this one ref was using a different style - fixed that.

* Switching to consistent use of apostrophe in spec

* More apostrophe fixes

* add patriknw to CopyrightWaivers

* Version 1.0.1

* =spec reactive-streams#384 amend spec to allow not mentioning rule number in exception message

* Update README.md

* =tck reactive-streams#384 dont check for cause message when checking 3.9

* Updating versions to 1.0.1-RC2 and clarifying changes in RELEASE-NOTES.md

* Fix links to "Terminal state" (reactive-streams#389)

* Fix links to "Terminal state"

* add angelsanz to CopyrightWaivers.txt

* Preparing 1.0.1 (reactive-streams#390)

* Bridge between Reactive-Streams and JDK 9 Flow API (reactive-streams#296)

* Bridge between Reactive-Streams and JDK 9 Flow API

* Apply changes based on ktoso's feedback

* Use oraclejdk9, resolve build.gradle conflict

* Change txt/code to use "Reactive Streams" as designator

* NPE to use the updated parameter name.

* Rename bridge class, tester class (+javadoc)

* Java 9 Flow bridge: add Subscriber converters (reactive-streams#399)

* Java 9 Flow bridge: add Subscriber converters

* Fix return type javadoc

* Example synchronous range Publisher (reactive-streams#395)

* Example synchronous range Publisher

* Udpated with rule numbers in comments

* Mentioning rule 3.9 again in emit()

* Move classes to the unicast package.

* [WIP] TCK for j.u.c.Flow types "directly" (reactive-streams#398)

* Add JDK9 TCK, using adapters

* Fixing wrapping and unwrapping of the wrappers themselves.

* Renames the converters to "toX" for RS and "toFlowX" for Flow.

Fixes so that the dist url for gradle is http iso https (TravisCI bug?)

Adds regression test for bridge converters.

* fix formatting

* cleanup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants