Skip to content

1.3 imprecise #431

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
davidmoten opened this issue May 22, 2018 · 29 comments
Closed

1.3 imprecise #431

davidmoten opened this issue May 22, 2018 · 29 comments

Comments

@davidmoten
Copy link
Contributor

davidmoten commented May 22, 2018

I was asked for documentation about signals being published serially by a Publisher and looked at 1.3. Seems rather imprecise. It says:

onSubscribe, onNext, onError and onComplete signaled to a Subscriber MUST be signaled in a thread-safe manner—and if performed by multiple threads—use external synchronization.

The vague bit to me is signalled in a thread-safe manner. I think we can be more precise, something like:

signals (onSubscribe, onNext, onError and onComplete) must be signaled to a Subscriber serially.

The comment box for 1.3 could then mention that

the signals may be sent from different threads but there must be happens-before relationships between the signals sent to a Subscriber.

@viktorklang
Copy link
Contributor

Hi @davidmoten,

apologies for the late response.

Good point. Perhaps we should say "sequentially", and if performed by multiple threads, each signal must happen-before the other?

@reactive-streams/contributors Wdyt?

@viktorklang
Copy link
Contributor

@davidmoten Perhaps we should reuse the "external synchronization" verbiage?

@artem-zinnatullin
Copy link

As @davidmoten suggested originally, "serially" (see Serializability, wiki) is a quite common term in multithreading/concurrency literature (also present in RxJava sources) that means "without overlapping in time",

might be a bit better choice than "sequentially" :)

@davidmoten
Copy link
Contributor Author

davidmoten commented Jun 2, 2018

The notion of serial does seem to be more prevalent in the literature. As defined in our glossary external synchronization is still vague just referring to "access coordination" so doesn't really nail things down. We could add serial or serially to the glossary and cover off there the notions of ordering and non-overlap (which we might explicitly mention as well perhaps because the signal going to a Subscriber is not some queued async signal but processed synchronously).

@viktorklang
Copy link
Contributor

@davidmoten

How about:

onSubscribe, onNext, onError and onComplete signaled to a Subscriber MUST be signaled serially—and if performed by multiple threads—use external synchronization.

@vietj
Copy link

vietj commented Jun 2, 2018

@viktorklang when you use the happens-before term, does it also apply to the state managed by these methods ?

@viktorklang
Copy link
Contributor

@vietj That is managed by 2:11

@viktorklang
Copy link
Contributor

Ping @davidmoten

@davidmoten
Copy link
Contributor Author

@viktorklang

onSubscribe, onNext, onError and onComplete signaled to a Subscriber MUST be signaled serially—and if performed by multiple threads—use external synchronization.

Yeah that helps. I think we can do better with the term external synchronization though. All contributors here understand this but a wider audience might be confused by it. When I google "external synchronization" all I see is clock synchronization for distributed systems.

@viktorklang
Copy link
Contributor

@davidmoten Any suggestions there?

@davidmoten
Copy link
Contributor Author

The best I can come up with is to use happens-before terminology. happens-before applies to actions not signals (messages) so mixing happens-before with the verb/noun signal is a tad confusing.

I notice that the glossary defines signal like so:

As a noun: one of the onSubscribe, onNext, onComplete, onError, request(n) or cancel methods. As a verb: calling/invoking a signal.

AFAICS the normal interpretation of a noun signal in a computer science context is as a message and we have now redefined it to be the action incurred by that message. A tad confusing but we can run with it.

With regards to:

onSubscribe, onNext, onError and onComplete signaled to a Subscriber MUST be signaled serially—and if performed by multiple threads—use external synchronization.

We don't need to add "and if performed by multiple threads ..." because it is redundant (the wording implies it is an extra criterion) but rather some clarification about the use of multiple threads is nice to have in the comment under the rule.

So I'm thinking:

onSubscribe, onNext, onError and onComplete signaled to a Subscriber MUST be signaled serially.

and a comment of:

Serially does not preclude the signalling of signals from multiple threads but it does demand that there be a happens-before relation between the signals.

@viktorklang
Copy link
Contributor

@davidmoten "signal" is conceptually messages in this model, but since synchronous Publishers and Subscribers are permitted, it has to refer to the methods (as a noun).

