Erlang/ets: сбросить таблицу ets после получения неверного аргумента?

Я учился использовать ets, но одна вещь, которая меня беспокоила, это то, что иногда* ets:match выдает bad argument… И, начиная с них, все последующие вызовы (даже вызовы, которые раньше работали) также выдают bad argument:

> ets:match(Tid, { [$r | '$1'] }, 1).
% this match works...
% Then, at some point, this comes up:
** exception error: bad argument
     in function  ets:match/3
        called as ets:match(24589,{[114|'$1']},1)
% And from then on, matches stop working:
> ets:match(Tid, { [$r | '$1'] }, 1).
** exception error: bad argument
     in function  ets:match/3
        called as ets:match(24589,{[114|'$1']},1)

Есть ли способ «сбросить» систему ets, чтобы я мог снова запросить ее (т.е. из оболочки)?

*: Я не смог воспроизвести проблему... Но это случается довольно часто, когда я пытаюсь заняться "другими делами".


person David Wolever    schedule 27.12.2009    source источник


Ответы (2)


Хотя я не уверен на 100%, эта тема кажется, отвечает на ваш вопрос. Похоже, вы наблюдаете такое поведение в оболочке. Если это так, то два факта взаимодействуют запутанным образом:

  1. Таблица ets удаляется, как только завершается процесс, владеющий ею.
  2. Оболочка erlang умирает всякий раз, когда получает исключение, и автоматически перезапускается.

Итак, когда вы получаете первое исключение, текущий процесс оболочки умирает, вызывая удаление таблицы ets, а затем для вас запускается новый процесс оболочки. Теперь, когда вы попробуете еще раз ets:match, произойдет сбой, потому что таблицы больше не существует.

person Dale Hagglund    schedule 27.12.2009

Дейл уже сказал тебе, что происходит. Вы можете подтвердить это, время от времени вызывая self() в оболочке.

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

1> self().
<0.32.0>    % shell's Pid

2> spawn(fun() -> ets:new(my_table, [named_table, public]), receive X -> ok end end).
<0.35.0>    % the spawned process's Pid

3> ets:insert(my_table, {a, b}).
true

Теперь сделайте исключение и проверьте, что таблица действительно сохранилась.

4> 1/0.
** exception error: bad argument in an arithmetic expression
     in operator  '/'/2
        called as 1 / 0
5> self().
<0.38.0>   % shell's reborn, with a different Pid

6> ets:insert(my_table, {c, d}).
true
7> ets:tab2list(my_table).
[{c,d},{a,b}]    % table did survive the shell restart

Чтобы удалить таблицу, просто отправьте что-нибудь вашему порожденному процессу:

8> pid(0,35,0) ! bye_bye.
bye_bye
9> ets:info(my_table).   
undefined
person Zed    schedule 27.12.2009