erlang otp gen-server

¿Qué tipo de tipos se pueden enviar en un mensaje erlang?



otp gen-server (3)

Principalmente quiero saber si puedo enviar una función en un mensaje en una configuración de erlang distribuida.

en la máquina 1

F1 = Fun()-> hey end, gen_server:call(on_other_machine,F1)

en la máquina 2

handler_call(Function,From,State) -> {reply,Function(),State)

¿tener sentido?


En cuanto a las funciones anónimas, parece que pueden enviarse y funcionar como se espera.

t1 @ localhost:

(t1@localhost)7> register(shell, self()). true (t1@localhost)10> A = me, receive Fun when is_function(Fun) -> Fun(A) end. hello me you ok

t2 @ localhost:

(t2@localhost)11> B = you. you (t2@localhost)12> Fn2 = fun (A) -> io:format("hello ~p ~p~n", [A, B]) end. #Fun<erl_eval.6.54118792> (t2@localhost)13> {shell, ''t1@localhost''} ! Fn2.

Estoy agregando lógica de cobertura a una aplicación basada en riak-core, y la fusión de los resultados recopilados puede ser complicada si las funciones anónimas no se pueden usar en los mensajes.

También echa un vistazo a riak_kv / src / riak_kv_coverage_filter.erl

riak_kv podría estar usándolo para filter resultado, supongo.


Puede enviar cualquier término válido de Erlang. Aunque debes tener cuidado al enviar diversiones. Cualquier diversión que haga referencia a una función dentro de un módulo necesita que ese módulo exista en el nodo objetivo para que funcione:

(first@host)9> rpc:call(second@host, erlang, apply, [fun io:format/1, ["Hey!~n"]]). Hey! ok (first@host)10> mymodule:func("Hey!~n"). 5 (first@host)11> rpc:call(second@host, erlang, apply, [fun mymodule:func/1, ["Hey!~n"]]). {badrpc,{''EXIT'',{undef,[{mymodule,func,["Hey!~n"]}, {rpc,''-handle_call_call/6-fun-0-'',5}]}}}

En este ejemplo, io existe en ambos nodos y funciona para enviar una función de io como diversión. Sin embargo, mymodule existe solo en el primer nodo y la diversión genera una excepción undef cuando se undef en el otro nodo.


Aquí hay un interesante artículo sobre "pasar diversión a otros nodos de Erlang". Para resumirlo brevemente:

[...] Como sabrá, la distribución de Erlang funciona enviando la codificación binaria de términos; y enviar una diversión también se hace esencialmente codificándolo usando erlang: term_to_binary / 1; pasar el binario resultante a otro nodo y luego decodificarlo de nuevo usando erlang: binary_to_term / 1. [...] Esto es bastante obvio para la mayoría de los tipos de datos; pero, ¿cómo funciona para los objetos de función?

Cuando codifica una diversión, lo codificado es solo una referencia a la función, no la implementación de la función. [...]

[...] la definición de la función no se transmite; exactamente la información suficiente para recrear la diversión en otro nodo si el módulo está allí.

[...] Si el módulo que contiene la diversión aún no se ha cargado, y el nodo de destino se está ejecutando en modo interactivo; luego se intenta cargar el módulo usando el mecanismo de carga de módulo regular (contenido en el módulo manejador de errores); y luego trata de ver si una diversión con la identificación dada está disponible en dicho módulo. Sin embargo, esto solo ocurre perezosamente cuando intentas aplicar la función.

[...] Si nunca intentas aplicar la función, entonces no pasa nada malo. La diversión se puede pasar a otro nodo (que tiene el módulo / diversión en cuestión) y luego todo el mundo está contento. Tal vez el nodo objetivo tiene un módulo cargado con dicho nombre, pero quizás en una versión diferente; que luego sería muy probable que tenga una suma de comprobación MD5 diferente, entonces obtendrá el error badfun si intenta aplicarlo.

Sugeriría que leyeras el artículo completo, porque es extremadamente interesante.