finagle-clojure.futures

Functions for working with com.twitter.util.Future objects. Futures are used to represent asynchronous operations in Finagle.

More info on the use of Futures (in Scala): * https://twitter.github.io/finagle/guide/Futures.html * https://twitter.github.io/scala_school/finagle.html

await

(await f)

Block until Future f is defined and return its value. You probably don’t want to use this in production code. This should never be used in code that runs on a Finagle thread as it will block the reactor.

This should only be used to wait for an asynchronous operation in a synchronous environment.

Arguments:

  • f: a Future

Returns: The value of f if it was successful. Throws the contained Exception if f was unsuccessful.

collect

(collect future-seq)

Takes a seq of Futures, returns a Future of a seq of their values.

Arguments:

  • future-seq: a Clojure seq of Futures

Returns:

A new Future that will be defined when all Futures in future-seq have been defined. The value of that Future will be a Clojure seq of the values of the Futures in future-seq.

ensure

macro

(ensure f & body)

ensure*

(ensure* f fn0)

Apply scala.Function0 fn0 when Future f is defined whether it is successful or not. This is primarily used for side-effects, the return value of fn0 is ignored.

Arguments:

  • f: a Future
  • fn0: a scala.Function0 or Clojure fn that will execute when f is defined.

Returns:

A new Future that will be defined when f is defined and fn0 has executed.

See scala/Function0, ensure

exception

(exception t)

Returns a defined Future with a Throw value of t. This can be used to create a Future that has failed immediately.

Arguments:

  • t: an instance of Throwable that the new Future should be defined with.

Returns:

A new Future that is defined with the Throw value t.

flatmap

macro

(flatmap f arg-binding & body)

Sugar for constructing a scala.Function1 & applying flatmap* with it.

Arguments:

  • f: a Future
  • arg-binding: is a vector with 1 element, the name to bind the successful value of Future f to.
  • body: will execute when the (non-error) value of f is defined. Its result should be a Future.

Returns:

A new Future that will be defined when f is defined and the Future returned by executing body is defined. If f results in an error then body won’t run.

See flatmap* & scala/Function

flatmap*

(flatmap* f fn1)

Apply scala.Function1 fn1 with the value of Future f when f is defined with a value (not an exception). fn1 should return a Future.

flatmap* is used to represent asynchronous transformations of the successful result of a Future. E.g. calling to a RPC service with the result of a previous call. map* or map can be used to run synchronous transformations of the successful value of a Future.

Arguments:

  • f: a Future
  • fn1: a scala.Function1 or Clojure fn that will execute when the (non-error) value of f is defined. Its result should be a Future.

Returns:

A new Future that will be defined when f is defined and the Future returned by calling fn1 is defined. If f results in an error then fn1 won’t run.

See scala/Function, flatmap

for

macro

(for bindings & body)

Like a scala for comprehension with Futures. bindings are pairs of [name future]. body is executed when all Futures are ready and should return a Future. Bindings can refer to Futures defined before them (which will be realized).

handle

macro

(handle f arg-binding & body)

Sugar for constructing a scala.PartialFunction & applying handle* with it. This is like map for when a Future results in an error.

Arguments:

  • f: a Future
  • arg-binding: is a vector with 1 element, the name to bind the value of Future f.
  • body: will execute when the (error) value of f is defined.

Returns:

A new Future that will be defined when f is defined and the Future returned by calling body is defined. If f is successful then body won’t run.

See handle* & scala/Function

handle*

(handle* f pfn)

Apply scala.PartialFunction pfn with the value of Future f when f is defined with a Throw (a Throwable). This is like map* for when a Future results in an error.

handle* is used to represent synchronous transformations of the unsuccessful result of a Future. E.g. some CPU bound calculation like computing the hash of the result. No blocking operations should be run with handle*. rescue* or rescue can be used to run asynchronous transformations of the unsuccessful value of a Future.

Arguments:

  • f: a Future
  • pfn: a scala.PartialFunction or Clojure fn that will execute when the value of f is defined with an unsuccessful value.

Returns:

A new Future that will be defined when f is defined and the Future returned by calling pfn is defined. If f is successful then pfn won’t run.

See scala/Function, handle

map

macro

(map f arg-binding & body)

Sugar for constructing a scala.Function1 & applying map* with it.

