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

Clarify intent of rule 1.9 #488

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Commits on May 7, 2020

  1. Clarify intent of rule 1.9

    Rule 1.9 defines that `onSubscribe()` on a `Subscriber` should be called before calling any other method on that `Subscriber`. However, this does not clarify that if `onSubscribe()` is signalled asynchronously then there should be a happens-before relationship between `subscribe()` and signalling of `onSubscribe()`.
    In absence of such a guarantee, non-final fields initialized in a constructor have no guarantee to be visible inside `onSubscribe()`.
    
    Considering a simple example:
    
    public class UnsafeSubscriber implements Subscriber<String> {
        private boolean duplicateOnSubscribe = false;
    
        @OverRide
        public void onSubscribe(final Subscription s) {
            if (duplicateOnSubscribe) {
                throw new IllegalStateException("Duplicate onSubscribe() calls.");
            }
            duplicateOnSubscribe = true;
        }
    
        @OverRide
        public void onNext(final String s) {
    
        }
    
        @OverRide
        public void onError(final Throwable t) {
    
        }
    
        @OverRide
        public void onComplete() {
    
        }
    }
    If an UnsafeSubscriber instance is created in a different thread than the one that invokes onSubscribe() (true for an asynchronous Publisher), according to the java memory model, this statement inside onSubscribe():
    
    if (duplicateOnSubscribe) {
    
    is guaranteed to compute to false if and only if the instance is published safely between these threads. None of the rules in the specifications establish a happens-before relationship between Publisher#subscribe() and Subscriber#onSubscribe(). So, the usage above can be categorized as unsafe. In a more convoluted form, the assignment:
    
    private boolean duplicateOnSubscribe = false;
    
    can be interleaved with
    
    duplicateOnSubscribe = true; such that duplicateOnSubscribe is set to false later.
    
    Has this been considered before or am I missing something?
    
    Fixes reactive-streams#486
    Nitesh Kant committed May 7, 2020
    Configuration menu
    Copy the full SHA
    24f35af View commit details
    Browse the repository at this point in the history