Démonstration de l'utilisation d'ETS avec gen_server

L'ETS (Erlang Term Storage) est une structure de données en mémoire dans Erlang, similaire à une base de données dans d'autres langages. Il permet de stocker et de récupérer des données dans un programme Erlang. **gen\_server** est un modèle d'Erlang utilisé pour créer des serveurs capables de gérer des requêtes clientes concurrentes.

Voici cinq exemples d'utilisation d'ETS dans un **gen\_server** :

Stockage de données

Nous pouvons utilisre ETS pour stocker des données dans la fonction **init** du **gen\_server**:

init([]) ->
    TableId = ets:new(etat, [named_table]),
    {ok, TableId}.

Ici, nous créons une nouvelle table ETS nommée "etat".

Insertion de données

Pour insérer des données, nous utilisons la fonction **handle\_info** du **gen\_server**:

handle_info({requete, IdRequete, Donnees}, TableId) ->
    ets:insert(TableId, {IdRequete, Donnees}),
    {noreply, TableId}.

Nous utilisons ici la fonction **ets:insert** pour ajouter des données à notre table ETS.

Requête de données

Afin de récupérer des données, nous pouvons utiliser le code suivant:

handle_info({requete, IdRequete, _}, TableId) ->
    case ets:lookup(TableId, IdRequete) of
        [] -> {noreply, TableId};
        [{IdRequete, Donnees}] ->
            {reply, Donnees, TableId}
    end.

Ce code utilise la fonction **ets:lookup** pour rechercher des données dans la table ETS.

Mise à jour de données

La mise à jour des données se fait grâce au code suivant:

handle_info({mise_a_jour, IdRequete, NouvellesDonnees}, TableId) ->
    ets:insert(TableId, {IdRequete, NouvellesDonnees}),
    {noreply, TableId}.

Nous utilisons ici la fonction **ets:insert** pour mettre à jour les données existantes dans la table ETS.

Suppression de données

Pour supprimer des données, nous utilisons le code suivant:

handle_info({suppression, IdRequete}, TableId) ->
    ets:delete(TableId, IdRequete),
    {noreply, TableId}.

Ce code utilise la fonction **ets:delete** pour retirer des données de la table ETS.

Parcours de la table ETS

Le parcours de tous les enregistrements de la table ETS peut être réalisé avec **ets:foldl**:

handle_info(parcurir, _From, TableId) ->
    Resultat = ets:foldl(fun(Enregistrement, Accumulateur) -> [Enregistrement | Accumulateur] end, [], TableId),
    {reply, lists:reverse(Resultat), TableId}.

Code exemple

Lors de l'utilisation du module **gen\_server** d'Erlang, il est possible d'utiliser une table ETS pour stocker les données d'état du serveur. Voici un exemple simple illustrant comment utiliser une table ETS dans un **gen\_server**:

-module(demo).
-export([demarrer/0, arreter/0, handle_call/3, handle_cast/2, handle_info/2]).

demarrer() ->
    register(demo, spawn(fun boucle/0)).

arreter() ->
    demo ! arret.

handle_call(Requete, _From, Etat) ->
    ets:insert(Etat#etat.table, {Requete, []}),
    {reply, Requete, Etat}.

handle_cast(arret, Etat) ->
    {stop, normal, Etat}.

handle_info(_, Etat) ->
    {noreply, Etat}.

boucle() ->
    boucle(ets:new(stockage, [named_table])).

boucle(Table) ->
    receive
        arret ->
            ok;
        Message ->
            NouvelleTable = ets:insert(Table, {Message, []}),
            boucle(NouvelleTable)
    end.

Dans ce code, nous définissons un module nommé demo qui comprend les fonctions **demarrer/0** et **arreter/0** pour démarrer et arrêter le serveur, ainsi que les fonctions **handle\_call/3**, **handle\_cast/2** et **handle\_info/2** pour traiter différents types de messages. La fonction **demarrer** enregistre le processus serveur sous le nom **demo**. Dans **handle\_call**, nous insérons une paire clé-valeur dans la table ETS et répondons avec la clé. La fonction **handle\_cast** traite les messages d'arrêt, tandis que **handle\_info** ignore les autres messages. Enfin, la fonction **boucle** reçoit les messages et agit en conséquence, soit en terminent le processus si le message est d'arrêt, soit en insérant le message dans la table ETS et en continuant à écouter.

Étiquettes: Erlang gen_server ets

Publié le 22 septembre à 05h26