aprendiendo ( Erlang ).

lunes, 15 de agosto de 2011

Envío síncrono de mensajes

| 4 comentarios |

Hasta ahora, hemos realizados comunicaciones asíncronas. Es decir, hemos enviado un mensaje a otro proceso y no hemos esperado a la respuesta. Este tipo de comunicación es lo normal en la mayoría de los casos.
Veamos un esquema de mensajes asíncronos:
spawn(fun asincrono/0)
PidDestino ! {mensaje_asincrono, self()}
Creamos nuestro proceso y realizamos la comunicación con un proceso destino sin esperar. Nuestra función proceso recogía la respuesta con el receive cuando el servidor la procesara.
asincrono() ->
    receive
        mensaje ->
            % procesamos el mensaje
            asincrono();
        terminar ->
            void.
    end.
Ahora bien, supongamos que necesitamos de la respuesta para poder continuar. Un ejemplo típico sería una conexión a una base de datos, necesitamos saber si tenemos conexión o no. Es decir, deseamos una comunicación síncrona con el servidor.
Veamos un esquema de mensaje síncrono:
sincrono(PidDestino) ->
    PidDestino ! {mensaje_sincrono, self()},
    receive
        ok -> 
            ok;  % todo ha ido bien
        error ->
            exit(error) % responde con un error
    after 5000 -> 
            exit(sin_conexion)  % no ha respondido después de 5000 milisegundos 
    end,
    % continuamos con nuestro código
    ok.
Una vez mandado el mensaje, inmediatamente después escribimos nuestra sentencia receive que permitirá continuar si la comunicación, con el otro proceso, ha sido exitosa. En otro caso, detendrá la ejecución o provocará un error, o lo que determinemos oportuno.

Publicar un comentario en la entrada

4 comentarios:

  1. Cosas que ver ..... dijo...

    Bueno,lo que yo veo es que para la recepción asíncrona te quedas permanente consultando el buzón hasta recibir la orden de "terminar". Mientras que en la síncrona consultas el buzón solo un intervalo de tiempo.
    La cuestión interesante es: puedo tener las dos a la vez? y cómo ?. Y la clave es: puedo tener un "receive" dentro de otro receive?. Adelanto que sí. Una forma interesante es describir toda la recepción de mensajes síncronos dentro de un bucle de recepción de asíncronos. No ?. Hay alguna forma mejor ?.

  2. Verdi dijo...

    Parece que el ejemplo no es lo suficientemente clarificador.

    En un sistema de mensajería síncrono se envía el mensaje y esperamos pacientemente la respuesta, o por lo menos, en un tiempo prudencial para evitar bloqueos. De ahí, el uso de la clausula "after" en el segundo ejemplo.

    UnProceso!Mensaje
    Receive que espera la respuesta (El proceso se bloquea).

    En un sistema asíncrono el mensaje se envía y no esperamos la respuesta, o por lo menos, no de forma inmediata. Es por ello, que se crea un proceso independiente, que se encarga de recoger las respuestas. Yo sólo me encargo de enviar el mensaje y que responda cuando quiera.

    Creación de proceso con Receive que espera la respuesta.
    UnProceso!Mensaje
    Continua la ejecución. No se bloquea

    Un mensaje puede tener un tratamiento asíncrono o síncrono pero no ambos. En la misma aplicación o modulo puedo combinar ambas metodologías (gen_server lo hace). No importa como lo implementes (dos receive por ejemplo) si esperamos al mensaje antes de continuar con la ejecución tenemos un sistema síncrono y en caso contrario no.

    Todo es mejorable, siempre. Procuro esquematizar los ejemplos para que sean fáciles de ver, que de un vistazo sepas lo importante que hay en él. Pero no siempre lo consigo.

    Gracias. Siempre es interesante tener otros puntos de vistas. Gracias.

  3. Cosas que ver ..... dijo...

    Gracias a tí, estaba claro y bien explicado por tu parte. Mis comentarios son solo preguntas ú otra forma de entender las cosas. No son ni mucho menos una queja.
    Si no fuese por tu blog iría mas despacio en esto de aprender Erlang.
    Así que de nuevo agradecido.

  4. Verdi dijo...

    No me lo he tomado como una queja. No creo que tu comentario llevara ese motivo. Al contrario, considero que el post te llevo ha equivoco y te ha confundido. Y como bien dices, "otra forma de entender las cosas" es lo que nos hace avanzar y progresar. Es por ello, por lo que, intenté dejar claro los conceptos para que vieras el objetivo del post. Como una aclaración o un intercambio de opiniones, que siempre es bueno. Lo que en ningún caso he pretendido ofender.

    Siento la confusión.

 
Licencia Creative Commons
Aprendiendo Erlang por Verdi se encuentra bajo una Licencia Creative Commons Atribución-NoComercial-CompartirIgual 3.0 Unported.