blob: a8e02e5344d64b09cbd0d0ee03313c8dbb7cb96e [file] [log] [blame]
E. Scott Danielsece5bbe2020-07-21 13:39:18 -04001.. 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============================================================================================
8Man Page: rmr_call
9============================================================================================
10
11
E. Scott Danielsa3a121c2020-05-06 09:07:08 -040012
13
14RMR LIBRARY FUNCTIONS
15=====================
16
17
18
19NAME
20----
21
E. Scott Danielsece5bbe2020-07-21 13:39:18 -040022rmr_call
E. Scott Danielsa3a121c2020-05-06 09:07:08 -040023
24
25SYNOPSIS
26--------
27
E. Scott Danielsece5bbe2020-07-21 13:39:18 -040028
29::
30
31 #include <rmr/rmr.h>
32
33 extern rmr_mbuf_t* rmr_call( void* vctx, rmr_mbuf_t* msg );
34
E. Scott Danielsa3a121c2020-05-06 09:07:08 -040035
36
37DESCRIPTION
38-----------
39
E. Scott Danielsece5bbe2020-07-21 13:39:18 -040040The ``rmr_call`` function sends the user application message
41to a remote endpoint, and waits for a corresponding response
42message before returning control to the user application. The
43user application supplies a completed message buffer, as it
44would for a ``rmr_send`` call, but unlike with the send, the
45buffer returned will have the response from the application
46that received the message.
47
48Messages which are received while waiting for the response
49are queued internally by RMR, and are returned to the user
50application when ``rmr_rcv_msg`` is invoked. These messages
51are returned in the order received, one per call to
52``rmr_rcv_msg.``
E. Scott Danielsa3a121c2020-05-06 09:07:08 -040053
54
55Call Timeout
56------------
57
E. Scott Danielsece5bbe2020-07-21 13:39:18 -040058The ``rmr_call`` function implements a timeout failsafe to
59prevent, in most cases, the function from blocking forever.
60The timeout period is **not** based on time (calls to clock
61are deemed too expensive for a low latency system level
62library), but instead the period is based on the number of
63received messages which are not the response. Using a
64mechanism which is not time based for *timeout* prevents the
65async queue from filling (which would lead to message drops)
66in an environment where there is heavy message traffic.
67
68When the threshold number of messages have been queued
69without receiving a response message, control is returned to
70the user application and a nil pointer is returned to
71indicate that no message was received to process. Currently
72the threshold is fixed at 20 messages, though in future
73versions of the library this might be extended to be a
74parameter which the user application may set.
E. Scott Danielsa3a121c2020-05-06 09:07:08 -040075
76
77Retries
78-------
79
E. Scott Danielsece5bbe2020-07-21 13:39:18 -040080The send operations in RMR will retry *soft* send failures
81until 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
91A retry loop consists of approximately 1000 send attempts
92**without** any intervening calls to *sleep()* or *usleep().*
93The number of retry loops defaults to 1, thus a maximum of
941000 send attempts is performed before returning to the user
95application. This value can be set at any point after RMR
96initialisation using the *rmr_set_stimeout()* function
97allowing the user application to completely disable retires
98(set to 0), or to increase the number of retry loops.
E. Scott Danielsa3a121c2020-05-06 09:07:08 -040099
100
101Transport Level Blocking
102------------------------
103
E. Scott Danielsece5bbe2020-07-21 13:39:18 -0400104The underlying transport mechanism used to send messages is
105configured in *non-blocking* mode. This means that if a
106message cannot be sent immediately the transport mechanism
107will **not** pause with the assumption that the inability to
108send will clear quickly (within a few milliseconds). This
109means that when the retry loop is completely disabled (set to
1100), that the failure to accept a message for sending by the
111underlying mechanisms (software or hardware) will be reported
112immediately to the user application.
113
114It should be noted that depending on the underlying transport
115mechanism being used, it is extremely likely that retry
116conditions will happen during normal operations. These are
117completely out of RMR's control, and there is nothing that
118RMR can do to avoid or mitigate these other than by allowing
119RMR to retry the send operation, and even then it is possible
120(e.g., during connection reattempts), that a single retry
121loop is not enough to guarantee a successful send.
E. Scott Danielsa3a121c2020-05-06 09:07:08 -0400122
123
124RETURN VALUE
125------------
126
E. Scott Danielsece5bbe2020-07-21 13:39:18 -0400127The ``rmr_call`` function returns a pointer to a message
128buffer with the state set to reflect the overall state of
129call processing (see Errors below). In some cases a nil
130pointer will be returned; when this is the case only *errno*
131will be available to describe the reason for failure.
E. Scott Danielsa3a121c2020-05-06 09:07:08 -0400132
133
134ERRORS
135------
136
E. Scott Danielsece5bbe2020-07-21 13:39:18 -0400137These values are reflected in the state field of the returned
138message.
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
158The global "variable" *errno* will be set to one of the
159following values if the overall call processing was not
160successful.
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
E. Scott Danielsa3a121c2020-05-06 09:07:08 -0400188
189
190EXAMPLE
191-------
192
E. Scott Danielsece5bbe2020-07-21 13:39:18 -0400193The following code snippet shows one way of using the
194``rmr_call`` function, and illustrates how the transaction ID
195must 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
E. Scott Danielsa3a121c2020-05-06 09:07:08 -0400236
237
238SEE ALSO
239--------
240
E. Scott Danielsece5bbe2020-07-21 13:39:18 -0400241rmr_alloc_msg(3), rmr_free_msg(3), rmr_init(3),
242rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3),
243rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3),
244rmr_fib(3), rmr_has_str(3), rmr_set_stimeout(3),
245rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3)