X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=docs%2Frmr_mt_call.3.rst;h=985e9d7f2497cd502e1671c15cf421d688d5006f;hb=c752bd3585297dac74faf2a56512556bf140300e;hp=b090e04b51e32e272a22a66ecba0e239ab6c2e83;hpb=43b7981cee870dcf523b910a3af92ccc53556b2a;p=ric-plt%2Flib%2Frmr.git diff --git a/docs/rmr_mt_call.3.rst b/docs/rmr_mt_call.3.rst index b090e04..985e9d7 100644 --- a/docs/rmr_mt_call.3.rst +++ b/docs/rmr_mt_call.3.rst @@ -1,260 +1,270 @@ - - -.. This work is licensed under a Creative Commons Attribution 4.0 International License. -.. SPDX-License-Identifier: CC-BY-4.0 -.. CAUTION: this document is generated from source in doc/src/rtd. -.. To make changes edit the source and recompile the document. -.. Do NOT make changes directly to .rst or .md files. - - -============================================================================================ -Man Page: rmr_mt_call -============================================================================================ - -RMR Library Functions -============================================================================================ - - -NAME --------------------------------------------------------------------------------------------- - -rmr_mt_call - -SYNOPSIS --------------------------------------------------------------------------------------------- - - -:: - - #include - extern rmr_mbuf_t* rmr_mt_call( void* vctx, rmr_mbuf_t* msg, int id, int timeout ); - - - -DESCRIPTION --------------------------------------------------------------------------------------------- - -The rmr_mt_call function sends the user application message -to a remote endpoint, and waits for a corresponding response -message before returning control to the user application. The -user application supplies a completed message buffer, as it -would for a rmr_send_msg call, but unlike with a send, the -buffer returned will have the response from the application -that received the message. The thread invoking the -*rmr_mt_call()* will block until a message arrives or until -*timeout* milliseconds has passed; which ever comes first. -Using a timeout value of zero (0) will cause the thread to -block without a timeout. - -The *id* supplied as the third parameter is an integer in the -range of 2 through 255 inclusive. This is a caller defined -"thread number" and is used to match the response message -with the correct user application thread. If the ID value is -not in the proper range, the attempt to make the call will -fail. - -Messages which are received while waiting for the response -are queued on a *normal* receive queue and will be delivered -to the user application with the next invocation of -*rmr_mt_rcv()* or *rmr_rvv_msg().* by RMR, and are returned -to the user application when rmr_rcv_msg is invoked. These -messages are returned in the order received, one per call to -rmr_rcv_msg. - -The Transaction ID -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The user application is responsible for setting the value of -the transaction ID field before invoking *rmr_mt_call.* The -transaction ID is a RMR_MAX_XID byte field that is used to -match the response message when it arrives. RMR will compare -**all** of the bytes in the field, so the caller must ensure -that they are set correctly to avoid missing the response -message. The application which returns the response message -is also expected to ensure that the return buffer has the -matching transaction ID. This can be done transparently if -the application uses the *rmr_rts_msg()* function and does -not adjust the transaction ID. - -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 attempts -**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 extremely likely that retry -conditions will happen during normal operations. These are -completely out of RMR's control, and there is nothing that -RMR can do to avoid or mitigate 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 guarantee a successful send. - -RETURN VALUE --------------------------------------------------------------------------------------------- - -The rmr_mt_call function returns a pointer to a message -buffer with the state set to reflect the overall state of -call processing. If the state is RMR_OK then the buffer -contains the response message; otherwise the state indicates -the error encountered while attempting to send the message. - -If no response message is received when the timeout period -has expired, a nil pointer will be returned (NULL). - -ERRORS --------------------------------------------------------------------------------------------- - -These values are reflected in the state field of the returned -message. - - - -RMR_OK - - The call was successful and the message buffer references - the response message. - - -RMR_ERR_BADARG - - An argument passed to the function was invalid. - - -RMR_ERR_CALLFAILED - - The call failed and the value of *errno,* as described - below, should be checked for the specific reason. - - -RMR_ERR_NOENDPT - - An endpoint associated with the message type could not be - found in the route table. - - -RMR_ERR_RETRY - - The underlying transport mechanism was unable to accept - the message for sending. The user application can retry - the call operation if appropriate to do so. - - -The global "variable" *errno* will be set to one of the -following values if the overall call processing was not -successful. - - - -ETIMEDOUT - - Too many messages were queued before receiving the - expected response - - -ENOBUFS - - The queued message ring is full, messages were dropped - - -EINVAL - - A parameter was not valid - - -EAGAIN - - The underlying message system wsa interrupted or the - device was busy; the message was **not** sent, and user - application should call this function with the message - again. - - -EXAMPLE --------------------------------------------------------------------------------------------- - -The following code bit shows one way of using the rmr_mt_call -function, and illustrates how the transaction ID must be set. - - -:: - - int retries_left = 5; // max retries on dev not available - static rmr_mbuf_t* mbuf = NULL; // response msg - msg_t* pm; // appl message struct (payload) - // get a send buffer and reference the payload - mbuf = rmr_alloc_msg( mr, sizeof( pm->req ) ); - pm = (msg_t*) mbuf->payload; - // generate an xaction ID and fill in payload with data and msg type - rmr_bytes2xact( mbuf, xid, RMR_MAX_XID ); - snprintf( pm->req, sizeof( pm->req ), "{ \\"req\\": \\"num users\\"}" ); - mbuf->mtype = MT_USR_RESP; - msg = rmr_mt_call( mr, msg, my_id, 100 ); // wait up to 100ms - if( ! msg ) { // probably a timeout and no msg received - return NULL; // let errno trickle up - } - if( mbuf->state != RMR_OK ) { - while( retries_left-- > 0 && // loop as long as eagain - mbuf->state == RMR_ERR_RETRY && - (msg = rmr_mt_call( mr, msg )) != NULL && - mbuf->state != RMR_OK ) { - usleep( retry_delay ); - } - if( mbuf == NULL || mbuf->state != RMR_OK ) { - rmr_free_msg( mbuf ); // safe if nil - return NULL; - } - } - // do something with mbuf - - - -SEE ALSO --------------------------------------------------------------------------------------------- - -rmr_alloc_msg(3), rmr_free_msg(3), rmr_init(3), -rmr_mt_rcv(3), rmr_payload_size(3), rmr_send_msg(3), -rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3), -rmr_ready(3), rmr_fib(3), rmr_has_str(3), -rmr_set_stimeout(3), rmr_tokenise(3), rmr_mk_ring(3), -rmr_ring_free(3) +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. SPDX-License-Identifier: CC-BY-4.0 +.. CAUTION: this document is generated from source in doc/src/rtd. +.. To make changes edit the source and recompile the document. +.. Do NOT make changes directly to .rst or .md files. + +============================================================================================ +Man Page: rmr_mt_call +============================================================================================ + + + + +RMR LIBRARY FUNCTIONS +===================== + + + +NAME +---- + +rmr_mt_call + + +SYNOPSIS +-------- + + +:: + + #include + + extern rmr_mbuf_t* rmr_mt_call( void* vctx, rmr_mbuf_t* msg, int id, int timeout ); + + + +DESCRIPTION +----------- + +The ``rmr_mt_call`` function sends the user application +message to a remote endpoint, and waits for a corresponding +response message before returning control to the user +application. The user application supplies a completed +message buffer, as it would for a ``rmr_send_msg`` call, but +unlike with a send, the buffer returned will have the +response from the application that received the message. The +thread invoking the *rmr_mt_call()* will block until a +message arrives or until *timeout* milliseconds has passed; +which ever comes first. Using a timeout value of zero (0) +will cause the thread to block without a timeout. + +The *id* supplied as the third parameter is an integer in the +range of 2 through 255 inclusive. This is a caller defined +"thread number" and is used to match the response message +with the correct user application thread. If the ID value is +not in the proper range, the attempt to make the call will +fail. + +Messages which are received while waiting for the response +are queued on a *normal* receive queue and will be delivered +to the user application with the next invocation of +*rmr_mt_rcv()* or *rmr_rvv_msg().* by RMR, and are returned +to the user application when ``rmr_rcv_msg`` is invoked. +These messages are returned in the order received, one per +call to ``rmr_rcv_msg.`` + + +The Transaction ID +------------------ + +The user application is responsible for setting the value of +the transaction ID field before invoking *rmr_mt_call.* The +transaction ID is a ``RMR_MAX_XID`` byte field that is used +to match the response message when it arrives. RMR will +compare **all** of the bytes in the field, so the caller must +ensure that they are set correctly to avoid missing the +response message. The application which returns the response +message is also expected to ensure that the return buffer has +the matching transaction ID. This can be done transparently +if the application uses the *rmr_rts_msg()* function and does +not adjust the transaction ID. + + +Retries +------- + +The send operations in RMR will retry *soft* send failures +until one of three conditions occurs: + + +* The message is sent without error + +* The underlying transport reports a *hard* failure + +* The maximum number of retry loops has been attempted + + +A retry loop consists of approximately 1000 send attempts +**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 extremely likely that retry +conditions will happen during normal operations. These are +completely out of RMR's control, and there is nothing that +RMR can do to avoid or mitigate 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 guarantee a successful send. + + +RETURN VALUE +------------ + +The ``rmr_mt_call`` function returns a pointer to a message +buffer with the state set to reflect the overall state of +call processing. If the state is ``RMR_OK`` then the buffer +contains the response message; otherwise the state indicates +the error encountered while attempting to send the message. + +If no response message is received when the timeout period +has expired, a nil pointer will be returned (NULL). + + +ERRORS +------ + +These values are reflected in the state field of the returned +message. + + + .. list-table:: + :widths: auto + :header-rows: 0 + :class: borderless + + * - **RMR_OK** + - + The call was successful and the message buffer references the + response message. + + * - **RMR_ERR_BADARG** + - + An argument passed to the function was invalid. + + * - **RMR_ERR_CALLFAILED** + - + The call failed and the value of *errno,* as described below, + should be checked for the specific reason. + + * - **RMR_ERR_NOENDPT** + - + An endpoint associated with the message type could not be + found in the route table. + + * - **RMR_ERR_RETRY** + - + The underlying transport mechanism was unable to accept the + message for sending. The user application can retry the call + operation if appropriate to do so. + + + +The global "variable" *errno* will be set to one of the +following values if the overall call processing was not +successful. + + + .. list-table:: + :widths: auto + :header-rows: 0 + :class: borderless + + * - **ETIMEDOUT** + - + Too many messages were queued before receiving the expected + response + + * - **ENOBUFS** + - + The queued message ring is full, messages were dropped + + * - **EINVAL** + - + A parameter was not valid + + * - **EAGAIN** + - + The underlying message system wsa interrupted or the device + was busy; the message was **not** sent, and user application + should call this function with the message again. + + + + +EXAMPLE +------- + +The following code bit shows one way of using the +``rmr_mt_call`` function, and illustrates how the transaction +ID must be set. + + +:: + + int retries_left = 5; // max retries on dev not available + static rmr_mbuf_t* mbuf = NULL; // response msg + msg_t* pm; // appl message struct (payload) + + // get a send buffer and reference the payload + mbuf = rmr_alloc_msg( mr, sizeof( pm->req ) ); + pm = (msg_t*) mbuf->payload; + + // generate an xaction ID and fill in payload with data and msg type + rmr_bytes2xact( mbuf, xid, RMR_MAX_XID ); + snprintf( pm->req, sizeof( pm->req ), "{ \\"req\\": \\"num users\\"}" ); + mbuf->mtype = MT_USR_RESP; + + msg = rmr_mt_call( mr, msg, my_id, 100 ); // wait up to 100ms + if( ! msg ) { // probably a timeout and no msg received + return NULL; // let errno trickle up + } + + if( mbuf->state != RMR_OK ) { + while( retries_left-- > 0 && // loop as long as eagain + mbuf->state == RMR_ERR_RETRY && + (msg = rmr_mt_call( mr, msg )) != NULL && + mbuf->state != RMR_OK ) { + + usleep( retry_delay ); + } + + if( mbuf == NULL || mbuf->state != RMR_OK ) { + rmr_free_msg( mbuf ); // safe if nil + return NULL; + } + } + + // do something with mbuf + + + +SEE ALSO +-------- + +rmr_alloc_msg(3), rmr_free_msg(3), rmr_init(3), +rmr_mt_rcv(3), rmr_payload_size(3), rmr_send_msg(3), +rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3), +rmr_ready(3), rmr_fib(3), rmr_has_str(3), +rmr_set_stimeout(3), rmr_tokenise(3), rmr_mk_ring(3), +rmr_ring_free(3)