JEE 7 Batch Processing - partie #2

JEE7 batch processing : différence bachlet et step

Nous avons vu précédemment de façon théorique, comment une API de batch est structurée et quels doivent être les éléments constitutifs d’un step (partie de traitement unitaire d’un batch). Nous avons également vu en détail comment cette API doit se conformer au flot d’exécution d’un batch.

Nous allons présenter ci-dessous comment JEE 7 implémente les concepts vu précédemment et comment définir les éléments du batch, ce qui nous permettra de présenter les différences entre batchlet et step. Nous traiterons ensuite des checkpoint qui présentent un mécanisme point de sauvegarde. Finalement nous discuterons de la gestion des erreurs par cette API.

Les étapes d’un batch, l’élément <step>

  • L’API du batch propose deux versions de la notion de Step : les batchlet et les chunk.

L’élément <batchlet>

Un élément batchlet est une étape qui peut être utilisée pour un traitement en tache de fond qui ne nécessite pas de suivre le pattern Read / Process / Write. L’interface Batchlet possède deux méthodes :

public String process() throws Exception;
public void stop() throws Exception;

La définition XML se fait alors de la façon suivante :

<step id="batchlet-0">
<batchlet ref="MonBatchlet" />

Avec l’attribut ref qualifie un nom complet ou un alias (exposé par CDI) pointant vers une implémentation de l’interface Batchlet.

L’élément <chunck>

Un chunk est une étape unitaire qui suit le modèle Reader / Processor / Writer. La définition se fait de la façon suivante :

<step id="id">
<chunk checkpoint-policy="custom" item-count="1">
	<reader>reader</reader>
	<writer>writer</writer>
	<processor>processor</processor>
</chunk>
</step>

Avec les valeurs des tags (reader, writer et processor) qui qualifient un nom complet ou un alias (exposé par CDI) pointant respectivement vers une implémentation de ItemReader, ItemWriter et ItemProcessor.

Le paramètre check-point-policy précise quelle stratégie de checkpoints est mise en place. La valeur item définit un checkpoint qui interviendra à l’issue d’un nombre d’éléments, cet intervalle étant définit par la valeur de item-count (la valeur de item-count n’est pas prise en compte dans le cas de ckeck-point-policy à custom).

L’élément <reader>

C’est la classe qui va lire les éléments disponibles sur le flux d’entrée, elle doit implémenter les méthodes suivantes :

void open(Serializable checkpoint) throws Exception;
void close() throws Exception;
T readItem() throws Exception;
Serializable checkpointInfo() throws Exception;
  • readItem va lire l’élément suivant disponible dans le flux et construire un objet résultat ou renvoyer null si plus aucun élément n’est disponible,
  • open permet d’exécuter des traitements avant la lecture, elle reçoit en entrée le dernier checkpoint généré pour ce reader,
  • close est exécutée en fin de lecture de items du flux,
  • checkPointInfo récupère les dernières informations correspondant au checkpoint enregistré.

L’élément <processor>

Une fois un item lu par le reader, la méthode processItem du processor prend le relais. La classe processor doit implémenter la méthode suivante :

R processItem(T item) throws Exception;

Un élément est traité par cette méthode et transformé. L’ensemble des éléments traités sont alors passés au writer.

L’élément <writer>

L’ItemWriter va se charger d’envoyer la liste de résultats sur un flux de sortie par exemple. Le writer doit implémenter les méthodes suivantes :

void open(Serializable checkpoint) throws Exception
void close() throws Exception
void writeItems(List<T> items) throws Exception
Serializable checkpointInfo() throws Exception

Les méthodes close, open et checkpointInfo sont similaires à celles de l’ItemWriter.

La méthode writeItems va recevoir les éléments traités par le couple Reader / Processor et les envoyer par exemple vers le flux de sortie, les stocker en base, les enregistrer dans un fichier, etc.

Les checkpoints

Dans un cadre transactionnel, un checkpoint va définir une marque utilisable par le processus batch, celle-ci renseignant le batch sur l’étape où il se trouve dans le traitement (par exemple dans le cas d’une reprise ou d’un rollback). Ce checkpoint est transmis au Reader, il peut être créé en début de traitement lors de l’appel à la méthode open.

Le checkpoint peut contenir toute information relative à l’exécution en cours (il doit toutefois implémenter l’interface Serializable). Il peut par exemple contenir le numéro de l’élément lu, le numéro de ligne dans un fichier en entrée, etc. L’objet checkpoint renvoyé par la méthode checkpointInfo.

