Skip to content

Remove Consumer/Processor/Producer #25

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
wants to merge 2 commits into from

Conversation

benjchristensen
Copy link
Contributor

As per discussions in #24, #23, and #22 I recommend eliminating the Consumer, Processor and Producer types and focusing purely on the interop types.

I spoke with @viktorklang on Skype about this topic and with him decided to submit a pull request to push the conversation forward.

NOTE: This does NOT fix the TCK which will not compile with this change. I want to determine if there is agreement before exerting that effort.

Why?

1) Simplicity

We should strive for as few types as possible to accomplish the stated goal of library interop. The Publisher, Subscriber and Subscription types achieve this without need for the other 3.

Publisher, Subscriber and Subscription clearly communicate their behavior and relationships via their signatures whereas Consumer and Producer do not.

2) Not succeeding in hiding SPI

The Producer and Consumer types are empty synonyms to Publisher and Subscriber and do not succeed in their effort to "hide" Publisher and Subscriber from users since Java does not support "friend" style modularity. The types are public and thus accessible. In fact, the Consumer and Producer types immediately expose the Publisher and Subscriber types anyways.

3) Focus

This spec should not get involved in how processing pipelines will be established and thus should not have the Processor type.

Interop will always occur at explicit boundaries where a library exposes either a Publisher or a Subscriber. These clearly communicate intent, lifecycle and capability. We do not need further abstraction, indirection, or factory behavior.

4) Safety

The goal of the spec should be to clearly communicate via the types how data flows, not try and prevent users from doing "bad things" through hiding the types. Safety in this case can not be prevented through obfuscation because that just impedes comprehension which in turn is more likely to cause misuse.

Clear, easy to use types are the best strategy for communicating the right mental model which in turn will result in correct usage.

Simplify to the the minimum viable types to allow interop without conflating concerns.
@smaldini
Copy link
Contributor

Agree on producer/consumer but actually processor can be justified at least I don't see an issue with it implementing publisher/subscriber which the tck already states in fact.

Sent from my iPhone

On 15 Apr 2014, at 21:04, Ben Christensen [email protected] wrote:

As per discussions in #24, #23, and #22 I recommend eliminating the Consumer, Processor and Producer types and focusing purely on the interop types.

I spoke with @viktorklang on Skype about this topic and with him decided to submit a pull request to push the conversation forward.

NOTE: This does NOT fix the TCK which will not compile with this change. I want to determine if there is agreement before exerting that effort.

Why?

  1. Simplicity

We should strive for as few types as possible to accomplish the stated goal of library interop. The Publisher, Subscriber and Subscription types achieve this without need for the other 3.

Publisher, Subscriber and Subscription clearly communicate their behavior and relationships via their signatures whereas Consumer and Producer do not.

  1. Not succeeding in hiding SPI

The Producer and Consumer types are empty synonyms to Publisher and Subscriber and do not succeed in their effort to "hide" Publisher and Subscriber from users since Java does not support "friend" style modularity. The types are public and thus accessible. In fact, the Consumer and Producer types immediately expose the Publisher and Subscriber types anyways.

  1. Focus

This spec should not get involved in how processing pipelines will be established and thus should not have the Processor type.

Interop will always occur at explicit boundaries where a library exposes either a Publisher or a Subscriber. These clearly communicate intent, lifecycle and capability. We do not need further abstraction, indirection, or factory behavior.

  1. Safety

The goal of the spec should be to clearly communicate via the types how data flows, not try and prevent users from doing "bad things" through hiding the types. Safety in this case can not be prevented through obfuscation because that just impedes comprehension which in turn is more likely to cause misuse.

Clear, easy to use types are the best strategy for communicating the right mental model which in turn will result in correct usage.

You can merge this Pull Request by running

git pull https://github.com/reactive-streams/reactive-streams simplest-viable-types
Or view, comment on, or merge it at:

#25

Commit Summary

Remove Consumer/Processor/Producer
File Changes

D spi/src/main/java/org/reactivestreams/api/Consumer.java (21)
D spi/src/main/java/org/reactivestreams/api/Processor.java (10)
D spi/src/main/java/org/reactivestreams/api/Producer.java (38)
Patch Links:

https://github.com/reactive-streams/reactive-streams/pull/25.patch
https://github.com/reactive-streams/reactive-streams/pull/25.diff

Reply to this email directly or view it on GitHub.

@benjchristensen
Copy link
Contributor Author

What is the use case for Processor in achieving library interop?

@viktorklang
Copy link
Contributor

I'll have to sleep on this one.

An addition to your 4th point: We'll have to be very clear about User's use of any Subscriber methods. (i.e. they are only ever intended for the active publisher to use).

As for Processor I think the risk is that every library will have to create its own implementation of this, and they will all be incompatible (binary) and IIRC only Scala's type system is "sophisticated" enough to be able to represent Subscriber[T] with Publisher[T]. On the other hand, it can always be represented as a Subscriber-Publisher pair, so... well... sleep on it it is!

@benjchristensen
Copy link
Contributor Author

We'll have to be very clear about User's use of any Subscriber methods. (i.e. they are only ever intended for the active publisher to use).

Sure, but I don't see how this isn't obvious. People know how to use listeners/observers/callbacks, this isn't a foreign concept we're thrusting on people.

If people are going to invoke the on* methods themselves they get what they deserve! There is nothing about the Subscriber type that suggests they should ever do that, especially since the methods are named as "handlers" with the "on" prefix.

More importantly though, hiding the Subscriber inside the Producer/Consumer does not prevent anyone from seeing it or doing bad things if they really want to.

@alexandru
Copy link

Subscriber will definitely be used by users, there's no point in denying them that - what needs to be very, very clear is the contract of a well behaved Subscriber and I think the spec could be more clear in that regard.

@viktorklang
Copy link
Contributor

@alexandru "and I think the spec could be more clear in that regard." What is unclear?

@rkuhn
Copy link
Member

rkuhn commented Apr 17, 2014

@benjchristensen There is one thing you will notice while fixing the TCK: IdentityProcessorVerification (which contains several useful rules of how various signals propagate in a processing network) requires you to create a type which implements both Subscriber and Publisher. This alone is probably enough reason to keep this type available for all implementations to use.

@benjchristensen
Copy link
Contributor Author

Closing and will re-create once decisions are made in #19 (comment)

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 this pull request may close these issues.

5 participants