-
Notifications
You must be signed in to change notification settings - Fork 20
Initial draft for specificationa #5
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
Conversation
3e7d0e7
to
7ba2381
Compare
tck/README.md
Outdated
@@ -0,0 +1 @@ | |||
# Reactive Streams TCK # |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Add link to CONTRIBUTING doc
- Add link to a code of conduct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This just drafted a spec and not aimed to provide everything at once. Im planning to fix TCK readme once we agreed on spec. Then, after first step, going to fix docs. Does it sound good to you?
CONTRIBUTING.md
Outdated
|
||
## Performing Official Releases | ||
|
||
Creating binary artifacts, uploading them to central repositories and declaring these to be an official release of the Reactive Streams project requires the consent of all gatekeepers. The process is initiated by creating a ticket in the `reactive-streams` repository for this purpose and consent is signaled in the same way as for pull requests. The actual work of updating version numbers and publishing the artifacts will typically involve pull requests targeting the affected repositories. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
update reactive-streams
to reactive-streams-js
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
README.md
Outdated
| <a name="1.2">2</a> | A `Publisher` MAY signal fewer `onNext` than requested and terminate the `Subscription` by calling `onComplete` or `onError`. | | ||
| [:bulb:](#1.2 "1.2 explained") | *The intent of this rule is to make it clear that a Publisher cannot guarantee that it will be able to produce the number of elements requested; it simply might not be able to produce them all; it may be in a failed state; it may be empty or otherwise already completed.* | | ||
| <a name="1.3">3</a> | `onSubscribe`, `onNext`, `onError` and `onComplete` signaled to a `Subscriber` MUST be signaled in a [thread-safe](#term_thread-safe) manner—and if performed by multiple threads—use [external synchronization](#term_ext_sync). | | ||
| [:bulb:](#1.3 "1.3 explained") | *The intent of this rule is to make it clear that [external synchronization](#term_ext_sync) must be employed if the Publisher intends to send signals from multiple/different threads. Note, this rule is implemented by default in JavaScript, since it is [single-threaded](#term_single-threaded) within the same context* | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing period after context
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
README.md
Outdated
| <a name="2.6">6</a> | A `Subscriber` MUST call `Subscription.cancel()` if the `Subscription` is no longer needed. | | ||
| [:bulb:](#2.6 "2.6 explained") | *The intent of this rule is to establish that Subscribers cannot just throw Subscriptions away when they are no longer needed, they have to call `cancel` so that resources held by that Subscription can be safely, and timely, reclaimed. An example of this would be a Subscriber which is only interested in a specific element, which would then cancel its Subscription to signal its completion to the Publisher.* | | ||
| <a name="2.7">7</a> | A `Subscriber` MUST ensure that all calls on its `Subscription` take place from the same thread or provide for respective [external synchronization](#term_ext_sync). | | ||
| [:bulb:](#2.7 "2.7 explained") | *The intent of this rule is to establish that [external synchronization](#term_ext_sync) must be added if a Subscriber will be using a Subscription concurrently by two or more threads. Note, this rule is implemented by default in JavaScript, since it is [single-threaded](#term_single-threaded) within the same context* | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing period after context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
README.md
Outdated
| <a name="2.10">10</a> | A `Subscriber` MUST be prepared to receive an `onError` signal with or without a preceding `Subscription.request(n: number | bigint)` call. | | ||
| [:bulb:](#2.10 "2.10 explained") | *The intent of this rule is to establish that Publisher failures may be completely unrelated to signalled demand. This means that Subscribers do not need to poll to find out if the Publisher will not be able to fulfill its requests.* | | ||
| <a name="2.11">11</a> | A `Subscriber` MUST make sure that all calls on its [signal](#term_signal) methods happen-before the processing of the respective signals. I.e. the Subscriber must take care of properly publishing the signal to its processing logic. | | ||
| [:bulb:](#2.11 "2.11 explained") | *The intent of this rule is to establish that it is the responsibility of the Subscriber implementation to make sure that asynchronous processing of its signals are thread safe. See [JMM definition of Happens-Before in section 17.4.5](https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4.5). Note, this rule is implemented by default in JavaScript, since it is [single-threaded](#term_single-threaded) within the same context* | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing period after context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
@OlegDokuka It's a bit tricky to see the diff between the original README/spec and this one—mai I suggest adding the original first and creating the PR against it so the diff is "accurate"? :-) |
@viktorklang sure thing. Give me a minute |
@viktorklang done. Added additional commit as a copy/paste from reactive-streams-jvm, so now you can observe introduced changes in that way -> |
@OlegDokuka Perfect! Thank YOU! ^^ |
@reactive-streams/contributors Please have a look if you're interested! |
@viktorklang dont have an access to that |
@OlegDokuka you should be on @reactive-streams/js-contributors |
Long.MAX_VALUE in JSRegarding usage of
on average results in (on my 2.9 GHz Intel Core i9):
In contrast, the same code but for a plain
on average results in:
which is about 4~5 times slower. From our conversation with @viktorklang on TwitterWhat I saw in Reactor Core JS, which was developed by @akarnokd: David Karnok, developing reactor-core-js implemented that special signal in JS as this -> https://github.com/reactor/reactor-core-js/blob/master/src/subscriber.js#L50 Viktor Klang 11m 10 minutes ago -> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity Viktor Klang 6m 5 minutes ago the problem in js is that precision of calculation which overflows 2^53 becomes incorrect like the following Oleh Dokuka
|
Ahh, even though we tried to rely on incorrect |
I would recommend keeping request_n as Number instead of BigInt. I don't see a need to preserve binary compatibility with other languages within a single language reactive streams implementation, that should be in the domain of binary reactive streams network protocols. RSocket for example limits request_n frames to 2^31-1, so it is up to the RSocket implementation to maintain high/low watermarks and hand out request_n frames up to the requested amount. |
After some thoughts, I concluded and agree with @rdegnan that we could rely on Any thoughts @viktorklang @benlesh? |
@OlegDokuka Hmmm, if there is to be a bridge between implementations in different languages, think for instance in Graal, then that bridge would have to know to translate between Long.MAX_VALUE and Infinity. Do we htink that is going to be an issue? |
@viktorklang I don't think this should be a big deal. I guess if such interop is somewhen, we can always provide an additional bridge for that which will catch |
@OlegDokuka The thing is that such a bridge would have to keep track of cumulative demand which overflows Long.MAX_VALUE too. |
Another option - stick to On the other hand, in real-world scenarios - no-one will request data by |
@OlegDokuka What happens if someone asks for (Long.MAX_VALUE / 10) 10 times in a row? |
https://jsbin.com/nariqatexe/edit?js,console that is funny) |
@viktorklang OK, what if we stick to long max value and leave details of the implementation for vendors. For example, in Reactor, we skip validation of the negative request and provide some StrictSubscriber implementation which follows all the rules and applies to the given subscriber in case it is non-reactor ecosystem one |
@viktorklang provided last fixes to the spec related to the upper limit. Spec keeps clear a requirement of the upper limit equal to If it looks good to you, we can merge it and I will send TCK shortly |
@OlegDokuka Latest commit looks good to me. You might want to check the latest master in reactive-streams-jvm for some updated verbiage, such as: reactive-streams/reactive-streams-jvm@4d6cdb7 Nice work, Oleg! |
Waits resolution for reactive-streams/reactive-streams-jvm#448 so once we have it, amend latest fixes and merge this PR |
This PR provides an initial draft of the Reactive Streams Specification for JavaScript.
At the point, the following PR is aimed to amend the specification and after that provide work for actual implementation of Spec and TCK.