scala asynchronous concurrency scalaz scalaz7

Un poco de ayuda para entender el futuro y la tarea de Scalaz.



asynchronous concurrency (4)

Estoy tratando de entender la idea y el propósito detrás del paquete concurrente de scalaz, principalmente las clases de Tarea y Futuro, pero al usarlas en alguna aplicación, ahora está lejos de ser analógico secuencial simple, mientras que scala.concurrent.Future , funciona más que mejor. ¿Puede alguien compartir su experiencia al escribir una aplicación concurrente / asíncrona con scalaz, básicamente cómo usar su método async correctamente? Como entiendo por las fuentes, async no usa un hilo separado como el llamado al future estándar, o los métodos de fork/apply de Scalaz funcionan, entonces ¿por qué se llama async ? ¿Significa que para obtener una concurrencia real con scalaz siempre tengo que llamar a fork(now(...)) o apply ?



No soy un experto en scalaz, pero intentaré ayudarte un poco. Déjame intentar responder a tus preguntas una por una:

1) ¿Puede alguien compartir su experiencia al escribir una aplicación concurrente / asíncrona con scalaz, básicamente cómo usar su método asíncrono correctamente?

Veamos primero la firma async :

def async[A](listen: (A => Unit) => Unit): Future[A]

Esto podría ser un poco críptico al principio, por lo que siempre es una buena idea ver las pruebas para entender los posibles casos de uso. En https://github.com/scalaz/scalaz/blob/scalaz-seven/tests/src/test/scala/scalaz/concurrent/FutureTest.scala puede encontrar el siguiente código:

"when constructed from Future.async" ! prop{(n: Int) => def callback(call: Int => Unit): Unit = call(n) Future.async(callback).run must_== }

Como sabemos por la firma Future.async simplemente construya un nuevo Futuro utilizando la función de firma (A => Unit) => Unit . Lo que realmente significa es que Future.async toma como función de parámetro la cual para una devolución de llamada determinada realiza todos los cálculos necesarios y pasa el resultado a esa devolución de llamada.
Lo que es importante tener en cuenta es que Future.async no ejecuta ningún cálculo en sí mismo, solo prepara la estructura para ejecutarlos más tarde.

2) Como entiendo por las fuentes, async no usa un hilo separado como el llamado al futuro estándar, o los métodos de bifurcación / aplicación de Scalaz funcionan, entonces ¿por qué se llama async?

Estás en lo correcto. Solo fork y apply parece estar ejecutando cualquier cosa utilizando subprocesos, lo cual es fácil de notar al mirar las firmas que contienen el implicit pool: ExecutorService . No puedo hablar por los autores aquí, pero supongo que async está relacionado con la devolución de llamada. Significa que en lugar de bloquear en Futuro para obtener un resultado al final, usarás la devolución de llamada asíncrona.

3) ¿Significa que para obtener una concurrencia real con scalaz siempre tengo que llamar a fork (now (...)) o aplicar?

Por lo que puedo decir, sí. Tenga en cuenta que cuando está creando Future utilizando la sintaxis Future(x) , está utilizando el método de apply aquí, por lo que este es un tipo de comportamiento predeterminado (que está bien).

Si desea comprender mejor el diseño de Scalaz Futures, le recomiendo que lea "Programación funcional en Scala" . Creo que este libro está escrito por los principales colaboradores de Scalaz y en el capítulo 7 se analiza el diseño de API para una biblioteca de paralelismo puramente funcional. No es exactamente lo mismo que Scalaz Future, pero puedes ver muchas similitudes.


También puede leer la maravillosa publicación del blog de Timothy Perrett sobre Tarea y futuro de Scalaz que cubre muchos detalles no tan obvios.


async se utiliza para adaptar una API asíncrona basada en el callback como Future . Se llama async porque se espera que se use con algo que se ejecute de forma asíncrona, tal vez llamando a la devolución de llamada desde otro hilo en algún lugar más abajo de la línea. Esta es una concurrencia "real", siempre que la API a la que llama realmente la use de forma asíncrona (por ejemplo, uso Future.async con las partes asíncronas del AWS SDK como AmazonSimpleDBAsyncClient ).

Si desea la concurrencia "real" de la API de Task scalaz directamente, debe usar elementos como fork o gatherUnordered , ya que muchas de las API están predeterminadas para ser seguras / deterministas y reiniciables, con concurrencia solo cuando se solicita explícitamente.