Arguments:

  • f: a Future
  • arg-binding: is a vector with 1 element, the name to bind to the successful value of Future f.
  • body: will execute when the (non-error) value of f is defined.

Returns:

A new Future that will be defined when f is defined and body has been applied to its value. The value of the new Future will be the result of body if f is successful. If f results in an error then body won’t run.

See map* & scala/Function

map*

(map* f fn1)

Apply scala.Function1 fn1 with the value of Future f when f is defined with a value (not exception).

map* is used to represent synchronous transformations of the successful result of a Future. E.g. some CPU bound calculation like computing the hash of the result. No blocking operations should be run with map. flatmap* or flatmap can be used to run asynchronous transformations of the successful value of a Future.

Arguments:

  • f: a Future
  • fn1: a scala.Function1 or Clojure fn that will execute when the (non-error) value of f is defined.

Returns:

A new Future that will be defined when f is defined and fn1 has been applied to its value. The value of the new Future will be the result of fn1 if f is successful. If f results in an error then fn1 won’t run.

See scala/Function, map

match-class

macro

(match-class value & body)

Sugar for conditional execution based on the class of the first argument value. Useful for handling different types of Exceptions in error callbacks.

Arguments:

  • value: the class of this argument will be used to dispatch with body.
  • body: like the body of a cond expression: expected-class expr

e.g.

(match-class (IllegalArgumentException.)
  IllegalArgumentException (value :illegal-argument)
  Exception (value :an-error))

Returns:

The result of the expression that matches the class of value.

See handle, rescue, transform.

on-failure

macro

(on-failure f arg-binding & body)

Sugar for constructing a scala.Function1 & applying on-failure* with it.

Arguments:

  • f: a Future.
  • arg-binding: is a vector with 1 element, the name to bind the value of Future f.
  • body: will execute when the error value of f is defined. body will be transformed to automatically return a scala.Unit value for compatibility.

Returns:

A Future that will run body when it is defined with an error value.

See on-failure* & scala/Function

on-failure*

(on-failure* f fn1)

Apply scala.Function1 fn1 with the value of Future f when f is defined with an exception. The return value of fn1 is ignored. While this is used for side effects it still should not block the thread on which it runs.

Arguments:

  • f: a Future
  • fn1: a scala.Function1 or Clojure fn that will execute when the error value of f is defined. fn1 should return scala.Unit.

Returns:

A Future that will run fn1 when it is defined with an error value.

See scala/Function, scala/unit, on-failure

on-success

macro

(on-success f arg-binding & body)

Sugar for constructing a scala.Function1 & applying on-success* with it.

Arguments:

  • f: a Future.
  • arg-binding: is a vector with 1 element, the name to bind the successful value of Future f.
  • body: will execute when the (non-error) value of f is defined. body will be transformed to automatically return a scala.Unit value for compatibility.

Returns:

A Future that will run body when it is defined with a successful value.

See on-success* & scala/Function

on-success*

(on-success* f fn1)

Apply scala.Function1 fn1 with the value of Future f when f is defined with a value (not exception). The return value of fn1 is ignored. While this is used for side effects it still should not block the thread on which it runs.

Arguments:

  • f: a Future
  • fn1: a scala.Function1 or Clojure fn that will execute when the (non-error) value of f is defined. fn1 should return scala.Unit.

Returns:

A Future that will run fn1 when it is defined with a successful value.

See scala/Function, scala/unit, on-success

raise

(raise f t)

Signal to the ‘producer’ of a Future that the computation is no longer needed. This will not change the visible state of the Future (e.g. it won’t cause it to be failed) and is rather used to attempt to cancel an in-flight operation.

Arguments:

  • f: a Future
  • t: a Throwable that will be delivered to the interrupted Future.

Returns:

nil

raise-within

(raise-within f timeout-value timeout-unit)(raise-within f timeout-value timeout-unit timer)

Interrupt this Future if it doesn’t complete within timeout-duration. This is like composing raise & within together.

Arguments:

  • f: a Future
  • timeout-value
  • timeout-unit: the unit for the timeout Duration (see finagle-clojure.duration/->Duration).
  • timer (optional): a com.twitter.util.Timer that schedules the check to see if f isn’t defined after timeout-duration. When not specified a default Timer is used.

