Preparation for releasing 4.8.5
[ric-plt/lib/rmr.git] / docs / rmr_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_call
9 ============================================================================================
10
11
12
13
14 RMR LIBRARY FUNCTIONS
15 =====================
16
17
18
19 NAME
20 ----
21
22 rmr_call
23
24
25 SYNOPSIS
26 --------
27
28
29 ::
30
31   #include <rmr/rmr.h>
32
33   extern rmr_mbuf_t* rmr_call( void* vctx, rmr_mbuf_t* msg );
34
35
36
37 DESCRIPTION
38 -----------
39
40 The ``rmr_call`` function sends the user application message
41 to a remote endpoint, and waits for a corresponding response
42 message before returning control to the user application. The
43 user application supplies a completed message buffer, as it
44 would for a ``rmr_send`` call, but unlike with the send, the
45 buffer returned will have the response from the application
46 that received the message.
47
48 Messages which are received while waiting for the response
49 are queued internally by RMR, and are returned to the user
50 application when ``rmr_rcv_msg`` is invoked. These messages
51 are returned in the order received, one per call to
52 ``rmr_rcv_msg.``
53
54
55 Call Timeout
56 ------------
57
58 The ``rmr_call`` function implements a timeout failsafe to
59 prevent, in most cases, the function from blocking forever.
60 The timeout period is **not** based on time (calls to clock
61 are deemed too expensive for a low latency system level
62 library), but instead the period is based on the number of
63 received messages which are not the response. Using a
64 mechanism which is not time based for *timeout* prevents the
65 async queue from filling (which would lead to message drops)
66 in an environment where there is heavy message traffic.
67
68 When the threshold number of messages have been queued
69 without receiving a response message, control is returned to
70 the user application and a nil pointer is returned to
71 indicate that no message was received to process. Currently
72 the threshold is fixed at 20 messages, though in future
73 versions of the library this might be extended to be a
74 parameter which the user application may set.
75
76
77 Retries
78 -------
79
80 The send operations in RMR will retry *soft* send failures
81 until one of three conditions occurs:
82
83
84 * The message is sent without error
85
86 * The underlying transport reports a *hard* failure
87
88 * The maximum number of retry loops has been attempted
89
90
91 A retry loop consists of approximately 1000 send attempts
92 **without** any intervening calls to *sleep()* or *usleep().*
93 The number of retry loops defaults to 1, thus a maximum of
94 1000 send attempts is performed before returning to the user
95 application. This value can be set at any point after RMR
96 initialisation using the *rmr_set_stimeout()* function
97 allowing the user application to completely disable retires
98 (set to 0), or to increase the number of retry loops.
99
100
101 Transport Level Blocking
102 ------------------------
103
104 The underlying transport mechanism used to send messages is
105 configured in *non-blocking* mode. This means that if a
106 message cannot be sent immediately the transport mechanism
107 will **not** pause with the assumption that the inability to
108 send will clear quickly (within a few milliseconds). This
109 means that when the retry loop is completely disabled (set to
110 0), that the failure to accept a message for sending by the
111 underlying mechanisms (software or hardware) will be reported
112 immediately to the user application.
113
114 It should be noted that depending on the underlying transport
115 mechanism being used, it is extremely likely that retry
116 conditions will happen during normal operations. These are
117 completely out of RMR's control, and there is nothing that
118 RMR can do to avoid or mitigate these other than by allowing
119 RMR to retry the send operation, and even then it is possible
120 (e.g., during connection reattempts), that a single retry
121 loop is not enough to guarantee a successful send.
122
123
124 RETURN VALUE
125 ------------
126
127 The ``rmr_call`` function returns a pointer to a message
128 buffer with the state set to reflect the overall state of
129 call processing (see Errors below). In some cases a nil
130 pointer will be returned; when this is the case only *errno*
131 will be available to describe the reason for failure.
132
133
134 ERRORS
135 ------
136
137 These values are reflected in the state field of the returned
138 message.
139
140
141     .. list-table::
142       :widths: auto
143       :header-rows: 0
144       :class: borderless
145
146       * - **RMR_OK**
147         -
148           The call was successful and the message buffer references the
149           response message.
150
151       * - **RMR_ERR_CALLFAILED**
152         -
153           The call failed and the value of *errno,* as described below,
154           should be checked for the specific reason.
155
156
157
158 The global "variable" *errno* will be set to one of the
159 following values if the overall call processing was not
160 successful.
161
162
163     .. list-table::
164       :widths: auto
165       :header-rows: 0
166       :class: borderless
167
168       * - **ETIMEDOUT**
169         -
170           Too many messages were queued before receiving the expected
171           response
172
173       * - **ENOBUFS**
174         -
175           The queued message ring is full, messages were dropped
176
177       * - **EINVAL**
178         -
179           A parameter was not valid
180
181       * - **EAGAIN**
182         -
183           The underlying message system was interrupted or the device
184           was busy; the message was **not** sent, and the user
185           application should call this function with the message again.
186
187
188
189
190 EXAMPLE
191 -------
192
193 The following code snippet shows one way of using the
194 ``rmr_call`` function, and illustrates how the transaction ID
195 must be set.
196
197
198 ::
199
200       int retries_left = 5;               // max retries on dev not available
201       int retry_delay = 50000;            // retry delay (usec)
202       static rmr_mbuf_t*  mbuf = NULL;    // response msg
203       msg_t*  pm;                         // application struct for payload
204
205       // get a send buffer and reference the payload
206       mbuf = rmr_alloc_msg( mr, sizeof( pm->req ) );
207       pm = (msg_t*) mbuf->payload;
208
209       // generate an xaction ID and fill in payload with data and msg type
210       snprintf( mbuf->xaction, RMR_MAX_XID, "%s", gen_xaction() );
211       snprintf( pm->req, sizeof( pm->req ), "{ \\"req\\": \\"num users\\"}" );
212       mbuf->mtype = MT_REQ;
213
214       msg = rmr_call( mr, msg );
215       if( ! msg ) {               // probably a timeout and no msg received
216           return NULL;            // let errno trickle up
217       }
218
219       if( mbuf->state != RMR_OK ) {
220           while( retries_left-- > 0 &&             // loop as long as eagain
221                  errno == EAGAIN &&
222                  (msg = rmr_call( mr, msg )) != NULL &&
223                  mbuf->state != RMR_OK ) {
224
225               usleep( retry_delay );
226           }
227
228           if( mbuf == NULL || mbuf->state != RMR_OK ) {
229               rmr_free_msg( mbuf );        // safe if nil
230               return NULL;
231           }
232       }
233
234       // do something with mbuf
235
236
237
238 SEE ALSO
239 --------
240
241 rmr_alloc_msg(3), rmr_free_msg(3), rmr_init(3),
242 rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3),
243 rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3),
244 rmr_fib(3), rmr_has_str(3), rmr_set_stimeout(3),
245 rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3)