2018-10-29 17:19:37 +08:00
|
|
|
|
/*
|
2019-01-02 18:55:26 +08:00
|
|
|
|
* Copyright (C) 2009-2019 Lightbend Inc. <https://www.lightbend.com>
|
2009-05-25 14:48:43 +02:00
|
|
|
|
*/
|
|
|
|
|
|
|
2010-10-26 12:49:25 +02:00
|
|
|
|
package akka.dispatch
|
2009-05-25 14:48:43 +02:00
|
|
|
|
|
2018-12-14 17:48:08 -05:00
|
|
|
|
import scala.runtime.{ AbstractPartialFunction, BoxedUnit }
|
2019-02-09 15:25:39 +01:00
|
|
|
|
import akka.japi.{ Procedure, Function => JFunc, Option => JOption }
|
2018-12-14 17:48:08 -05:00
|
|
|
|
|
|
|
|
|
|
import scala.concurrent.{ ExecutionContext, ExecutionContextExecutor, ExecutionContextExecutorService, Future, Promise }
|
2019-02-09 15:25:39 +01:00
|
|
|
|
import java.lang.{ Iterable => JIterable }
|
|
|
|
|
|
import java.util.{ LinkedList => JLinkedList }
|
2018-12-14 17:48:08 -05:00
|
|
|
|
import java.util.concurrent.{ Callable, Executor, ExecutorService }
|
|
|
|
|
|
|
|
|
|
|
|
import scala.util.{ Failure, Success, Try }
|
2016-01-21 16:37:26 +01:00
|
|
|
|
import java.util.concurrent.CompletionStage
|
|
|
|
|
|
import java.util.concurrent.CompletableFuture
|
2018-12-14 17:48:08 -05:00
|
|
|
|
|
2017-03-27 18:05:54 +02:00
|
|
|
|
import akka.compat
|
2018-12-14 17:48:08 -05:00
|
|
|
|
import akka.util.unused
|
2019-04-03 13:13:44 +02:00
|
|
|
|
import com.github.ghik.silencer.silent
|
2012-07-22 21:40:09 +02:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* ExecutionContexts is the Java API for ExecutionContexts
|
|
|
|
|
|
*/
|
|
|
|
|
|
object ExecutionContexts {
|
2019-03-11 10:38:24 +01:00
|
|
|
|
|
2012-07-22 21:40:09 +02:00
|
|
|
|
/**
|
|
|
|
|
|
* Returns a new ExecutionContextExecutor which will delegate execution to the underlying Executor,
|
|
|
|
|
|
* and which will use the default error reporter.
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param executor the Executor which will be used for the ExecutionContext
|
|
|
|
|
|
* @return a new ExecutionContext
|
|
|
|
|
|
*/
|
|
|
|
|
|
def fromExecutor(executor: Executor): ExecutionContextExecutor =
|
|
|
|
|
|
ExecutionContext.fromExecutor(executor)
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Returns a new ExecutionContextExecutor which will delegate execution to the underlying Executor,
|
|
|
|
|
|
* and which will use the provided error reporter.
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param executor the Executor which will be used for the ExecutionContext
|
|
|
|
|
|
* @param errorReporter a Procedure that will log any exceptions passed to it
|
|
|
|
|
|
* @return a new ExecutionContext
|
|
|
|
|
|
*/
|
|
|
|
|
|
def fromExecutor(executor: Executor, errorReporter: Procedure[Throwable]): ExecutionContextExecutor =
|
|
|
|
|
|
ExecutionContext.fromExecutor(executor, errorReporter.apply)
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Returns a new ExecutionContextExecutorService which will delegate execution to the underlying ExecutorService,
|
|
|
|
|
|
* and which will use the default error reporter.
|
|
|
|
|
|
*
|
2015-05-15 16:53:24 +02:00
|
|
|
|
* @param executorService the ExecutorService which will be used for the ExecutionContext
|
2012-07-22 21:40:09 +02:00
|
|
|
|
* @return a new ExecutionContext
|
|
|
|
|
|
*/
|
|
|
|
|
|
def fromExecutorService(executorService: ExecutorService): ExecutionContextExecutorService =
|
|
|
|
|
|
ExecutionContext.fromExecutorService(executorService)
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Returns a new ExecutionContextExecutorService which will delegate execution to the underlying ExecutorService,
|
|
|
|
|
|
* and which will use the provided error reporter.
|
|
|
|
|
|
*
|
2015-05-15 16:53:24 +02:00
|
|
|
|
* @param executorService the ExecutorService which will be used for the ExecutionContext
|
2012-07-22 21:40:09 +02:00
|
|
|
|
* @param errorReporter a Procedure that will log any exceptions passed to it
|
|
|
|
|
|
* @return a new ExecutionContext
|
|
|
|
|
|
*/
|
2019-03-13 10:56:20 +01:00
|
|
|
|
def fromExecutorService(
|
|
|
|
|
|
executorService: ExecutorService,
|
|
|
|
|
|
errorReporter: Procedure[Throwable]): ExecutionContextExecutorService =
|
2012-07-22 21:40:09 +02:00
|
|
|
|
ExecutionContext.fromExecutorService(executorService, errorReporter.apply)
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @return a reference to the global ExecutionContext
|
|
|
|
|
|
*/
|
2014-01-13 09:31:36 +01:00
|
|
|
|
def global(): ExecutionContextExecutor = ExecutionContext.global
|
2013-01-22 22:50:09 +01:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* WARNING: Not A General Purpose ExecutionContext!
|
|
|
|
|
|
*
|
|
|
|
|
|
* This is an execution context which runs everything on the calling thread.
|
|
|
|
|
|
* It is very useful for actions which are known to be non-blocking and
|
|
|
|
|
|
* non-throwing in order to save a round-trip to the thread pool.
|
|
|
|
|
|
*/
|
2013-01-31 18:59:48 +01:00
|
|
|
|
private[akka] object sameThreadExecutionContext extends ExecutionContext with BatchingExecutor {
|
|
|
|
|
|
override protected def unbatchedExecute(runnable: Runnable): Unit = runnable.run()
|
2014-01-27 16:08:49 +01:00
|
|
|
|
override protected def resubmitOnBlock: Boolean = false // No point since we execute on same thread
|
2013-01-22 22:50:09 +01:00
|
|
|
|
override def reportFailure(t: Throwable): Unit =
|
|
|
|
|
|
throw new IllegalStateException("exception in sameThreadExecutionContext", t)
|
|
|
|
|
|
}
|
2012-07-22 21:40:09 +02:00
|
|
|
|
}
|
2011-12-11 00:40:52 +01:00
|
|
|
|
|
2011-12-15 16:56:53 +01:00
|
|
|
|
/**
|
|
|
|
|
|
* Futures is the Java API for Futures and Promises
|
|
|
|
|
|
*/
|
2011-12-12 14:39:10 +01:00
|
|
|
|
object Futures {
|
2012-10-23 12:07:38 +02:00
|
|
|
|
import scala.collection.JavaConverters.iterableAsScalaIterableConverter
|
2019-03-11 10:38:24 +01:00
|
|
|
|
|
2010-11-12 14:04:06 +01:00
|
|
|
|
/**
|
2013-03-07 09:05:55 +01:00
|
|
|
|
* Starts an asynchronous computation and returns a `Future` object with the result of that computation.
|
|
|
|
|
|
*
|
|
|
|
|
|
* The result becomes available once the asynchronous computation is completed.
|
|
|
|
|
|
*
|
2015-06-02 21:01:00 -07:00
|
|
|
|
* @param body the asynchronous computation
|
2013-03-07 09:05:55 +01:00
|
|
|
|
* @param executor the execution context on which the future is run
|
|
|
|
|
|
* @return the `Future` holding the result of the computation
|
2010-11-12 14:04:06 +01:00
|
|
|
|
*/
|
2012-07-22 13:38:12 +02:00
|
|
|
|
def future[T](body: Callable[T], executor: ExecutionContext): Future[T] = Future(body.call)(executor)
|
2011-06-18 23:23:47 -06:00
|
|
|
|
|
2010-10-26 16:40:09 +02:00
|
|
|
|
/**
|
2013-03-07 09:05:55 +01:00
|
|
|
|
* Creates a promise object which can be completed with a value.
|
|
|
|
|
|
*
|
|
|
|
|
|
* @return the newly created `Promise` object
|
2010-10-26 16:40:09 +02:00
|
|
|
|
*/
|
2012-07-22 13:38:12 +02:00
|
|
|
|
def promise[T](): Promise[T] = Promise[T]()
|
2010-11-12 12:54:48 +01:00
|
|
|
|
|
2011-12-15 16:56:53 +01:00
|
|
|
|
/**
|
2013-03-07 09:05:55 +01:00
|
|
|
|
* creates an already completed Promise with the specified exception
|
2011-12-15 16:56:53 +01:00
|
|
|
|
*/
|
2012-07-22 13:38:12 +02:00
|
|
|
|
def failed[T](exception: Throwable): Future[T] = Future.failed(exception)
|
2011-12-15 16:56:53 +01:00
|
|
|
|
|
|
|
|
|
|
/**
|
2013-03-07 09:05:55 +01:00
|
|
|
|
* Creates an already completed Promise with the specified result
|
2011-12-15 16:56:53 +01:00
|
|
|
|
*/
|
2012-07-22 13:38:12 +02:00
|
|
|
|
def successful[T](result: T): Future[T] = Future.successful(result)
|
2011-12-15 16:56:53 +01:00
|
|
|
|
|
2016-01-21 16:37:26 +01:00
|
|
|
|
/**
|
|
|
|
|
|
* Creates an already completed CompletionStage with the specified exception
|
|
|
|
|
|
*/
|
|
|
|
|
|
def failedCompletionStage[T](ex: Throwable): CompletionStage[T] = {
|
|
|
|
|
|
val f = CompletableFuture.completedFuture[T](null.asInstanceOf[T])
|
|
|
|
|
|
f.obtrudeException(ex)
|
|
|
|
|
|
f
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2011-08-26 17:25:18 +02:00
|
|
|
|
/**
|
|
|
|
|
|
* Returns a Future that will hold the optional result of the first Future with a result that matches the predicate
|
|
|
|
|
|
*/
|
2019-03-13 10:56:20 +01:00
|
|
|
|
def find[T <: AnyRef](
|
|
|
|
|
|
futures: JIterable[Future[T]],
|
|
|
|
|
|
predicate: JFunc[T, java.lang.Boolean],
|
|
|
|
|
|
executor: ExecutionContext): Future[JOption[T]] = {
|
2012-07-17 17:21:08 +02:00
|
|
|
|
implicit val ec = executor
|
2019-03-11 10:38:24 +01:00
|
|
|
|
compat.Future.find[T](futures.asScala)(predicate.apply(_))(executor).map(JOption.fromScalaOption)
|
2011-08-26 17:25:18 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2011-03-22 22:12:16 +01:00
|
|
|
|
/**
|
|
|
|
|
|
* Returns a Future to the result of the first future in the list that is completed
|
|
|
|
|
|
*/
|
2011-12-30 13:48:31 +01:00
|
|
|
|
def firstCompletedOf[T <: AnyRef](futures: JIterable[Future[T]], executor: ExecutionContext): Future[T] =
|
2012-10-23 12:07:38 +02:00
|
|
|
|
Future.firstCompletedOf(futures.asScala)(executor)
|
2011-10-06 21:19:46 +02:00
|
|
|
|
|
2011-03-22 22:12:16 +01:00
|
|
|
|
/**
|
2011-12-27 12:02:55 +01:00
|
|
|
|
* A non-blocking fold over the specified futures, with the start value of the given zero.
|
2011-03-22 22:12:16 +01:00
|
|
|
|
* The fold is performed on the thread where the last future is completed,
|
|
|
|
|
|
* the result will be the first failure of any of the futures, or any failure in the actual fold,
|
|
|
|
|
|
* or the result of the fold.
|
|
|
|
|
|
*/
|
2019-03-13 10:56:20 +01:00
|
|
|
|
def fold[T <: AnyRef, R <: AnyRef](
|
|
|
|
|
|
zero: R,
|
|
|
|
|
|
futures: JIterable[Future[T]],
|
|
|
|
|
|
fun: akka.japi.Function2[R, T, R],
|
|
|
|
|
|
executor: ExecutionContext): Future[R] =
|
2017-03-27 18:05:54 +02:00
|
|
|
|
compat.Future.fold(futures.asScala)(zero)(fun.apply)(executor)
|
2011-06-18 23:23:47 -06:00
|
|
|
|
|
2011-03-22 22:12:16 +01:00
|
|
|
|
/**
|
2012-07-13 12:21:55 +02:00
|
|
|
|
* Reduces the results of the supplied futures and binary function.
|
2011-03-22 22:12:16 +01:00
|
|
|
|
*/
|
2019-03-13 10:56:20 +01:00
|
|
|
|
def reduce[T <: AnyRef, R >: T](
|
|
|
|
|
|
futures: JIterable[Future[T]],
|
|
|
|
|
|
fun: akka.japi.Function2[R, T, R],
|
|
|
|
|
|
executor: ExecutionContext): Future[R] =
|
2017-03-27 18:05:54 +02:00
|
|
|
|
compat.Future.reduce[T, R](futures.asScala)(fun.apply)(executor)
|
2011-10-06 21:19:46 +02:00
|
|
|
|
|
2011-04-15 13:09:53 -06:00
|
|
|
|
/**
|
2013-03-07 09:05:55 +01:00
|
|
|
|
* Simple version of [[#traverse]]. Transforms a JIterable[Future[A]] into a Future[JIterable[A]].
|
2011-04-15 13:09:53 -06:00
|
|
|
|
* Useful for reducing many Futures into a single Future.
|
|
|
|
|
|
*/
|
2011-12-30 13:48:31 +01:00
|
|
|
|
def sequence[A](in: JIterable[Future[A]], executor: ExecutionContext): Future[JIterable[A]] = {
|
|
|
|
|
|
implicit val d = executor
|
2019-03-11 10:38:24 +01:00
|
|
|
|
in.asScala.foldLeft(Future(new JLinkedList[A]())) { (fr, fa) =>
|
|
|
|
|
|
for (r <- fr; a <- fa) yield { r.add(a); r }
|
|
|
|
|
|
}
|
2011-10-06 21:19:46 +02:00
|
|
|
|
}
|
2011-01-24 16:37:08 +01:00
|
|
|
|
|
2011-03-30 21:19:26 +02:00
|
|
|
|
/**
|
2019-02-09 15:25:39 +01:00
|
|
|
|
* Transforms a JIterable[A] into a Future[JIterable[B]] using the provided Function A => Future[B].
|
2011-04-03 10:40:06 -06:00
|
|
|
|
* This is useful for performing a parallel map. For example, to apply a function to all items of a list
|
2011-04-15 13:09:53 -06:00
|
|
|
|
* in parallel.
|
2011-03-30 21:19:26 +02:00
|
|
|
|
*/
|
2011-12-30 13:48:31 +01:00
|
|
|
|
def traverse[A, B](in: JIterable[A], fn: JFunc[A, Future[B]], executor: ExecutionContext): Future[JIterable[B]] = {
|
|
|
|
|
|
implicit val d = executor
|
2019-02-09 15:25:39 +01:00
|
|
|
|
in.asScala.foldLeft(Future(new JLinkedList[B]())) { (fr, a) =>
|
2011-04-15 13:09:53 -06:00
|
|
|
|
val fb = fn(a)
|
2019-03-11 10:38:24 +01:00
|
|
|
|
for (r <- fr; b <- fb) yield { r.add(b); r }
|
2011-04-15 13:09:53 -06:00
|
|
|
|
}
|
2011-10-06 21:19:46 +02:00
|
|
|
|
}
|
2011-03-18 17:26:53 +01:00
|
|
|
|
}
|
2012-01-26 15:11:49 +01:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* This class contains bridge classes between Scala and Java.
|
|
|
|
|
|
* Internal use only.
|
|
|
|
|
|
*/
|
2012-01-26 14:15:25 +01:00
|
|
|
|
object japi {
|
|
|
|
|
|
@deprecated("Do not use this directly, use subclasses of this", "2.0")
|
2012-06-25 13:56:11 +02:00
|
|
|
|
class CallbackBridge[-T] extends AbstractPartialFunction[T, BoxedUnit] {
|
2012-01-26 14:15:25 +01:00
|
|
|
|
override final def isDefinedAt(t: T): Boolean = true
|
2012-02-24 15:03:36 +01:00
|
|
|
|
override final def apply(t: T): BoxedUnit = {
|
|
|
|
|
|
internal(t)
|
|
|
|
|
|
BoxedUnit.UNIT
|
|
|
|
|
|
}
|
2018-12-14 17:48:08 -05:00
|
|
|
|
protected def internal(@unused result: T): Unit = ()
|
2012-01-26 14:15:25 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@deprecated("Do not use this directly, use 'Recover'", "2.0")
|
2012-06-25 13:56:11 +02:00
|
|
|
|
class RecoverBridge[+T] extends AbstractPartialFunction[Throwable, T] {
|
2012-01-26 14:15:25 +01:00
|
|
|
|
override final def isDefinedAt(t: Throwable): Boolean = true
|
|
|
|
|
|
override final def apply(t: Throwable): T = internal(t)
|
2018-12-14 17:48:08 -05:00
|
|
|
|
protected def internal(@unused result: Throwable): T = null.asInstanceOf[T]
|
2012-01-26 14:15:25 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@deprecated("Do not use this directly, use subclasses of this", "2.0")
|
|
|
|
|
|
class BooleanFunctionBridge[-T] extends scala.Function1[T, Boolean] {
|
|
|
|
|
|
override final def apply(t: T): Boolean = internal(t)
|
2018-12-14 17:48:08 -05:00
|
|
|
|
protected def internal(@unused result: T): Boolean = false
|
2012-01-26 14:15:25 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@deprecated("Do not use this directly, use subclasses of this", "2.0")
|
2019-02-09 15:25:39 +01:00
|
|
|
|
class UnitFunctionBridge[-T] extends (T => BoxedUnit) {
|
2012-06-25 13:56:11 +02:00
|
|
|
|
final def apply$mcLJ$sp(l: Long): BoxedUnit = { internal(l.asInstanceOf[T]); BoxedUnit.UNIT }
|
|
|
|
|
|
final def apply$mcLI$sp(i: Int): BoxedUnit = { internal(i.asInstanceOf[T]); BoxedUnit.UNIT }
|
|
|
|
|
|
final def apply$mcLF$sp(f: Float): BoxedUnit = { internal(f.asInstanceOf[T]); BoxedUnit.UNIT }
|
|
|
|
|
|
final def apply$mcLD$sp(d: Double): BoxedUnit = { internal(d.asInstanceOf[T]); BoxedUnit.UNIT }
|
|
|
|
|
|
override final def apply(t: T): BoxedUnit = { internal(t); BoxedUnit.UNIT }
|
2018-12-14 17:48:08 -05:00
|
|
|
|
protected def internal(@unused result: T): Unit = ()
|
2012-01-26 14:15:25 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2012-01-26 15:11:49 +01:00
|
|
|
|
/**
|
|
|
|
|
|
* Callback for when a Future is completed successfully
|
|
|
|
|
|
* SAM (Single Abstract Method) class
|
|
|
|
|
|
*
|
|
|
|
|
|
* Java API
|
|
|
|
|
|
*/
|
2019-04-03 13:13:44 +02:00
|
|
|
|
@silent
|
2012-01-26 14:15:25 +01:00
|
|
|
|
abstract class OnSuccess[-T] extends japi.CallbackBridge[T] {
|
|
|
|
|
|
protected final override def internal(result: T) = onSuccess(result)
|
2012-01-26 15:11:49 +01:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* This method will be invoked once when/if a Future that this callback is registered on
|
|
|
|
|
|
* becomes successfully completed
|
|
|
|
|
|
*/
|
2012-04-24 17:56:18 +02:00
|
|
|
|
@throws(classOf[Throwable])
|
2012-01-26 14:15:25 +01:00
|
|
|
|
def onSuccess(result: T): Unit
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2012-01-26 15:11:49 +01:00
|
|
|
|
/**
|
|
|
|
|
|
* Callback for when a Future is completed with a failure
|
|
|
|
|
|
* SAM (Single Abstract Method) class
|
|
|
|
|
|
*
|
|
|
|
|
|
* Java API
|
|
|
|
|
|
*/
|
2019-04-03 13:13:44 +02:00
|
|
|
|
@silent
|
2012-01-26 14:15:25 +01:00
|
|
|
|
abstract class OnFailure extends japi.CallbackBridge[Throwable] {
|
|
|
|
|
|
protected final override def internal(failure: Throwable) = onFailure(failure)
|
2012-01-26 15:11:49 +01:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* This method will be invoked once when/if a Future that this callback is registered on
|
|
|
|
|
|
* becomes completed with a failure
|
|
|
|
|
|
*/
|
2012-04-24 17:56:18 +02:00
|
|
|
|
@throws(classOf[Throwable])
|
2012-01-26 14:15:25 +01:00
|
|
|
|
def onFailure(failure: Throwable): Unit
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2012-01-26 15:11:49 +01:00
|
|
|
|
/**
|
|
|
|
|
|
* Callback for when a Future is completed with either failure or a success
|
|
|
|
|
|
* SAM (Single Abstract Method) class
|
|
|
|
|
|
*
|
|
|
|
|
|
* Java API
|
|
|
|
|
|
*/
|
2019-04-03 13:13:44 +02:00
|
|
|
|
@silent
|
2012-08-20 15:21:44 +02:00
|
|
|
|
abstract class OnComplete[-T] extends japi.CallbackBridge[Try[T]] {
|
|
|
|
|
|
protected final override def internal(value: Try[T]): Unit = value match {
|
2019-02-09 15:25:39 +01:00
|
|
|
|
case Failure(t) => onComplete(t, null.asInstanceOf[T])
|
|
|
|
|
|
case Success(r) => onComplete(null, r)
|
2012-01-26 14:15:25 +01:00
|
|
|
|
}
|
2012-01-26 15:11:49 +01:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* This method will be invoked once when/if a Future that this callback is registered on
|
|
|
|
|
|
* becomes completed with a failure or a success.
|
|
|
|
|
|
* In the case of success then "failure" will be null, and in the case of failure the "success" will be null.
|
|
|
|
|
|
*/
|
2012-04-24 17:56:18 +02:00
|
|
|
|
@throws(classOf[Throwable])
|
2012-01-26 14:15:25 +01:00
|
|
|
|
def onComplete(failure: Throwable, success: T): Unit
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2012-01-26 15:11:49 +01:00
|
|
|
|
/**
|
|
|
|
|
|
* Callback for the Future.recover operation that conditionally turns failures into successes.
|
|
|
|
|
|
*
|
|
|
|
|
|
* SAM (Single Abstract Method) class
|
|
|
|
|
|
*
|
|
|
|
|
|
* Java API
|
|
|
|
|
|
*/
|
2019-04-03 13:13:44 +02:00
|
|
|
|
@silent
|
2012-01-26 14:15:25 +01:00
|
|
|
|
abstract class Recover[+T] extends japi.RecoverBridge[T] {
|
|
|
|
|
|
protected final override def internal(result: Throwable): T = recover(result)
|
2012-01-26 15:11:49 +01:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* This method will be invoked once when/if the Future this recover callback is registered on
|
|
|
|
|
|
* becomes completed with a failure.
|
|
|
|
|
|
*
|
2012-02-06 16:59:09 +01:00
|
|
|
|
* @return a successful value for the passed in failure
|
2015-05-15 16:53:24 +02:00
|
|
|
|
* Throws the passed in failure to propagate it.
|
2012-01-26 15:11:49 +01:00
|
|
|
|
*
|
|
|
|
|
|
* Java API
|
|
|
|
|
|
*/
|
|
|
|
|
|
@throws(classOf[Throwable])
|
2012-01-26 14:15:25 +01:00
|
|
|
|
def recover(failure: Throwable): T
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2012-01-26 15:11:49 +01:00
|
|
|
|
/**
|
2012-02-26 21:53:17 +01:00
|
|
|
|
* <i><b>Java API (not recommended):</b></i>
|
2012-01-26 15:11:49 +01:00
|
|
|
|
* Callback for the Future.filter operation that creates a new Future which will
|
|
|
|
|
|
* conditionally contain the success of another Future.
|
|
|
|
|
|
*
|
2012-02-26 21:53:17 +01:00
|
|
|
|
* Unfortunately it is not possible to express the type of a Scala filter in
|
|
|
|
|
|
* Java: Function1[T, Boolean], where “Boolean” is the primitive type. It is
|
|
|
|
|
|
* possible to use `Future.filter` by constructing such a function indirectly:
|
|
|
|
|
|
*
|
|
|
|
|
|
* {{{
|
2012-02-27 11:08:02 +01:00
|
|
|
|
* import static akka.dispatch.Filter.filterOf;
|
2012-02-26 21:53:17 +01:00
|
|
|
|
* Future<String> f = ...;
|
2012-02-27 11:08:02 +01:00
|
|
|
|
* f.filter(filterOf(new Function<String, Boolean>() {
|
2012-02-26 21:53:17 +01:00
|
|
|
|
* @Override
|
2012-02-27 11:08:02 +01:00
|
|
|
|
* public Boolean apply(String s) {
|
2012-02-26 21:53:17 +01:00
|
|
|
|
* ...
|
|
|
|
|
|
* }
|
|
|
|
|
|
* }));
|
|
|
|
|
|
* }}}
|
|
|
|
|
|
*
|
|
|
|
|
|
* However, `Future.filter` exists mainly to support Scala’s for-comprehensions,
|
|
|
|
|
|
* thus Java users should prefer `Future.map`, translating non-matching values
|
|
|
|
|
|
* to failure cases.
|
2012-01-26 15:11:49 +01:00
|
|
|
|
*/
|
2012-02-25 19:34:59 +01:00
|
|
|
|
object Filter {
|
2019-02-09 15:25:39 +01:00
|
|
|
|
def filterOf[T](f: akka.japi.Function[T, java.lang.Boolean]): (T => Boolean) =
|
2012-02-27 11:08:02 +01:00
|
|
|
|
new Function1[T, Boolean] { def apply(result: T): Boolean = f(result).booleanValue() }
|
2012-02-25 19:34:59 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2012-01-26 15:11:49 +01:00
|
|
|
|
/**
|
|
|
|
|
|
* Callback for the Future.foreach operation that will be invoked if the Future that this callback
|
|
|
|
|
|
* is registered on becomes completed with a success. This method is essentially the same operation
|
|
|
|
|
|
* as onSuccess.
|
|
|
|
|
|
*
|
|
|
|
|
|
* SAM (Single Abstract Method) class
|
|
|
|
|
|
* Java API
|
|
|
|
|
|
*/
|
2019-04-03 13:13:44 +02:00
|
|
|
|
@silent
|
2012-01-26 14:15:25 +01:00
|
|
|
|
abstract class Foreach[-T] extends japi.UnitFunctionBridge[T] {
|
|
|
|
|
|
override final def internal(t: T): Unit = each(t)
|
2012-01-26 15:11:49 +01:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* This method will be invoked once when/if a Future that this callback is registered on
|
|
|
|
|
|
* becomes successfully completed
|
|
|
|
|
|
*/
|
2012-04-24 17:56:18 +02:00
|
|
|
|
@throws(classOf[Throwable])
|
2012-01-26 14:15:25 +01:00
|
|
|
|
def each(result: T): Unit
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2012-01-26 15:11:49 +01:00
|
|
|
|
/**
|
|
|
|
|
|
* Callback for the Future.map and Future.flatMap operations that will be invoked
|
|
|
|
|
|
* if the Future that this callback is registered on becomes completed with a success.
|
|
|
|
|
|
* This callback is the equivalent of an akka.japi.Function
|
|
|
|
|
|
*
|
2012-04-24 17:56:18 +02:00
|
|
|
|
* Override "apply" normally, or "checkedApply" if you need to throw checked exceptions.
|
|
|
|
|
|
*
|
2012-01-26 15:11:49 +01:00
|
|
|
|
* SAM (Single Abstract Method) class
|
|
|
|
|
|
*
|
|
|
|
|
|
* Java API
|
|
|
|
|
|
*/
|
2012-04-24 17:56:18 +02:00
|
|
|
|
abstract class Mapper[-T, +R] extends scala.runtime.AbstractFunction1[T, R] {
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Override this method to perform the map operation, by default delegates to "checkedApply"
|
|
|
|
|
|
* which by default throws an UnsupportedOperationException.
|
|
|
|
|
|
*/
|
|
|
|
|
|
def apply(parameter: T): R = checkedApply(parameter)
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Override this method if you need to throw checked exceptions
|
|
|
|
|
|
*
|
2015-05-15 16:53:24 +02:00
|
|
|
|
* Throws UnsupportedOperation by default.
|
2012-04-24 17:56:18 +02:00
|
|
|
|
*/
|
|
|
|
|
|
@throws(classOf[Throwable])
|
2019-03-11 10:38:24 +01:00
|
|
|
|
def checkedApply(@unused parameter: T): R =
|
|
|
|
|
|
throw new UnsupportedOperationException("Mapper.checkedApply has not been implemented")
|
2012-04-24 17:56:18 +02:00
|
|
|
|
}
|