2009-09-17 2 views
8

У меня есть серверное приложение, сделанное в Erlang. В нем у меня есть таблица mnesia , которая хранит некоторую информацию о фотографиях. В духе «все это процесс », я решил обернуть эту таблицу в модуле gen_server, так что модуль gen_server является единственным, который напрямую обращается к таблице. Запрос и добавление информации в эту таблицу выполняется путем отправки сообщений этому процессу (у которого есть зарегистрированное имя). Идея состоит в том, что будет несколько клиентов обрабатывать информацию из этой таблицы.Использование gen_server для инкапсуляции таблицы mnesia?

Это работает просто отлично, но что gen_server модуль не имеет состояния. Все, что требуется , хранится в таблице mnesia. Итак, интересно, может ли gen_server не лучшая модель для инкапсуляции этой таблицы?

Должен ли я просто не делать это процессом, а вместо этого инкапсулировать таблицу через функции в этом модуле? В случае ошибки в этом модуле, что приведет к сбою процесса вызова, что, я думаю, может быть лучше, потому что это повлияет только на одного клиента, а не на то, что это приведет к тому, что процесс будет авария, оставив всех без доступа к таблице (до супервизор перезапустит ее).

Любой ввод очень ценится.

ответ

9

Я думаю, согласно Occam's razor нет нет необходимости в этом gen_server существовать, тем более, что нет абсолютно нет состояния в нем хранится. Такой процесс может потребоваться в ситуациях, когда вам нужен доступ к таблице (или любому другому ресурсу), который должен быть строго последовательным (например, вы можете избегать любых прерванных транзакций по стоимости узкого места).

Инкапсулирующий доступ к таблице в модуле является хорошим решением. Он создает без дополнительной сложности, предоставляя надлежащим образом уровень абстракции и инкапсуляции.

6

Я не уверен, что понимаю, почему вы решили инкапсулировать таблицу процессом. Mnesia предназначена для оповещения о множественных параллельных доступах к таблицам, как локально, так и распределенных по кластеру.

Создание модуля API, который выполняет все операции и обновления доступа к таблице, является хорошей идеей, поскольку функции API передадут ваше намерение лучше в коде, который их вызывает. Это будет более читаемым, чем перенос операций mnesia непосредственно в вызывающий код.

Модуль API также дает вам возможность позже переключиться с mnesia на другую систему хранения, если вам нужно. Использование транзакций mnesia внутри вашего модуля API защищает вас от некоторых ошибок программирования, так как mnesia откатывается от операций, которые выходят из строя. Модуль API всегда будет доступен для вызывающих абонентов и позволяет любому количеству вызывающих абонентов выполнять операции одновременно, тогда как API-интерфейс gen_server имеет точку отказа, этот процесс может сделать API недоступным.

Единственное, что API, основанный на gen_server, дает вам API-интерфейс с чисто функциональными возможностями - это сериализовать доступ к таблице, что является необычным требованием, и если вам это специально не нужно, это будет убийца производительности.

0

Может быть хорошей идеей обрабатывать таблицу mnesia, используя один процесс gen_server, когда вы хотите использовать грязный доступ и избегать транзакций. Этот подход может быть быстрее, чем txs, но, как правило, вам нужно сравнить его.

Смежные вопросы