Add installation guide with link to PackageCloud
[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  &item The message is sent without error 
85   
86  &item The underlying transport reports a *hard* failure 
87   
88  &item 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)