EA Async implémente les méthodes Async-Await dans la JVM. Il permet aux programmeurs d'écrire du code asynchrone de manière séquentielle.
Il est fortement inspiré de Async-Await sur le .NET CLR, voir Programmation asynchrone avec Async et Await pour plus d'informations.
EA Async doit être utilisé pour écrire du code asynchrone non bloquant qui fait un usage intensif de CompletableFutures ou CompletionStage. Il améliore l'évolutivité en libérant les threads de travail pendant que votre code attend d'autres processus ; Et améliore la productivité en rendant le code asynchrone plus simple et plus lisible.
Ce projet a été développé par Electronic Arts et est sous licence BSD à 3 clauses.
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 );
}
}
Dans cet exemple, Bank.decrement
renvoie CompletableFuture<Boolean>
et Inventory.giveItem
renvoie CompletableFuture<String>
EA Async réécrit les appels à Async.await
rendant vos méthodes non bloquantes.
Les méthodes semblent bloquantes mais sont en réalité transformées en méthodes asynchrones qui utilisent CompleteableFutures pour poursuivre l'exécution à mesure que les résultats intermédiaires arrivent.
Voici à quoi ressemble le premier exemple sans EA Async. C'est un peu moins lisible.
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 );
});
}
}
Ceci est un petit exemple... Une méthode avec quelques CompletableFutures supplémentaires peut paraître très compliquée.
EA Async élimine la complexité des CompletableFutures.
Alors vous aimez CompleteableFutures ? Essayez de convertir cette méthode pour utiliser uniquement CompletableFutures sans jamais bloquer (donc pas de jointure) :
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 );
}
}
}
J'ai compris? Envoyez-le-nous. Cela a probablement l'air moche...
EA Async prend actuellement en charge JDK 8-10.
Il fonctionne avec Java et Scala et devrait fonctionner avec la plupart des langages JVM. La seule condition requise pour utiliser EA Async est qu'il doit être utilisé uniquement dans les méthodes qui renvoient CompletableFuture
, CompletionStage
ou des sous-classes 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'
Démarrez votre application avec un paramètre JVM supplémentaire : -javaagent:ea-async-1.2.3.jar
java -javaagent:ea-async-1.2.3.jar -cp your_claspath YourMainClass args...
Il est recommandé de l'ajouter comme option par défaut aux lanceurs des projets IntelliJ qui utilisent ea-async.
Sur votre cours principal ou le plus tôt possible, appelez au moins une fois :
Async.init();
À condition que votre JVM ait la fonctionnalité activée, cela démarrera un agent d'instrumentation d'exécution. Si vous oubliez d'invoquer cette fonction, le premier appel à await
initialisera le système (et imprimera un avertissement).
Il s'agit d'une solution de test et de développement, elle comporte le moins de configuration. Cela pourrait interférer avec le débogage de la JVM. Cette alternative est présente comme solution de repli.
Le ea-async-1.2.3.jar est un pot exécutable qui peut pré-instrumenter vos fichiers.
Usage:
java -cp YOUR_PROJECT_CLASSPATH -jar ea-async-1.2.3.jar classDirectory
Exemple:
java -cp guava.jar ; commons-lang.jar -jar ea-async-1.2.3.jar target/classes
Après cela, tous les fichiers de target/classes auront été instrumentés. Il n’y aura plus aucune référence à Async.await
et Async.init
dans ces classes.
Utilisez le plugin ea-async-maven. Il instrumentera vos classes au moment de la compilation et supprimera toutes les références à Async.await
et Async.init()
.
Avec l'instrumentation au moment de la construction, les utilisateurs de votre projet n'auront pas besoin d'avoir EA Async dans leur chemin de classe, à moins qu'ils ne choisissent également de l'utiliser. Cela signifie qu'EA Async n'a pas besoin d'être une dépendance transitive .
C'est la meilleure option pour les bibliothèques et les projets 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 >