-
Notifications
You must be signed in to change notification settings - Fork 7.6k
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
Possible race condition in Subscription.scala #554
Comments
A question: can |
It doesn't need a lock, it just needs to use For example:
I'm somewhat curious as to why Scala adapters are reimplementing this logic rather than leveraging the Java core implementations. |
in this implementation, The following implementation can guarantee def apply(u: => Unit): Subscription = {
new Subscription() {
private val lock = new ReentrantLock()
private val unsubscribed = new AtomicBoolean(false)
def isUnsubscribed = unsubscribed.get()
val asJavaSubscription = new rx.Subscription {
def unsubscribe() {
lock.lock
try {
if (!unsubscribed.get()) {
u;
unsubscribed.set(true)
}
} finally {
lock.unlock
}
}
}
}
} |
We need a lock because we need to guarantee the codes of the three operators |
@samuelgruetter can you help me confirm if the following conventions are right:
|
Why are these not just wrapping Java implementations? |
|
So the upshot is. The implementation is wrong, but it is a temporary hack (probably) and the scala classes should really be wrappers so semantics reside in the java implementation with delegation from scala classes. Wrt to semantics, and question from zsxwing, the call to unsubscribe can return before u completes, which seems reasonable and seems to be the behaviour in the java classes. |
@benjchristensen Could you help clarify the semantics of |
I discussed this with @headinthebox last week and there isn't a very strong argument for making the major breaking change of adding Changing the If the
Considering all of this, what is trying to be achieved by adding this method to the |
@zsxwing null => not subscribed to yet This is so that a race-condition for using This is important so the unsubscribe action is propagated to the actual subscription either when |
@benjchristensen that makes sense, so I'll remove isUnsubscribed from Scala Subscription and hope everyone is happy with it? |
Yes, I think it makes sense for |
@benjchristensen So if |
In practice yes. It is answering whether the outer |
For Scala it is OK to have isUnsubscribed since you just call Subscription{ block } making it as convenient as a functional interface. |
Well @headinthebox if you really want isUnsubscribed in Scala Subscription, you can have it ;-) But then Scala subscription should wrap a Java BooleanSubscription instead of implementing itself the "logic" of remembering if already unsubscribed. |
|
Fixed in #598 |
Hi,
I'm looking at Subscription.scala because I'm doing the Coursera Reactive course.
The code below from Subscription.scala looks a bit suspect. I think there's a race condition that will happen especially if u takes a long time that could lead to multiple calls to u. I'm not sure if you consider this an issue as I am not sure if Subscriptions are shared across threads, but the use of the AtomicBoolean seems to imply this.
Would something like:
be better - also looks like subclasses eg. BooleanSubscription may have this problem.
If you think this is an issue I can look to fix.
Regards
Mick
The text was updated successfully, but these errors were encountered: