+NAME
+--------------------------------------------------------------------------------------------
+
+rmr_wh_call
+
+SYNOPSIS
+--------------------------------------------------------------------------------------------
+
+
+::
+
+ #include <rmr/rmr.h>
+ rmr_mbuf_t* rmr_wh_call( void* vctx, rmr_whid_t whid, rmr_mbuf_t* msg, int call_id, int max_wait )
+
+
+
+DESCRIPTION
+--------------------------------------------------------------------------------------------
+
+The rmr_wh_call function accepts a message buffer (msg) from
+the user application and attempts to send it using the
+wormhole ID provided (whid). If the send is successful, the
+call will block until either a response message is received,
+or the max_wait number of milliseconds has passed. In order
+for the response to be recognised as a response, the remote
+process **must** use rmr_rts_msg() to send their response.
+
+Like *rmr_wh_send_msg,* this function attempts to send the
+message directly to a process at the other end of a wormhole
+which was created with *rmr_wh-open().* When sending message
+via wormholes, the normal RMr routing based on message type
+is ignored, and the caller may leave the message type
+unspecified in the message buffer (unless it is needed by the
+receiving process). The call_id parameter is a number in the
+range of 2 through 255 and is used to identify the calling
+thread in order to properly match a response message when it
+arrives. Providing this value, and ensuring the proper
+uniqueness, is the responsibility of the user application and
+as such the ability to use the rmr_wh_call() function from
+potentially non-threaded concurrent applications (such as
+Go's goroutines) is possible.
+
+Retries
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The send operations in RMr will retry *soft* send failures
+until one of three conditions occurs:
+
+
+
+1.
+
+ The message is sent without error
+
+
+2.
+
+ The underlying transport reports a * hard * failure
+
+
+3.
+
+ The maximum number of retry loops has been attempted
+
+
+A retry loop consists of approximately 1000 send attemps **
+without** any intervening calls to * sleep() * or * usleep().
+* The number of retry loops defaults to 1, thus a maximum of
+1000 send attempts is performed before returning to the user
+application. This value can be set at any point after RMr
+initialisation using the * rmr_set_stimeout() * function
+allowing the user application to completely disable retires
+(set to 0), or to increase the number of retry loops.
+
+Transport Level Blocking
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The underlying transport mechanism used to send messages is
+configured in *non-blocking* mode. This means that if a
+message cannot be sent immediately the transport mechanism
+will **not** pause with the assumption that the inability to
+send will clear quickly (within a few milliseconds). This
+means that when the retry loop is completely disabled (set to
+0), that the failure to accept a message for sending by the
+underlying mechanisms (software or hardware) will be reported
+immediately to the user application.
+
+It should be noted that depending on the underlying transport
+mechanism being used, it is extremly possible that during
+normal operations that retry conditions are very likely to
+happen. These are completely out of RMr's control, and there
+is nothing that RMr can do to avoid or midigate these other
+than by allowing RMr to retry the send operation, and even
+then it is possible (e.g. during connection reattempts), that
+a single retry loop is not enough to guarentee a successful
+send.
+
+RETURN VALUE
+--------------------------------------------------------------------------------------------
+
+On success, new message buffer, with the payload containing
+the response from the remote endpoint is returned. The state
+in this buffer will reflect the overall send operation state
+and should be RMR_OK.
+
+If a message is returned with a state which is anything other
+than RMR_OK, the indication is that the send was not
+successful. The user application must check the state and
+determine the course of action. If the return value is NULL,
+no message, the indication is that there was no response
+received within the timeout (max_wait) period of time.
+
+ERRORS
+--------------------------------------------------------------------------------------------
+
+The following values may be passed back in the *state* field
+of the returned message buffer.
+
+
+
+RMR_ERR_WHID
+
+ The wormhole ID passed in was not associated with an open
+ wormhole, or was out of range for a valid ID.
+
+RMR_ERR_NOWHOPEN
+
+ No wormholes exist, further attempt to validate the ID are
+ skipped.
+
+RMR_ERR_BADARG
+
+ The message buffer pointer did not refer to a valid
+ message.
+
+RMR_ERR_NOHDR
+
+ The header in the message buffer was not valid or
+ corrupted.
+
+
+EXAMPLE
+--------------------------------------------------------------------------------------------
+
+The following is a simple example of how the a wormhole is
+created (rmr_wh_open) and then how rmr_wh_send_msg function
+is used to send messages. Some error checking is omitted for
+clarity.
+
+
+::
+
+ #include <rmr/rmr.h> .// system headers omitted for clarity
+ int main() {
+ rmr_whid_t whid = -1; // wormhole id for sending
+ void* mrc; //msg router context
+ int i;
+ rmr_mbuf_t* sbuf; // send buffer
+ int count = 0;
+ mrc = rmr_init( "43086", RMR_MAX_RCV_BYTES, RMRFL_NONE );
+ if( mrc == NULL ) {
+ fprintf( stderr, "[FAIL] unable to initialise RMr environment\\n" );
+ exit( 1 );
+ }
+ while( ! rmr_ready( mrc ) ) { e i// wait for routing table info
+ sleep( 1 );
+ }
+ sbuf = rmr_alloc_msg( mrc, 2048 );
+ while( 1 ) {
+ if( whid < 0 ) {
+ whid = rmr_wh_open( mrc, "localhost:6123" ); // open fails if endpoint refuses conn
+ w if( RMR_WH_CONNECTED( wh ) ) {
+ snprintf( sbuf->payload, 1024, "periodic update from sender: %d", count++ );
+ sbuf->len = strlen( sbuf->payload );
+ sbuf = rmr_wh_call( mrc, whid, sbuf, 1000 ); f s// expect a response in 1s or less
+ if( sbuf != NULL && sbuf->state = RMR_OK ) {
+ sprintf( stderr, "response: %s\\n", sbuf->payload ); x// assume they sent a string
+ } else {
+ sprintf( stderr, "response not received, or send error\\n" );
+ }
+ }
+ }
+ sleep( 5 );
+ }
+ }
+
+
+
+SEE ALSO
+--------------------------------------------------------------------------------------------
+
+rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3),
+rmr_payload_size(3), rmr_rcv_msg(3), rmr_rcv_specific(3),
+rmr_rts_msg(3), rmr_ready(3), rmr_fib(3), rmr_has_str(3),
+rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3),
+rmr_set_stimeout(3), rmr_wh_open(3), rmr_wh_close(3),
+rmr_wh_state(3)
+
+