Serially does not preclude the signalling of signals from multiple threads but it does demand that there be a happens-before relation between the signals.

Sounds like a great explanation. I would want to avoid using "demand" in this context as to avoid confusion with the other notion of "demand" in this spec. Perhaps something like this?

Serially does not preclude the signalling of signals from multiple threads but it does require establishing a happens-before relation between each of the signals.

@davidmoten
Copy link
Contributor Author

@viktorklang sounds good. Might be able to improve on my double negative:

Serially allows the signalling of signals from multiple threads but it does require establishing a happens-before relation between each of the signals.

Could be simplified a bit more? Perhaps

Serially allows the signalling of signals from multiple threads but there must be a happens-before relation between each of the signals.

@viktorklang
Copy link
Contributor

@davidmoten Perhaps even simpler:

Serially permits the signalling of signals from multiple threads if a happens-before relation between each of the signals is established.

@davidmoten
Copy link
Contributor Author

I'm good with that. Could replace the is established with there is:

Serially permits the signalling of signals from multiple threads if there is a happens-before relation between each of the signals.

@viktorklang
Copy link
Contributor

@davidmoten I felt that wording to be a bit vague on what was required by the implementor. Is there some wording which clearly states that the implementor much provide this?

@davidmoten
Copy link
Contributor Author

I understand. If you want to emphasize that then let's leave it as you had it.

@viktorklang
Copy link
Contributor

@davidmoten Cool. Do you want to do the honors of opening a PR?

@davidmoten
Copy link
Contributor Author

Okey doke

@davidmoten
Copy link
Contributor Author

I realize there is a tad more to talk about.

We propose for 1.3:

onSubscribe, onNext, onError and onComplete signaled to a Subscriber MUST be signaled serially.

and a comment of:

Serially permits the signalling of signals from multiple threads if a happens-before relation between each of the signals is established.

However, I see there is a convention in place where every comment starts with "The intent of this rule is". If we do follow the convention then perhaps something like:

The intent of this rule is to permit the signalling of signals from multiple threads if a happens-before relation between each of the signals is established.

@viktorklang
Copy link
Contributor

@davidmoten Great catch with the Intent-section! I believe we also need to supersede the use of "External synchronization" in the spec (amend 2:7).

Come to think of it, I think we need an iff in the intent:

The intent of this rule is to permit the signalling of signals from multiple threads iff a happens-before relation between each of the signals is established.

@davidmoten
Copy link
Contributor Author

Come to think of it, I think we need an iff in the intent

Yeah I agree, you want it expanded (if and only if)?

To retire the "External synchronization" term we'll need to

  • remove External Synchronization entry from glossary
  • reword Thread-Safety in Glossary
  • reword 2.7

I'll put up some suggestions and we can bounce them around.

@viktorklang
Copy link
Contributor

@davidmoten I think we need to spell it out so people who are unfamiliar with it don't think it's a typo.

Your plan sounds good, I'm looking forward to having a look at your suggestions.

@viktorklang
Copy link
Contributor

@davidmoten What's the status here, David?

@davidmoten
Copy link
Contributor Author

@viktorklang I'll have another look this week

@davidmoten
Copy link
Contributor Author

@viktorklang
Thanks for working with me on this one. Apologies for the big delay. I'm still stretched a bit far to invest time in the retirement of the term "External Synchronization". I'd be happy to make a PR to cover the 1.3 rewording and raise an issue as a TODO on further rewording. Does that suit for the moment?

@viktorklang
Copy link
Contributor

@davidmoten No worries, I understand. As for 2.7, see the discussion here: #405 (comment)

@viktorklang
Copy link
Contributor

@davidmoten Ping.

1 similar comment
@viktorklang
Copy link
Contributor

@davidmoten Ping.

davidmoten added a commit to davidmoten/reactive-streams-jvm that referenced this issue Dec 7, 2018
viktorklang pushed a commit that referenced this issue Feb 21, 2019
* improve Publisher 1.3 #431

* add Serially glossary entry

* update README with specification wording changes

* update 2.7 intent

* update because happens-before applicable in single thread for preventing re-entrancy
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

No branches or pull requests

4 participants