ScalaとFuture その２ ~Futureが実行されるまでをソースコードリーディング~

# ScalaとFuture その２
- [その１](https://qiita.com/4245Ryomt/items/63bcf0bf0bab3a99f6b5)
- ScalaのFutureはスレッドが立ち上あがって並列処理を行なっているようだ。
- Futureの実行はExecutionContextが行うらしいがよく知らないので理解を深めたい
- ソースコードを読んでみる
- [参考](https://github.com/scala/scala)

## クラス図
- クラス図の作り方記事 -> https://qiita.com/4245Ryomt/items/71c0b674f56f5920f962
![future.jpg](https://qiita-image-store.s3.amazonaws.com/0/153296/facf7099-9a3c-f753-4cd5-79278b33dc61.jpeg)

## ソースコードから読み解くFuture ~FutureがExecutionContextで実行されるまで~
- ExecutionContextにより実行される(らしい)

```scala

Future { ??? }
```

### Future
- [ソースコード](https://github.com/scala/scala/blob/cc7acdde787fe32ba5894c35d1019963ed094c87/src/library/scala/concurrent/Future.scala#L545)
- Futureのコンパニオンオブジェクトのapplyに処理を渡している
- [apply](https://github.com/scala/scala/blob/69eb09f002a58db17c227a00168a4d529f610d1f/src/library/scala/concurrent/Future.scala#L654) -> [unit](https://github.com/scala/scala/blob/69eb09f002a58db17c227a00168a4d529f610d1f/src/library/scala/concurrent/Future.scala#L612) -> [successful](https://github.com/scala/scala/blob/69eb09f002a58db17c227a00168a4d529f610d1f/src/library/scala/concurrent/Future.scala#L628)
- applyはunitから返る`Promise.successful(result).future`をmapする

#### コードの流れ(scala.concurrent.Future)

```scala

def apply[T](body: =>T)(implicit @deprecatedName('execctx) executor: ExecutionContext): Future[T] =
    unit.map(_ => body)
```

↓

```scala
val unit: Future[Unit] = successful(())
```

↓

```scala
def successful[T](result: T): Future[T] = Promise.successful(result).future
```

- ここまで未だExecutionContextは出てこず
- Promiseが登場してきた

### Promise
- [ソースコード](https://github.com/scala/scala/blob/cc7acdde787fe32ba5894c35d1019963ed094c87/src/library/scala/concurrent/Promise.scala#L28)

- `scala.concurrent.Promise`はトレイト
- `scala.concurrent.impl.Promise`で実装されている
- `scala.concurrent.impl.Promise`は`scala.concurrent.Promise`と`Future`を実装するトレイト

#### コードの流れ(scala.concurrent.Promise)

```scala
trait Promise[T] extends scala.concurrent.Promise[T] with scala.concurrent.Future[T]
```

- さらに、`impl.Promise`を実装している`Kept`

```scala
sealed trait Kept[T] extends Promise[T]
```

- `Future.successful`から呼ばれる`Promise.successful(result).future`は`impl.Promise.KeptPromise[T]`が返される

```scala
def successful[T](result: T): Promise[T] = fromTry(Success(result))
```

↓

```scala
def fromTry[T](result: Try[T]): Promise[T] = impl.Promise.KeptPromise[T](result)
```



### Kept
- [ソースコード](https://github.com/scala/scala/blob/ff32c8a4129b58839568c70a8ef76a52436366f5/src/library/scala/concurrent/impl/Promise.scala#L354)

- `Kept`の`onComplete[U]`の実装を見るとようやく`ExecutionContext`を使う
- `CallbackRunnable`のコンストラクタに`ExecutionContext` と`onComplete`で引数にとった関数`Try[T] => U`を渡し、`CallbackRunnable`の`executeWithValue`を実行している


```scala
private[this] sealed trait Kept[T] extends Promise[T] {
      // 略
      override def onComplete[U](func: Try[T] => U)(implicit executor: ExecutionContext): Unit =
        (new CallbackRunnable(executor.prepare(), func)).executeWithValue(result)
// `CallbackRunnable`は`Runnable`の実装クラス
}
```



- `CallbackRunnable`の`executeWithValue`の実装を見ると`ExecutionContext`の`execute`メソッドへ`CallbackRunnable `自身を渡し実行している。

```scala
private final class CallbackRunnable[T](val executor: ExecutionContext, val onComplete: Try[T] => Any) extends Runnable with OnCompleteRunnable {
  // must be filled in before running it
  var value: Try[T] = null

  override def run() = {
    require(value ne null) // must set value to non-null before running!
    try onComplete(value) catch { case NonFatal(e) => executor reportFailure e }
  }

  def executeWithValue(v: Try[T]): Unit = {
    require(value eq null) // can't complete it twice
    value = v
    // Note that we cannot prepare the ExecutionContext at this point, since we might
    // already be running on a different thread!
    try executor.execute(this) catch { case NonFatal(t) => executor reportFailure t }
  }
}
```

- ここまでで、ようやく`Future`にわたした処理が`ExecutionContext`に渡される(長い..)
- `Successful`, `Failed`が`Kept`の実装クラスになっている -> 冒頭のクラス図
	- Keptのコンパニオンオブジェクトによって`Successful`または`Failed`が生成される

```scala
object KeptPromise {
// 略
  def apply[T](result: Try[T]): scala.concurrent.Promise[T] =
    resolveTry(result) match {
      case s @ Success(_) => new Successful(s)
      case f @ Failure(_) => new Failed(f)
    }
}
```

## ExecutionContext
- [ソースコード](https://github.com/scala/scala/blob/cc7acdde787fe32ba5894c35d1019963ed094c87/src/library/scala/concurrent/ExecutionContext.scala#L59)
- Futureを実行する。traitで定義されている
	- `execute`と`reportFailure`くらいしかない
- executeは`Runnable`を取る
	- Keptで出てきた`CallbackRunnable`が`Runnable`だったね

```scala
trait ExecutionContext {
  def execute(runnable: Runnable): Unit

  def reportFailure(cause: Throwable): Unit
}
```

## なるほど
- `Future.apply`に渡されたブロックは`Promise`を通して`Runnable`になってから`ExecutionContext`にわたされるんだね
- scalaのソースコードは難しいけど読んでいて楽しいね！
- つぎは`scala.concurrent.ExecutionContext.Implicits.global`を読んで、どうやってFuture(から生み出された`Runnable`)が実行されるのか見に行くぞ！