Tengo un gen_server
en ejecución que debe limpiar su estado cada vez que se detiene normalmente o se bloquee de forma inesperada. La limpieza básicamente consiste en eliminar algunos archivos.Manejo de la limpieza del estado gen_server
En este momento, cuando el gen_server
falla o se detiene normalmente, la limpieza se realiza en terminate/2
.
¿Hay alguna razón por la cual terminate/2
no se llamaría si se bloquea el gen_server
?
debe haber ningún otro proceso de seguimiento de la gen_server
a la espera de hacer la limpieza si el gen_server
muere de forma inesperada?
Por lo tanto, el código es así:
terminate(normal, State) ->
% Invoked when the process stops
% Clean up the mess
terminate(Error, State) ->
% Invoked when the process crashes
% Clean up the mess
EDIT: He encontrado este correo electrónico en la lista de correo oficial que está hablando de lo mismo:
http://groups.google.com/group/erlang-programming/browse_thread/thread/9a1ba2d974775ce8
Como dice Adam a continuación, si queremos evitar atrapar el existe en el gen_server
, podríamos usar diferentes enfoques.
Pero si atrapamos el existe, terminate/2
parece ser un lugar seguro para hacer la limpieza como siempre se llamará. Por otra parte hay que manejar correctamente cuando se envía a 'EXIT'
terminate/2
y para handle_call/3
tratando de propagar los errores correctamente entre los trabajadores y supervisores.
Adam, ¿por qué publicar como cw? –
Corrígeme si me equivoco, pero se invocará AFAIK 'terminate/2' incluso cuando' gen_server' no atrape las salidas. Es necesario atraparlos para controlar cuándo se bloquea tu padre. – Ricardo
Realicé algunas pruebas y se invoca 'terminate/2' cuando falla el' gen_server', entonces ¿bajo qué circunstancias es posible que 'terminar/2' no se invoque? – Ricardo