Erlang / ETS: resettare tavolo ETS dopo avere ottenuto un “argomento”?
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"
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:
- Una tabella ETS viene cancellato non appena il processo di possedere muore.
- 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