EA Async implementa métodos Async-Await en la JVM. Permite a los programadores escribir código asincrónico de forma secuencial.
Está muy inspirado en Async-Await en .NET CLR; consulte Programación asincrónica con Async y Await para obtener más información.
EA Async debe usarse para escribir código asincrónico sin bloqueo que haga un uso intensivo de CompletableFutures o CompletionStage. Mejora la escalabilidad al liberar subprocesos de trabajo mientras su código espera otros procesos; Y mejora la productividad al hacer que el código asincrónico sea más simple y legible.
Este proyecto fue desarrollado por Electronic Arts y tiene la licencia BSD de 3 cláusulas.
import static com . ea . async . Async . await ;
import static java . util . concurrent . CompletableFuture . completedFuture ;
public class Store
{
public CompletableFuture < Boolean > buyItem ( String itemTypeId , int cost )
{
if (! await ( bank . decrement ( cost ))) {
return completedFuture ( false );
}
await ( inventory . giveItem ( itemTypeId ));
return completedFuture ( true );
}
}
En este ejemplo, Bank.decrement
devuelve CompletableFuture<Boolean>
e Inventory.giveItem
devuelve CompletableFuture<String>
EA Async reescribe las llamadas a Async.await
haciendo que sus métodos no bloqueen.
Los métodos parecen bloqueantes, pero en realidad se transforman en métodos asincrónicos que utilizan CompletableFutures para continuar la ejecución a medida que llegan los resultados intermedios.
Así es como se ve el primer ejemplo sin EA Async. Es un poco menos legible.
import static java . util . concurrent . CompletableFuture . completedFuture ;
public class Store
{
public CompletableFuture < Boolean > buyItem ( String itemTypeId , int cost )
{
return bank . decrement ( cost )
. thenCompose ( result -> {
if (! result ) {
return completedFuture ( false );
}
return inventory . giveItem ( itemTypeId ). thenApply ( res -> true );
});
}
}
Este es un pequeño ejemplo... Un método con algunos CompletableFutures más puede parecer muy complicado.
EA Async abstrae la complejidad de CompletableFutures.
¿Entonces te gusta CompletableFutures? Intente convertir este método para usar solo CompletableFutures sin bloquear nunca (por lo que no se puede unir):
import static com . ea . async . Async . await ;
import static java . util . concurrent . CompletableFuture . completedFuture ;
public class Store
{
public CompletableFuture < Boolean > buyItem ( String itemTypeId , int cost )
{
if (! await ( bank . decrement ( cost ))) {
return completedFuture ( false );
}
try {
await ( inventory . giveItem ( itemTypeId ));
return completedFuture ( true );
} catch ( Exception ex ) {
await ( bank . refund ( cost ));
throw new AppException ( ex );
}
}
}
¿Entiendo? Envíanoslo. Probablemente se vea feo...
EA Async actualmente es compatible con JDK 8-10.
Funciona con Java y Scala y debería funcionar con la mayoría de los lenguajes JVM. El único requisito para usar EA Async es que debe usarse solo dentro de métodos que devuelven CompletableFuture
, CompletionStage
o subclases de CompletableFuture
.
< dependency >
< groupId >com.ea.async</ groupId >
< artifactId >ea-async</ artifactId >
< version >1.2.3</ version >
</ dependency >
'com.ea.async:ea-async:1.2.3'
Inicie su aplicación con un parámetro JVM adicional: -javaagent:ea-async-1.2.3.jar
java -javaagent:ea-async-1.2.3.jar -cp your_claspath YourMainClass args...
Se recomienda agregar esto como opción predeterminada a los lanzadores en proyectos IntelliJ que usan ea-async.
En tu clase principal o lo más temprano posible, llama al menos una vez:
Async.init();
Siempre que su JVM tenga la capacidad habilitada, esto iniciará un agente de instrumentación en tiempo de ejecución. Si olvida invocar esta función, la primera llamada a await
inicializará el sistema (e imprimirá una advertencia).
Esta es una solución para pruebas y desarrollo, tiene la menor cantidad de configuración. Podría interferir con la depuración de JVM. Esta alternativa está presente como alternativa.
ea-async-1.2.3.jar es un jar ejecutable que puede instrumentar previamente sus archivos.
Uso:
java -cp YOUR_PROJECT_CLASSPATH -jar ea-async-1.2.3.jar classDirectory
Ejemplo:
java -cp guava.jar ; commons-lang.jar -jar ea-async-1.2.3.jar target/classes
Después de eso, se habrán instrumentado todos los archivos en destino/clases. No quedarán referencias a Async.await
y Async.init
en esas clases.
Utilice el complemento ea-async-maven. Instrumentará sus clases en tiempo de compilación y eliminará todas las referencias a Async.await
y Async.init()
.
Con la instrumentación en tiempo de compilación, los usuarios de su proyecto no necesitarán tener EA Async en su classpath a menos que también decidan usarlo. Esto significa que EA Async no necesita ser una dependencia transitiva .
Esta es la mejor opción para bibliotecas y proyectos maven.
< build >
< plugins >
< plugin >
< groupId >com.ea.async</ groupId >
< artifactId >ea-async-maven-plugin</ artifactId >
< version >1.2.3</ version >
< executions >
< execution >
< goals >
< goal >instrument</ goal >
< goal >instrument-test</ goal >
</ goals >
</ execution >
</ executions >
</ plugin >
</ plugins >
</ build >