sealed
trait
Callback[+O] extends AnyRef
Abstract Value Members
-
abstract
def
execute(onComplete: (Try[O]) ⇒ Unit = _ => ()): Unit
-
abstract
def
flatMap[U](f: (O) ⇒ Callback[U]): Callback[U]
-
abstract
def
map[U](f: (O) ⇒ U): Callback[U]
-
abstract
def
mapTry[U](f: (Try[O]) ⇒ Try[U]): Callback[U]
-
abstract
def
recover[U >: O](p: PartialFunction[Throwable, U]): Callback[U]
-
abstract
def
recoverWith[U >: O](p: PartialFunction[Throwable, Callback[U]]): Callback[U]
Concrete Value Members
-
final
def
!=(arg0: AnyRef): Boolean
-
final
def
!=(arg0: Any): Boolean
-
final
def
##(): Int
-
final
def
==(arg0: AnyRef): Boolean
-
final
def
==(arg0: Any): Boolean
-
final
def
asInstanceOf[T0]: T0
-
def
clone(): AnyRef
-
final
def
eq(arg0: AnyRef): Boolean
-
def
equals(arg0: Any): Boolean
-
def
finalize(): Unit
-
final
def
getClass(): Class[_]
-
def
hashCode(): Int
-
final
def
isInstanceOf[T0]: Boolean
-
final
def
ne(arg0: AnyRef): Boolean
-
final
def
notify(): Unit
-
final
def
notifyAll(): Unit
-
final
def
synchronized[T0](arg0: ⇒ T0): T0
-
def
toFuture(implicit ex: ExecutionContext): Future[O]
-
def
toString(): String
-
final
def
wait(): Unit
-
final
def
wait(arg0: Long, arg1: Int): Unit
-
final
def
wait(arg0: Long): Unit
-
final
def
withFilter(f: (O) ⇒ Boolean): Callback[O]
-
-
Inherited from AnyRef
Inherited from Any
A Callback is a Monad for doing in-thread non-blocking operations. It is essentially a "function builder" that uses function composition to chain together a callback function that is eventually passed to another function.
Normally if you have a function that requires a callback, the function looks something like:
and then you'd call it like
This is the well-known continuation pattern, and it something we'd like to avoid due to the common occurrance of deeply nested "callback hell". Instead, the
Callback
allows us to define out function asdef doSomething(param1, param2): Callback[Result]
and call it like
Thus, in practice working with Callbacks is very similar to working with Futures. The big differences from a future are:
1. Callbacks are not thread safe at all. They are entirely intended to stay inside a single worker. Otherwise just use Futures.
2. The execute() method needs to be called once the callback has been fully built, which unlike futures requires some part of the code to know when a callback is ready to be invoked
Using Callbacks in Services
When building services, particularly when working with service clients, you will usually be getting Callbacks back from clients when requests are sent. *Do not call
execute
yourself!* on these Callbacks. They must be returned as part of request processing, and Colossus will invoke the callback itself.Using Callbacks elsewhere
If you are using Callbacks in some custom situation outside of services, be aware that exceptions thrown inside a
map
orflatMap
are properly caught and can be recovered usingrecover
andrecoverWith
, however exceptions thrown in the "final" handler passed toexecute
are not caught. This is because the final block cannot be mapped on (since it is only passed when the callback is executed) and throwing the exception is preferrable to suppressing it.Any exception that is thrown in this block is however rethrown as a
CallbackExecutionException
. Therefore, any "trigger" function you wrap inside a callback should properly catch this exception.