All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.thoughtworks.future.concurrent.Converters.scala Maven / Gradle / Ivy

package com.thoughtworks.future.concurrent

import com.thoughtworks.future.{Continuation, Future}

import scala.concurrent.Promise
import scala.util.control.Exception.Catcher
import scala.util.control.TailCalls.{TailRec, done}

/**
  * @author 杨博 (Yang Bo) <[email protected]>
  */
object Converters {

  /**
    * Forwards all [[com.thoughtworks.future.Future]] API to the underlying [[scala.concurrent.Future]].
    */
  implicit final class FromConcurrentFuture[AwaitResult](underlying: scala.concurrent.Future[AwaitResult])(
      implicit executor: scala.concurrent.ExecutionContext)
      extends Future[AwaitResult] {
    import scala.util._

    override def value = underlying.value

    override def onComplete(handler: (Try[AwaitResult]) => TailRec[Unit]): TailRec[Unit] = {
      underlying.onComplete { tryA =>
        executor.execute(new Runnable {
          override def run(): Unit = {
            handler(tryA).result
          }
        })
      }
      done(())

    }
  }

  /**
    * Forwards all [[scala.concurrent.Future]] API to the underlying [[com.thoughtworks.future.Future]].
    */
  implicit final class ToConcurrentFuture[AwaitResult](underlying: Future[AwaitResult])
      extends scala.concurrent.Future[AwaitResult] {
    def transform[S](f: scala.util.Try[AwaitResult] => scala.util.Try[S])(
        implicit executor: scala.concurrent.ExecutionContext): scala.concurrent.Future[S] = {
      val p = Promise[S]
      underlying.onComplete { tryA =>
        p.completeWith(scala.concurrent.Future {
          f(tryA).get
        })
        done(())
      }.result
      p.future
    }

    def transformWith[S](f: scala.util.Try[AwaitResult] => scala.concurrent.Future[S])(
        implicit executor: scala.concurrent.ExecutionContext): scala.concurrent.Future[S] = {
      val p = Promise[S]
      underlying.onComplete { tryA =>
        new Runnable {
          override def run(): Unit = {
            p.completeWith(
              f(tryA)
            )
          }
        }
        done(())
      }.result
      p.future
    }

    import scala.concurrent._
    import scala.concurrent.duration.Duration
    import scala.util._

    override def value: Option[Try[AwaitResult]] = underlying.value

    override def isCompleted: Boolean = underlying.isCompleted

    override def onComplete[U](func: (Try[AwaitResult]) => U)(implicit executor: ExecutionContext) {
      underlying.onComplete { tryA =>
        executor.execute(new Runnable {
          override def run(): Unit = {
            func(tryA)
          }
        })
        done(())
      }.result

    }

    override def result(atMost: Duration)(implicit permit: CanAwait): AwaitResult = {
      ready(atMost)
      value.get match {
        case Success(successValue) => successValue
        case Failure(throwable) => throw throwable
      }
    }

    override def ready(atMost: Duration)(implicit permit: CanAwait): this.type = {
      if (atMost eq Duration.Undefined) {
        throw new IllegalArgumentException
      }
      val lock = new AnyRef

      lock.synchronized {
        {
          implicit def catcher: Catcher[Unit] = {
            case throwable: Throwable => {
              lock.synchronized {
                notifyAll()
              }
            }
          }

          for (successValue <- new Continuation.ContinuationOps(underlying)) {
            lock.synchronized {
              notifyAll()
            }
          }
        }

        if (atMost.isFinite) {
          val timeoutAt = atMost.toNanos + System.nanoTime
          while (!isCompleted) {
            val restDuration = timeoutAt - System.nanoTime
            if (restDuration < 0) {
              throw new TimeoutException
            }
            wait(restDuration / 1000000, (restDuration % 1000000).toInt)
          }
        } else {
          while (!isCompleted) {
            wait()
          }
        }
        this
      }
    }

  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy