CI: Add silent cmake SonarCloud scan
[ric-plt/lib/rmr.git] / docs / rmr_wh_call.3.rst
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
12
13
14 RMR LIBRARY FUNCTIONS
15 =====================
16
17
18
19 NAME
20 ----
21
22 rmr_wh_call
23
24
25 SYNOPSIS
26 --------
27
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
36
37
38 DESCRIPTION
39 -----------
40
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.
65
66
67 Retries
68 -------
69
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.
89
90
91 Transport Level Blocking
92 ------------------------
93
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.
112
113
114 RETURN VALUE
115 ------------
116
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.
128
129
130 ERRORS
131 ------
132
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
161
162
163 EXAMPLE
164 -------
165
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
216
217
218 SEE ALSO
219 --------
220
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)