/**
@page GRAS_tut_tour_rpc Lesson 10: Remote Procedure Calling (RPC)
\section GRAS_tut_tour_rpc_toc Table of Contents
- \ref GRAS_tut_tour_rpc_intro
- \ref GRAS_tut_tour_rpc_use
- \ref GRAS_tut_tour_rpc_use_declare
- \ref GRAS_tut_tour_rpc_use_i2a_cb
- \ref GRAS_tut_tour_rpc_use_a2i_cb
- \ref GRAS_tut_tour_rpc_use_rest
- \ref GRAS_tut_tour_rpc_recap
\section GRAS_tut_tour_rpc_intro Introduction
So far, we saw how to send messages from one host to another, but quite
often, we need a two-way message exchange: a "client" sends a request to a
"server", and the server returns a result after doing some sort of
computation. This design is often refered to as "Remote Procedure Call" or
RPC for short.
It is naturally possible to build RPC exchanges using only one-way messages,
as the ones we used in GRAS so far, but it's a bit awkward (specially when
the server wants to return a value to the client in a remote function call).
That is why GRAS provide a support for RPC, as we will now detail.
\section GRAS_tut_tour_rpc_use Putting rpc into action
We will build a simple RPC where clients use a remote server to convert
strings into numbers and vice-versa (ie, changing between "1234" and 1234).
To achieve its duty, the server will simply use the strtol function in one
direction. In the other direction, we will use bprintf(). This is a sprintf()
version allocating the needed room before doing the conversion. Its
portability is discutable, but SimGrid declares this function when it cannot
be found on the host architecture, so you can use it peacefully.
\subsection GRAS_tut_tour_rpc_use_declare Declaring the RPC
To declare a RPC message, we should simply use gras_msgtype_declare_rpc().
Compared to gras_msgtype_declare() that we use to declare one-way messages,
this function accepts one extra argument: the datatype of the answer
message. In our example, we accept one string in input, and a long in
output for the a2i conversion (a=char 2=to i=integer), and the contrary in
the other direction.
\dontinclude 10-rpc.c
\skip gras_msgtype_declare_rpc
\until long
\until string
\subsection GRAS_tut_tour_rpc_use_i2a_cb Declaring a simple RPC callback: the integer to string conversion
RPC callbacks are very close to "regular" ones. The only difference is that
they must call gras_msg_rpcreturn() at some point to return their result to
the caller. This function accepts 3 arguments: First the timeout to use when
sending back the result (we must use callbacks when doing network
communication to avoid deadlocks and such issues). The second argument is
the callback context that the callback got as first argument. It denotes how
to reach the caller and such. The last argument is a pointer to a variable
containing the result to pass to the caller.
Having the callee explicitly returning data to the caller allows to free
data that were allocated to do the job asked by the client, as in this
example.
\skip server_convert_i2a_cb
\until end_of_convert_callback
\subsection GRAS_tut_tour_rpc_use_a2i_cb RPC and exceptions: the string to integer conversion
When converting strings into integer, we must deal with the possibility that
the provided string is not a number. This is done very easily by raising an
exception in the RPC callback. This exception will get captured by the
middleware running the callback on the server side, sent accross the network
to the client side, and revived here. In short, exceptions raised on callee
side get passed automagically to the caller.
\skip server_convert_a2i_cb
\until end_of_convert_callback
\subsection GRAS_tut_tour_rpc_use_rest The rest of the story
The rest of the story is not really exciting. The server and the client are
very classical compared to what we saw so far. We simply have a specific
message "done" to stop the server when the client is done using it.
This may also be the first time you see the xbt_ex_display() function, which
allows to display an exception as if it were not catched without killing the
process.
\section GRAS_tut_tour_rpc_recap Recapping everything together
The program now reads:
\include 10-rpc.c
Which produces the expected output:
\include 10-rpc.output
Now, you know how to send messages, attach callbacks and do RPCs. The next
lesson will learn you the last missing part of the messaging library:
\ref GRAS_tut_tour_explicitwait
*/