¿Usa gen_server para encapsular una tabla de mnesia?
Pregunta
Tengo una aplicación de servidor hecha en Erlang. En ella tengo una mesa de mnesia
que almacenan alguna información en fotos. En el espíritu de " todo es un
proceso " Decidí envolver esa tabla en un módulo gen_server
, para que el
El módulo gen_server
es el único que accede directamente a la tabla. Consulta
y agregar información a esa tabla se realiza enviando mensajes a ese proceso
(que tiene un nombre registrado). La idea es que habrá varios clientes
procesa la consulta de información de esa tabla.
Esto funciona bien, pero ese módulo gen_server
no tiene estado. Todo lo
requiere se almacena en la tabla de mnesia. Entonces, me pregunto si un gen_server
es quizás
¿No es el mejor modelo para encapsular esa tabla?
¿No debería simplemente convertirlo en un proceso y, en cambio, solo encapsular la tabla
a través de las funciones en ese módulo? En caso de un error en ese módulo, eso
causaría que el proceso de llamada se bloquee, lo que creo que podría ser mejor, porque
solo afectaría a un solo cliente, a diferencia de ahora, cuando causaría
El proceso gen_server
se bloquea, dejando a todos sin acceso a la tabla (hasta
el supervisor lo reinicia).
Cualquier entrada es muy apreciada.
Solución
Supongo que según La navaja de Occam hay gen_server
exista , especialmente porque no hay absolutamente ningún estado almacenado en él. Tal proceso podría ser necesario en situaciones en las que necesita acceso a la tabla (o cualquier otro recurso) para ser estrictamente secuencial (por ejemplo, podría querer evitar cualquier transacción abortada en costo de un cuello de botella).
Encapsular el acceso a la tabla en un módulo es una buena solución . Crea sin complejidad adicional , al tiempo que proporciona un nivel de abstracción y encapsulación adecuado .
Otros consejos
No estoy seguro de entender por qué ha decidido encapsular una tabla con un proceso. Mnesia está diseñada para mediar múltiples accesos concurrentes a tablas, tanto localmente como distribuidos en un clúster.
Crear un módulo API que realice todas las operaciones y actualizaciones particulares de acceso a la tabla es una buena idea ya que las funciones API transmitirán mejor su intención en el código que las llama. Será más legible que poner las operaciones de mnesia directamente en el código de llamada.
Un módulo API también le da la opción de cambiar de mnesia a otro sistema de almacenamiento más adelante si es necesario. El uso de transacciones de mnesia dentro de su módulo API lo protege de algunos errores de programación, ya que mnesia revertirá las operaciones que se bloquean. El módulo API siempre estará disponible para las personas que llaman y permite que cualquier número de personas realice operaciones simultáneamente, mientras que una API basada en gen_server tiene un punto de falla, el proceso, que puede hacer que la API no esté disponible.
Lo único que una API basada en gen_server le brinda a través de una API puramente funcional es serializar el acceso a la tabla, lo cual es un requisito inusual y, a menos que lo necesite específicamente, será un asesino de rendimiento.
Puede ser una buena idea manejar una tabla de mnesia utilizando un único proceso gen_server cuando desee utilizar el acceso sucio y evitar transacciones. Este enfoque puede ser más rápido que los txs, pero, como de costumbre, debe compararlo.