Personnalisation des checkpoint : l’élément <checkpoint-algorithm>

Par défaut, l’enregistrement du checkpoint se déclenche pour suite à un certain nombre d’éléments (Item). Il est possible de personnaliser ce comportement en définissant un algorithme.

Pour cela la balise checkpoint-algorithm fait le lien avec une classe implémentant l’interface CheckpointAlgorithm et qui définit les méthodes :

public int checkpointTimeout() throws Exception;
public void beginCheckpoint() throws Exception;
public boolean isReadyToCheckpoint() throws Exception;
public void endCheckpoint() throws Exception;

La méthode la plus importante est isReadyToCheckpoint, elle va indiquer au batch s’il doit démarrer un nouveau checkpoint.

Exemple : effectuer un checkpoint toutes les cinq secondes.

public class TestCheckPointAlgorithm extends AbstractCheckpointAlgorithm {
[…]
private long time;
public TestCheckPointAlgorithm() {
	time = System.currentTimeMillis();
}

public boolean isReadyToCheckpoint() throws Exception {
	boolean result = System.currentTimeMillis() - time >= 5000l && time != 0l;
	[…]
	return result;
}
[…]

beginCheckpoint et endCheckpoint sont appelées respectivement en début et fin de checkpoint.

Note sur les transactions

Chaque étape de type chunk peut être exécutée dans une transaction qui lui est propre. Lorsque le nombre d’éléments traités correspond à la valeur de la configuration et que la transaction est globale au Step, les données sont commitées. Pour un checkpoint custom, la transaction est validée si l’algorithme de checkpoint renvoie true pour l’appel à isReadyToCheckpoint.

La durée de la transaction globale est définie par la propriété suivante : javax.transaction.global.timeout={durée en secondes} – la valeur par défaut est de 180 secondes.

Cette valeur peut être passée en paramètre au niveau de la définition du Step.

<step id="…">
	<properties>
		<property name="javax.transaction.global.timeout" value="600"/>
	</properties>
</step>

Gestion des erreurs

Toute exception renvoyée par un listener qui est définit au niveau racine provoque l’arrêt du Job avec un statut FAILED.

Toute exception envoyée par un Job ou par un élément de niveau Step pendant le traitement des étapes provoque l’arrêt de l’étape et du Job associé avec un statut FAILED.

Par défaut, quand une exception est remontée depuis un traitement de type chunk, le Job se termine avec un statut FAILED. Il est toutefois possible d’outrepasser ce comportement avec un certain nombre de balises.

  • skippable-exception-classes permet d’ignorer des exceptions ou de poursuivre si une exception survient. Une liste d’exceptions peut-être précisée avec les sous-balises include et exclude (la valeur étant le nom complet des classes d’exceptions). Il peut y avoir plusieurs occurrences de ces sous-balises.

Par exemple :

<skippable-exception-classes>
	<include class="java.lang.RuntimeException"/>
	<exclude class="java.io.IOException"/>
</skippable-exception-classes>
  • retryable-exception-classes permet de préciser les exceptions pour lesquelles l’élément chunk va essayer à nouveau de s’exécuter. Comme ci-dessus, il est possible de préciser des listes d’exclusion et d’inclusion des exceptions.

Exemple :

<retryable-exception-classes>
   	<include class="java.lang.IllegalArgumentException"/>
</retryable-exception-classes>

On peut préciser que le batch n’effectue pas de rollback lorsque des exceptions surviennent avec la balise no-rollback-exception-classes :

<no-rollback-exception-classes >
	<include class="java.lang.IllegalArgumentException"/>
</no-rollback-exception-classes>

Toute tache de type batchlet qui lève une exception interrompt le traitement du Job avec un statut FAILED.


Nous avons vu dans cette partie les éléments principaux permettant la mise en œuvre d’un bacth (step, transaction, gestions des erreurs et points de sauvegarde).

Nous verrons dans la partie suivante comment s’opère la programmation avancée des batch. Pour cela nous présenterons l’utilisation des listeners sur les différentes éléments du batch ; nous discuterons des outils permettant la création d’un flot d’exécution, des outils pour le morcellement des étapes ; finalement nous ferons le point sur le paramétrage des éléments du batch.

0 commentaires

votre commentaire

Se joindre à la discussion ?
Vous êtes libre de contribuer !

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Inscription newsletter

Ne manquez plus nos derniers articles !