Erlang / ETS: resettare tavolo ETS dopo avere ottenuto un “argomento”?

StackOverflow https://stackoverflow.com/questions/1964990

  •  21-09-2019
  •  | 
  •  

Domanda

Ho imparato come usare ETS, ma una cosa che mi ha infastidito è che, di tanto in tanto *, ets:match getta una bad argument ... E, da loro in poi, tutte le chiamate successive (anche chiamate che in precedenza ha lavorato) gettano anche una 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)

C'è un modo per "resettare" il sistema ets modo che io possa interrogare (vale a dire, dalla shell) di nuovo?

*:. Non sono stato in grado di riprodurre il problema ... ma succede abbastanza spesso, mentre io sto cercando di fare "altre cose"

È stato utile?

Soluzione

Anche se non sono sicuro al 100%, questa discussione sembra rispondere alla tua domanda. Sembra che si sta osservando questo comportamento nella shell. In tal caso, due fatti interagiscono in maniera confusa:

  1. Una tabella ETS viene cancellato non appena il processo di possedere muore.
  2. Il guscio erlang muore whenver riceve un'eccezione e viene riavviato silenziosamente.

Quindi, quando si ottiene la prima eccezione, il processo di shell corrente muore causando la tabella di ETS da eliminare, e quindi un nuovo processo shell è avviato per voi. Ora, quando si tenta un'altra ets:match, non riesce perché la tabella non esiste più.

Altri suggerimenti

Dale già detto che cosa accade. È possibile confermare che chiamando sé () nella shell di tanto in tanto.

Come soluzione rapida è possibile generare un altro processo per creare una tabella pubblica per voi. Poi quel tavolo non morirà con la shell.

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

Ora fare un'eccezione e verificare che la tabella in effetti è sopravvissuto.

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

Per eliminare la tabella, basta inviare qualcosa al vostro processo generato:

8> pid(0,35,0) ! bye_bye.
bye_bye
9> ets:info(my_table).   
undefined
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top