Returns:

A new Future that will be defined with a TimeoutException if it isn’t otherwise defined within timeout-duration. An attempt will also be made to interrupt the underlying operation.

See raise, within, raise-within*

raise-within*

(raise-within* f timeout-duration)(raise-within* f timeout-duration timer)

Interrupt this Future if it doesn’t complete within timeout-duration. This is like composing raise* & within* together.

Arguments:

  • f: a Future
  • timeout-duration: a com.twitter.util.Duration indicating how long to wait before erroring.
  • timer (optional): a com.twitter.util.Timer that schedules the check to see if f isn’t defined after timeout-duration. When not specified a default Timer is used.

Returns:

A new Future that will be defined with a TimeoutException if it isn’t otherwise defined within timeout-duration. An attempt will also be made to interrupt the underlying operation.

See finagle-clojure.duration/->Duration, raise, within*, raise-within

rescue

macro

(rescue f arg-binding & body)

Sugar for constructing a scala.PartialFunction & applying rescue* with it. This is like flatmap for when a Future results in an error.

Arguments:

  • f: a Future
  • arg-binding: is a vector with 1 element, the name to bind the unsuccessful value of Future f.
  • body: will execute when the (error) value of f is defined. The return value should be a Future.

Returns:

A new Future that will be defined when f is defined and the Future returned by calling body is defined. If f is successful then body won’t run.

See rescue* & scala/Function

rescue*

(rescue* f pfn)

Apply scala.PartialFunction pfn with the value of Future f when f is defined with an unsuccessful value (a Throwable). This is like flatmap* for when a Future results in an error.

rescue* is used to represent asynchronous transformations of the unsuccessful result of a Future. handle* or handle can be used to run synchronous transformations of the unsuccessful value of a Future.

Arguments:

  • f: a Future
  • pfn: a scala.PartialFunction or Clojure fn that will execute when the value of f is defined with an unsuccessful value. The return value should be a Future.

Returns:

A new Future that will be defined when f is defined and the Future returned by calling pfn is defined. If f is successful then pfn won’t run.

See scala/Function, rescue

select

(select f1 f2)

Arguments:

  • f1: a Future
  • f2: a Future

Returns:

A new Future that will be defined with the value of the Future that returns first (between f1 & f2).

transform

(transform f success-fn)(transform f success-fn failure-fn)

Returns a new Future that will transform its value when defined using the supplied fns. This is sugar around chaining flatmap & rescue, so the supplied functions should return a Future.

Arguments:

  • f: a Future
  • success-fn: a Clojure IFn that will be called with the successful value of f when it’s defined. success-fn should return a Future.
  • failure-fn: a Clojure IFn that will be called with the exception that defines f. failure-fn should return a Future. Exceptions will not be rescue if this isn’t passed.

Returns:

A new Future that will be defined once f has been defined and the Future returned by the transformation fns has been defined.

See flatmap & rescue.

value

(value v)

Returns a defined Future with the constant Return value v.

Arguments:

  • v: the value that the new Future should be defined with.

Returns:

A new Future that is defined with the value v.

within

(within f timeout-value timeout-unit)(within f timeout-value timeout-unit timer)

Returns a new Future that will error if not complete within timeout-value timeout-unit.

Arguments:

  • f: a Future
  • timeout-value
  • timeout-unit: the unit for the timeout Duration (see finagle-clojure.duration/->Duration).
  • timer (optional): a com.twitter.util.Timer that schedules the check to see if f isn’t defined after timeout-value. When not specified a default Timer is used.

Returns:

A new Future that will be defined with a TimeoutException if it isn’t otherwise defined within timeout-value timeout-units.

See within* & finagle-clojure.duration/->Duration

within*

(within* f timeout-duration)(within* f timeout-duration timer)

Returns a new Future that will error if not complete within timeout-duration.

Arguments:

  • f: a Future
  • timeout-duration: a com.twitter.util.Duration indicating how long to wait before erroring.
  • timer (optional): a com.twitter.util.Timer that schedules the check to see if f isn’t defined after timeout-duration. When not specified a default Timer is used.

Returns:

A new Future that will be defined with a TimeoutException if it isn’t otherwise defined within timeout-duration.

See finagle-clojure.duration/->Duration, within