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

Я изучал, как использовать ets, но одна вещь, которая побеспокоила меня, состоит в том что, иногда*, ets:match броски a bad argument… И, от них на, все последующие вызовы (даже вызовы, которые ранее работали) также бросают a 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 система так, чтобы я мог запросить его (т.е. от оболочки) снова?

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

5
задан David Wolever 27 December 2009 в 02:45
поделиться

2 ответа

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

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

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

.
12
ответ дан 18 December 2019 в 13:15
поделиться

Дейл уже рассказал вам о том, что произойдет. Вы можете подтвердить это, время от времени вызывая 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
2
ответ дан 18 December 2019 в 13:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: