E. Scott Daniels | ece5bbe | 2020-07-21 13:39:18 -0400 | [diff] [blame] | 1 | .. This work is licensed under a Creative Commons Attribution 4.0 International License. |
| 2 | .. SPDX-License-Identifier: CC-BY-4.0 |
| 3 | .. CAUTION: this document is generated from source in doc/src/rtd. |
| 4 | .. To make changes edit the source and recompile the document. |
| 5 | .. Do NOT make changes directly to .rst or .md files. |
| 6 | |
| 7 | ============================================================================================ |
| 8 | Man Page: rmr_wh_call |
| 9 | ============================================================================================ |
| 10 | |
| 11 | |
E. Scott Daniels | a3a121c | 2020-05-06 09:07:08 -0400 | [diff] [blame] | 12 | |
| 13 | |
| 14 | RMR LIBRARY FUNCTIONS |
| 15 | ===================== |
| 16 | |
| 17 | |
| 18 | |
| 19 | NAME |
| 20 | ---- |
| 21 | |
E. Scott Daniels | ece5bbe | 2020-07-21 13:39:18 -0400 | [diff] [blame] | 22 | rmr_wh_call |
E. Scott Daniels | a3a121c | 2020-05-06 09:07:08 -0400 | [diff] [blame] | 23 | |
| 24 | |
| 25 | SYNOPSIS |
| 26 | -------- |
| 27 | |
E. Scott Daniels | ece5bbe | 2020-07-21 13:39:18 -0400 | [diff] [blame] | 28 | |
| 29 | :: |
| 30 | |
| 31 | #include <rmr/rmr.h> |
| 32 | |
| 33 | rmr_mbuf_t* rmr_wh_call( void* vctx, rmr_whid_t whid, rmr_mbuf_t* msg, int call_id, int max_wait ) |
| 34 | |
| 35 | |
E. Scott Daniels | a3a121c | 2020-05-06 09:07:08 -0400 | [diff] [blame] | 36 | |
| 37 | |
| 38 | DESCRIPTION |
| 39 | ----------- |
| 40 | |
E. Scott Daniels | ece5bbe | 2020-07-21 13:39:18 -0400 | [diff] [blame] | 41 | The ``rmr_wh_call`` function accepts a message buffer (msg) |
| 42 | from the user application and attempts to send it using the |
| 43 | wormhole ID provided (whid). If the send is successful, the |
| 44 | call will block until either a response message is received, |
| 45 | or the ``max_wait`` number of milliseconds has passed. In |
| 46 | order for the response to be recognised as a response, the |
| 47 | remote process **must** use ``rmr_rts_msg()`` to send their |
| 48 | response. |
| 49 | |
| 50 | Like *rmr_wh_send_msg,* this function attempts to send the |
| 51 | message directly to a process at the other end of a wormhole |
| 52 | which was created with *rmr_wh_open().* When sending message |
| 53 | via wormholes, the normal RMR routing based on message type |
| 54 | is ignored, and the caller may leave the message type |
| 55 | unspecified in the message buffer (unless it is needed by the |
| 56 | receiving process). The ``call_id`` parameter is a number in |
| 57 | the range of 2 through 255 and is used to identify the |
| 58 | calling thread in order to properly match a response message |
| 59 | when it arrives. Providing this value, and ensuring the |
| 60 | proper uniqueness, is the responsibility of the user |
| 61 | application and as such the ability to use the |
| 62 | ``rmr_wh_call()`` function from potentially non-threaded |
| 63 | concurrent applications (such as Go's goroutines) is |
| 64 | possible. |
E. Scott Daniels | a3a121c | 2020-05-06 09:07:08 -0400 | [diff] [blame] | 65 | |
| 66 | |
| 67 | Retries |
| 68 | ------- |
| 69 | |
E. Scott Daniels | ece5bbe | 2020-07-21 13:39:18 -0400 | [diff] [blame] | 70 | The send operations in RMR will retry *soft* send failures |
| 71 | until one of three conditions occurs: |
| 72 | |
| 73 | |
| 74 | * The message is sent without error |
| 75 | |
| 76 | * The underlying transport reports a *hard* failure |
| 77 | |
| 78 | * The maximum number of retry loops has been attempted |
| 79 | |
| 80 | |
| 81 | A retry loop consists of approximately 1000 send attempts |
| 82 | **without** any intervening calls to *sleep()* or *usleep().* |
| 83 | The number of retry loops defaults to 1, thus a maximum of |
| 84 | 1000 send attempts is performed before returning to the user |
| 85 | application. This value can be set at any point after RMR |
| 86 | initialisation using the *rmr_set_stimeout()* function |
| 87 | allowing the user application to completely disable retires |
| 88 | (set to 0), or to increase the number of retry loops. |
E. Scott Daniels | a3a121c | 2020-05-06 09:07:08 -0400 | [diff] [blame] | 89 | |
| 90 | |
| 91 | Transport Level Blocking |
| 92 | ------------------------ |
| 93 | |
E. Scott Daniels | ece5bbe | 2020-07-21 13:39:18 -0400 | [diff] [blame] | 94 | The underlying transport mechanism used to send messages is |
| 95 | configured in *non-blocking* mode. This means that if a |
| 96 | message cannot be sent immediately the transport mechanism |
| 97 | will **not** pause with the assumption that the inability to |
| 98 | send will clear quickly (within a few milliseconds). This |
| 99 | means that when the retry loop is completely disabled (set to |
| 100 | 0), that the failure to accept a message for sending by the |
| 101 | underlying mechanisms (software or hardware) will be reported |
| 102 | immediately to the user application. |
| 103 | |
| 104 | It should be noted that depending on the underlying transport |
| 105 | mechanism being used, it is extremely likely that retry |
| 106 | conditions will happen during normal operations. These are |
| 107 | completely out of RMR's control, and there is nothing that |
| 108 | RMR can do to avoid or mitigate these other than by allowing |
| 109 | RMR to retry the send operation, and even then it is possible |
| 110 | (e.g., during connection reattempts), that a single retry |
| 111 | loop is not enough to guarantee a successful send. |
E. Scott Daniels | a3a121c | 2020-05-06 09:07:08 -0400 | [diff] [blame] | 112 | |
| 113 | |
| 114 | RETURN VALUE |
| 115 | ------------ |
| 116 | |
E. Scott Daniels | ece5bbe | 2020-07-21 13:39:18 -0400 | [diff] [blame] | 117 | On success, new message buffer, with the payload containing |
| 118 | the response from the remote endpoint is returned. The state |
| 119 | in this buffer will reflect the overall send operation state |
| 120 | and should be ``RMR_OK.`` |
| 121 | |
| 122 | If a message is returned with a state which is anything other |
| 123 | than ``RMR_OK,`` the indication is that the send was not |
| 124 | successful. The user application must check the state and |
| 125 | determine the course of action. If the return value is NULL, |
| 126 | no message, the indication is that there was no response |
| 127 | received within the timeout (max_wait) period of time. |
E. Scott Daniels | a3a121c | 2020-05-06 09:07:08 -0400 | [diff] [blame] | 128 | |
| 129 | |
| 130 | ERRORS |
| 131 | ------ |
| 132 | |
E. Scott Daniels | ece5bbe | 2020-07-21 13:39:18 -0400 | [diff] [blame] | 133 | The following values may be passed back in the *state* field |
| 134 | of the returned message buffer. |
| 135 | |
| 136 | |
| 137 | .. list-table:: |
| 138 | :widths: auto |
| 139 | :header-rows: 0 |
| 140 | :class: borderless |
| 141 | |
| 142 | * - **RMR_ERR_WHID** |
| 143 | - |
| 144 | The wormhole ID passed in was not associated with an open |
| 145 | wormhole, or was out of range for a valid ID. |
| 146 | |
| 147 | * - **RMR_ERR_NOWHOPEN** |
| 148 | - |
| 149 | No wormholes exist, further attempt to validate the ID are |
| 150 | skipped. |
| 151 | |
| 152 | * - **RMR_ERR_BADARG** |
| 153 | - |
| 154 | The message buffer pointer did not refer to a valid message. |
| 155 | |
| 156 | * - **RMR_ERR_NOHDR** |
| 157 | - |
| 158 | The header in the message buffer was not valid or corrupted. |
| 159 | |
| 160 | |
E. Scott Daniels | a3a121c | 2020-05-06 09:07:08 -0400 | [diff] [blame] | 161 | |
| 162 | |
| 163 | EXAMPLE |
| 164 | ------- |
| 165 | |
E. Scott Daniels | ece5bbe | 2020-07-21 13:39:18 -0400 | [diff] [blame] | 166 | The following is a simple example of how the a wormhole is |
| 167 | created (rmr_wh_open) and then how ``rmr_wh_send_msg`` |
| 168 | function is used to send messages. Some error checking is |
| 169 | omitted for clarity. |
| 170 | |
| 171 | |
| 172 | :: |
| 173 | |
| 174 | |
| 175 | #include <rmr/rmr.h> // system headers omitted for clarity |
| 176 | |
| 177 | int main() { |
| 178 | rmr_whid_t whid = -1; // wormhole id for sending |
| 179 | void* mrc; //msg router context |
| 180 | int i; |
| 181 | rmr_mbuf_t* sbuf; // send buffer |
| 182 | int count = 0; |
| 183 | int norm_msg_size = 1500; // most messages fit in this size |
| 184 | |
| 185 | mrc = rmr_init( "43086", norm_msg_size, RMRFL_NONE ); |
| 186 | if( mrc == NULL ) { |
| 187 | fprintf( stderr, "[FAIL] unable to initialise RMR environment\\n" ); |
| 188 | exit( 1 ); |
| 189 | } |
| 190 | |
| 191 | while( ! rmr_ready( mrc ) ) { // wait for routing table info |
| 192 | sleep( 1 ); |
| 193 | } |
| 194 | |
| 195 | sbuf = rmr_alloc_msg( mrc, 2048 ); |
| 196 | |
| 197 | while( 1 ) { |
| 198 | if( whid < 0 ) { |
| 199 | whid = rmr_wh_open( mrc, "localhost:6123" ); // open fails if endpoint refuses conn |
| 200 | if( RMR_WH_CONNECTED( wh ) ) { |
| 201 | snprintf( sbuf->payload, 1024, "periodic update from sender: %d", count++ ); |
| 202 | sbuf->len = strlen( sbuf->payload ); |
| 203 | sbuf = rmr_wh_call( mrc, whid, sbuf, 1000 ); // expect a response in 1s or less |
| 204 | if( sbuf != NULL && sbuf->state = RMR_OK ) { |
| 205 | sprintf( stderr, "response: %s\\n", sbuf->payload ); // assume they sent a string |
| 206 | } else { |
| 207 | sprintf( stderr, "response not received, or send error\\n" ); |
| 208 | } |
| 209 | } |
| 210 | } |
| 211 | |
| 212 | sleep( 5 ); |
| 213 | } |
| 214 | } |
| 215 | |
E. Scott Daniels | a3a121c | 2020-05-06 09:07:08 -0400 | [diff] [blame] | 216 | |
| 217 | |
| 218 | SEE ALSO |
| 219 | -------- |
| 220 | |
E. Scott Daniels | ece5bbe | 2020-07-21 13:39:18 -0400 | [diff] [blame] | 221 | rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3), |
| 222 | rmr_payload_size(3), rmr_rcv_msg(3), rmr_rcv_specific(3), |
| 223 | rmr_rts_msg(3), rmr_ready(3), rmr_fib(3), rmr_has_str(3), |
| 224 | rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3), |
| 225 | rmr_set_stimeout(3), rmr_wh_open(3), rmr_wh_close(3), |
| 226 | rmr_wh_state(3) |