Skip to content
Browse files

Added FutureSend#when_failed:

  • Loading branch information...
1 parent 9ad9964 commit 3cf4c7049892f1ad608b516526e95d87baccf1cf @bakkdoor committed Feb 7, 2012
Showing with 71 additions and 2 deletions.
  1. +31 −2 lib/future.fy
  2. +40 −0 tests/future.fy
View
33 lib/future.fy
@@ -16,6 +16,7 @@ class FutureSend {
@completed = false
@failed = false
@continuations = []
+ @fail_continuations = []
@actor ! ('future, (@message, @params), self)
}
@@ -37,9 +38,20 @@ class FutureSend {
def completed! {
@condvar broadcast
- unless: @failed do: {
- @continuations each: @{ call: [@value] }
+ if: @failed then: {
+ try {
+ @fail_continuations each: @{ call: [@fail_reason] }
+ } catch Exception => ex {
+ *stderr* println: "Error in FutureSend#completed! while calling fail continuations: #{ex}"
+ }
+ } else: {
+ try {
+ @continuations each: @{ call: [@value] }
+ } catch Exception => ex {
+ *stderr* println: "Error in FutureSend#completed! while calling success continuations: #{ex}"
+ }
}
+ @fail_continuations = []
@continuations = []
}
@@ -123,6 +135,23 @@ class FutureSend {
value send_future: message with_params: params
}
+ def when_failed: block {
+ """
+ @block @Block@ to be registered as a continuation when @self fails.
+
+ Registers @block as a continuation to be called with @self's fail reason in case of failure.
+ """
+
+ { return nil } if: succeeded?
+ @completed_mutex synchronize: {
+ if: @failed then: {
+ block call: [@fail_reason]
+ } else: {
+ @fail_continuations << block
+ }
+ }
+ }
+
def when_done: block {
"""
@block @Block@ to be registered as a continuation when @self succeeds.
View
40 tests/future.fy
@@ -53,4 +53,44 @@ FancySpec describe: FutureSend with: {
f failure message is: "error!"
f failed? is: true
}
+
+ it: "calls a block when done" with: 'when_done: when: {
+ called? = false
+ failed? = false
+ val = 0
+ f = { Thread sleep: 0.01; 2 } @ call
+ f when_done: |v| {
+ val = v
+ called? = true
+ }
+ f when_failed: |err| {
+ val = err
+ failed? = true
+ }
+
+ f value
+ called? is: true
+ val is: 2
+ }
+
+ it: "calls a block when failed" with: 'when_failed: when: {
+ called? = false
+ failed? = false
+ val = 0
+ f = { Thread sleep: 0.01; "Fail!" raise! } @ call
+ f when_done: |v| {
+ val = v
+ called? = true
+ }
+ f when_failed: |err| {
+ val = err
+ failed? = true
+ }
+
+ f value
+ called? is: false
+ failed? is: true
+ val message is: "Fail!"
+ val is_a?: Exception
+ }
}

0 comments on commit 3cf4c70

Please sign in to comment.
Something went wrong with that request. Please try again.