Как добиться потокобезопасности для состояния ETS в Erlang?

Я создал процесс объединения соединений в Erlang, который имеет подпроцессы (каждый из которых является соединением). Процесс объединения соединений (супервизор) должен хранить состояние всех дочерних подпроцессов, например флаг, указывающий, доступен ли подпроцесс для сдачи в аренду запрашивающей стороне. Это состояние хранится в таблице ETS.

ПУЛ-МАСТЕР:

  • процесс подключения 1
  • процесс подключения 2
  • процесс подключения 3

Когда клиент запрашивает подключение к POOL-MASTER, он должен выяснить, какой процесс подключения доступен, просматривая ETS и получая состояние. Этот этап называется "получить аренду". Затем состояние обновляется. Точно так же, когда клиент возвращает соединение с пулом, он использует функцию "return-lease", которая помечает элемент как доступный для следующего клиента.

Я хочу, чтобы функции выше "get-lease и return-lease" были поточно-ориентированными. Другими словами, я хочу убедиться, что ни один клиент не использует эти функции одновременно, иначе получается, что состояние соединений может быть перепутано (два клиента получают одно и то же соединение). В java для этой цели будет использоваться синхронизированный метод.

Есть ли что-нибудь в erlang, что можно сделать для этого? Например, какой-то механизм блокировки в таблице ETS, а затем снятие блокировки? Или это следует сделать, создав единый процесс, который обрабатывает определенные функции, которые должны быть заблокированы/разблокированы, и отправляет сообщения этому процессу (при условии, что обмен сообщениями является однопоточным)?


person gextra    schedule 26.10.2013    source источник
comment
Как уже указывалось в ответах, в ETS нет или, скорее, ОЧЕНЬ ограничена обработка транзакций по дизайну. Если вам нужны транзакции, вам нужно обернуть доступ к ETS в процессе.   -  person rvirding    schedule 26.10.2013


Ответы (2)


Поточно-безопасный? Что это ? Erlang этого не знает :) так как мы работаем над передачей сообщений между процессами. Это гарантирует, что доступ к любой структуре (поддерживаемой серверным erlang-процессом) всегда будет сериализованным способом [так же, как упомянул Дон Брэнсон.]

What I would have done is:

1. Create a gen server process monitored by a supervisor process.

2. Этот серверный процесс будет менеджером вашей таблицы ETS и предоставляет API/методы, которые будут вызываться клиентами для запроса и освобождения соединений.

3. Запросы будут обрабатываться handle_call (для синхронного вызова) или handle_cast (для асинхронного вызова).

4. Возможно, вы даже захотите реализовать некоторые функции тайм-аута для освобождения соединений путем повторения вашей таблицы ETS и удаления из нее на основе некоторых критериев.

Вышеупомянутое будет отлично работать, давая вам достойную производительность (если производительность придет вам на ум). И никаких условий гонки, поскольку доступ сериализован.

person Arunmu    schedule 26.10.2013
comment
означает ли это, что два параллельных процесса A и B, вызывающие одну и ту же функцию mymodule:myfunc(x) в одно и то же время, будут фактически поставлены в очередь и обслуживаться myfunc(x) по одному? - person gextra; 26.10.2013
comment
Да, если мой модуль является генсервером. Также да, если myfunc в mymodule — это простая функция, выполняющая прием и отправку (!) - person Arunmu; 26.10.2013

Одним из подходов может быть процесс, предназначенный для управления арендой посредством обмена сообщениями. Отправьте этому процессу сообщение get_lease. Он получит сообщение об аренде, тем самым упорядочив доступ, и отправит ответное сообщение запрашивающему процессу, когда аренда станет доступной. Арендатор отправит менеджеру сообщение return_lease, которое вернет аренду в список бесплатных.

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

person Don Branson    schedule 26.10.2013