Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Fix Promise#filter #302

Merged
merged 1 commit into from

3 participants

@julienrf
Collaborator

#459

  • Fix Promise#filter so it never leads to an unredeemable promise ;
  • Follow the Scala standard Future#filter behavior when the predicate fails: throw a NoSuchElementException ;
  • Remove STMPromise#collect which was wrong and anyway not expose at the Promise interface level.
@sadache sadache was assigned
@pk11
Collaborator

Hi @sadache, it looks OK to me but could you please check this?

@sadache
Collaborator

Yes, Ok for me too. But the pull request needs to be cleaned from the two other unrelated commits. This means we integrate only 9d69b11.
Thanks Julien for this fix.

@sadache
Collaborator

Actually not so sure any more.
Maybe leaving filter as is and making collect public is better.
The idea is that you can combine two or more filtered promises using "or".

@julienrf
Collaborator
@sadache
Collaborator

Nothing is blocking, but it never redeems.
I want to find a way to keep the very interesting and practical functionality to "or" different potentially redeeming promises.

@sadache
Collaborator

clean the pull request so that I can pull it before I change my mind

@julienrf
Collaborator

Ok, I understand your points. There is a Future#either which seems to perform the Promise#or of Play, unless I’m wrong?

@sadache
Collaborator

The Future#either would return NoSuchElement if the first redeemed future is out of the filter (whereas the second could be satisfactory)

@sadache sadache merged commit c45771d into playframework:master
@julienrf
Collaborator

Oh yes, you’re right… We could write a orSuccess which would perform what you said?

@sadache
Collaborator

Won't work, I want to use error in worst case scenario (both promises return an error), ignoring NoSuchElement is wrong because it could happen from something else.

@julienrf julienrf deleted the julienrf:fix/459 branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on May 21, 2012
  1. @julienrf

    Fix Promise#filter

    julienrf authored
This page is out of date. Refresh to see the latest.
View
11 framework/src/play/src/main/scala/play/api/libs/concurrent/Promise.scala
@@ -125,13 +125,10 @@ class STMPromise[A] extends Promise[A] with Redeemable[A] {
def filter(p: A => Boolean): Promise[A] = {
val result = new STMPromise[A]()
- onRedeem(a => if (p(a)) result.redeem(a))
- result
- }
-
- def collect[B](p: PartialFunction[A, B]) = {
- val result = new STMPromise[B]()
- onRedeem(a => p.lift(a).foreach(result.redeem(_)))
+ this.addAction(_.value match {
+ case Redeemed(a) => if (p(a)) result.redeem(a) else result.redeem(throw new NoSuchElementException)
+ case Thrown(t) => result.redeem(throw t)
+ })
result
}
View
32 framework/src/play/src/test/scala/play/concurrent/PromiseSpec.scala
@@ -0,0 +1,32 @@
+package play.concurrent
+
+import org.specs2.mutable.Specification
+import play.api.libs.concurrent._
+import org.specs2.execute.Result
+
+class PromiseSpec extends Specification {
+
+ "Promise" can {
+
+ "filter" in {
+
+ "Redeemed values" << {
+ val p = Promise.timeout(42, 100)
+ p.filter(_ == 42).value.get must equalTo (42)
+ }
+
+ "Redeemed values not matching the predicate" << {
+ val p = Promise.timeout(42, 100)
+ p.filter(_ != 42).value.get must throwA [NoSuchElementException]
+ }
+
+ "Thrown values" << {
+ val p = Promise.timeout(42, 100).map[Int]{ _ => throw new Exception("foo") }
+ p.filter(_ => true).value.get must throwAn [Exception](message = "foo")
+ }
+
+ }
+
+ }
+
+}
Something went wrong with that request. Please try again.