Pergunta

I use Play Framework 2.2

In order to implement a WebSocket connection, I use a Concurrent.unicast that fits my needs:

val enumerator = Concurrent.unicast[JsValue] {
    channel => userIdWithChannelMap += u.id -> channel
}

However, the source code of Concurrent.unicast shows the needs of several arguments:

def unicast[E](
    onStart: Channel[E] => Unit,
    onComplete: => Unit = (),
    onError: (String, Input[E]) => Unit = (_: String, _: Input[E]) => ())(implicit ec: ExecutionContext)

I understand that onComplete is executed when an Iteratee is Done.
However what is the difference between onComplete callback and the map method of the Iteratee:

/**
   *
   * Uses the provided function to transform the Iteratee's computed result when the Iteratee is done.
   *
   * @param f a function for transforming the computed result
   * $paramEcSingle
   */
  def map[B](f: A => B)(implicit ec: ExecutionContext): Iteratee[E, B] = this.flatMap(a => Done(f(a), Input.Empty))(ec)

Besides, what is the need for Enumerator#onDoneEnumerating, presented in the source code.
Indeed, I came across some implementation of WebSocket dealing with:

Concurrent.unicast{...}.onDoneEnumerating{...}

I'm confused with onComplete, onDoneEnumerating and Iteratee#map.
May anyone explain the differences?
And especially, why Concurrent#broadcast doesn't present an onComplete argument as unicast does.

Hard to find some good docs about the Iteratee world.

Foi útil?

Solução

Each of these is different, but the differences are subtle.

The onComplete parameter of unicast lets you setup a callback for when the Iteratee that it is applied to completes successfully. The separate onError callback is for when it fails.

The onDoneEnumerating method of Enumerator lets you attach a callback that will be called if the Iteratee either completes successfully or fails.

Iteratee.map allows you to attach a callback to an Iteratee that completes successfully, and alter the value that it completes with.

Concurrent.broadcast doesn't take onComplete or onError callbacks because it can be applied to multiple Iteratee instances, which won't necessarily behave the same way. One instance may die with an error, while another one completes successfully at a later time, while another never completes. Because of this it is unlikely for it to make sense for the code running the Enumerator to react to these events.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top