telecomunicaciones programacion imagenes erlang otp

programacion - erlang telecomunicaciones



¿Cuál es la mejor manera de hacer algo periódicamente en Erlang? (3)

La mejor manera es:

init([]) -> Timer = erlang:send_after(1, self(), check), {ok, Timer}. handle_info(check, OldTimer) -> erlang:cancel_timer(OldTimer), do_task(), Timer = erlang:send_after(1000, self(), check), {noreply, Timer}.

Tengo un proceso que necesita trabajar un poco cada quince segundos. Actualmente lo estoy haciendo así:

-behavior(gen_server). interval_milliseconds ()-> 15000. init()-> {ok, _State = FascinatingStateData, _TimeoutInterval = interval_milliseconds () }. %% This gets called automatically as a result of our handlers %% including the optional _TimeoutInterval value in the returned %% Result handle_info(timeout, StateData)-> {noreply, _State = do_some_work(StateData), _TimeoutInterval = interval_milliseconds () }.

Esto funciona, pero es extremadamente frágil: si quiero enseñarle un nuevo mensaje a mi servidor, cuando escribo una nueva función de controlador, debo recordar incluir el intervalo de tiempo de espera opcional en su valor de retorno. Es decir, diga si estoy manejando una llamada sincrónica, necesito hacer esto:

%% Someone wants to know our state; tell them handle_call(query_state_data, _From, StateData)-> {reply, StateData, _NewStateData = whatever (), interval_milliseconds ()};

en lugar de

%% Someone wants to know our state; tell them handle_call(query_state_data, _From, StateData)-> {reply, StateData, _NewStateData = whatever ()};

Como puedes imaginar, he cometido ese mismo error varias veces. Es desagradable, porque una vez que el código maneja ese mensaje query_state_data, los tiempos de espera ya no se generan, y todo el servidor se detiene. (Puedo "desfibrilarlo" manualmente obteniendo un shell en la máquina y enviando un mensaje de "timeout" a mano, pero ... eww.)

Ahora, podría tratar de recordar especificar siempre ese parámetro de Tiempo de espera opcional en mi valor de Resultado. Pero eso no se amplía: algún día lo olvidaré, y volveré a mirar este error. Entonces, ¿cuál es la mejor manera?

No creo que quiera escribir un bucle real que funcione para siempre y que pase la mayor parte del tiempo durmiendo; Eso parece contrario al espíritu de la OTP.


Usa el módulo timer :)


Utilice el timer : send_interval / 2. P.ej:

-behavior(gen_server). interval_milliseconds()-> 15000. init()-> timer:send_interval(interval_milliseconds(), interval), {ok, FascinatingStateData}. %% this clause will be called every 15 seconds handle_info(interval, StateData)-> State2 = do_some_work(StateData) {noreply, State2}.