Vous utilisez gen_server pour encapsuler une table mnesia?
Question
J'ai une application serveur créée à Erlang. J'y ai une table de mnesia
qui stocke des informations sur les photos. Dans l'esprit de "tout est un
traiter " J'ai décidé d'envelopper cette table dans un module gen_server
, de sorte que le
Le module gen_server
est le seul qui accède directement à la table. Interrogation
et l'ajout d'informations à cette table se fait en envoyant des messages à ce processus
(qui a un nom enregistré). L’idée est qu’il y aura plusieurs clients
traite les informations d'interrogation de cette table.
Cela fonctionne très bien, mais ce module gen_server
n'a pas d'état. Tout ça
require est stocké dans la table mnesia. Donc, je me demande si un gen_server
est peut-être
pas le meilleur modèle pour encapsuler cette table?
Dois-je simplement ne pas en faire un processus, mais plutôt encapsuler la table
à travers les fonctions de ce module? En cas de bug dans ce module, cela
provoquerait le blocage du processus d’appel, ce qui, à mon avis, pourrait être meilleur, car
cela n'affecterait qu'un seul client, par opposition à maintenant, alors que cela causerait la
processus gen_server
à se bloquer, laissant tout le monde sans accès à la table (jusqu'à ce que
le superviseur le redémarre).
Toute contribution est grandement appréciée.
La solution
Je suppose que selon le le rasoir d'Occam , il y a nul besoin de ce gen_server
pour exister , d’autant plus qu’il contient aucun état . Un tel processus peut être nécessaire dans les situations où vous devez accéder à la table (ou à toute autre ressource) de manière strictement séquentielle (par exemple, vous pourriez vouloir éviter toute transaction annulée à coût d'un goulot d'étranglement).
Encapsuler l’accès à la table dans un module est une bonne solution . Il ne crée aucune complexité supplémentaire , tout en fournissant le niveau approprié d'abstraction et d'encapsulation.
Autres conseils
Je ne suis pas sûr de comprendre pourquoi vous avez décidé d'encapsuler une table avec un processus. Mnesia est conçu pour gérer plusieurs accès simultanés aux tables, à la fois localement et sur un cluster.
La création d'un module d'API qui effectue toutes les opérations d'accès à la table et les mises à jour particulières est une bonne idée car les fonctions de l'API traduiront mieux votre intention dans le code qui les appelle. Ce sera plus lisible que de mettre les opérations mnesia directement dans le code appelant.
Un module API vous offre également la possibilité de passer ultérieurement de mnesia à un autre système de stockage, si vous en avez besoin. L'utilisation de transactions mnesia dans votre module d'API vous protège de certaines erreurs de programmation, car mnesia annulera les opérations qui se bloquent. Le module API sera toujours disponible pour les appelants et permettra à un nombre quelconque d’appel d’effectuer des opérations simultanément, alors qu’une API basée sur gen_server a un point d’échec, le processus, qui peut rendre l’API indisponible.
La seule chose qu'une API basée sur gen_server vous offre par rapport à une API purement fonctionnelle est de sérialiser l'accès à la table - ce qui est une exigence inhabituelle et, à moins que vous n'en ayez spécifiquement besoin, ce sera un destructeur de performances.
Il peut être judicieux de gérer une table mnesia à l'aide d'un seul processus gen_server lorsque vous souhaitez utiliser un accès modifié et éviter les transactions. Cette approche est peut-être plus rapide que les tx, mais comme d’habitude, vous devez la comparer.