Add missing send timeout man page
[ric-plt/lib/rmr.git] / doc / src / man / rmr_call.3.xfm
1 .if false
2 ==================================================================================
3         Copyright (c) 2019 Nokia 
4         Copyright (c) 2018-2019 AT&T Intellectual Property.
5
6    Licensed under the Apache License, Version 2.0 (the "License");
7    you may not use this file except in compliance with the License.
8    You may obtain a copy of the License at
9
10        http://www.apache.org/licenses/LICENSE-2.0
11
12    Unless required by applicable law or agreed to in writing, software
13    distributed under the License is distributed on an "AS IS" BASIS,
14    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15    See the License for the specific language governing permissions and
16    limitations under the License.
17 ==================================================================================
18 .fi
19
20
21 .if false
22         Mnemonic        rmr_call_man.xfm
23         Abstract        The manual page for the rmr_call function.
24         Author          E. Scott Daniels
25         Date            28 January 2019
26 .fi
27
28 .** if formatting with tfm, the roff.im will cause roff output to be generated
29 .** if formatting with pfm, then pretty postscript will be generated
30 .gv e LIB lib
31 .if pfm
32         .im &{lib}/generic_ps.im
33 .ei
34         .gv e OUTPUT_RST use_rst
35         .if .ev &use_rst 1 = 
36                 .im &{lib}/rst.im
37         .ei
38                 .im &{lib}/roff.im
39         .fi
40 .fi
41
42 &line_len(6i)
43
44 &h1(RMR Library Functions)
45 &h2(NAME)
46         rmr_call
47
48 &h2(SYNOPSIS )
49 &indent
50 &ex_start
51 #include <rmr/rmr.h>
52
53 extern rmr_mbuf_t* rmr_call( void* vctx, rmr_mbuf_t* msg );
54 &ex_end
55 &uindent
56
57 &h2(DESCRIPTION)
58 The &cw(rmr_call) function sends the user application message to a remote
59 endpoint, and waits for a corresponding response message before returning
60 control to the user application.
61 The user application supplies a completed message buffer, as it would for
62 a &cw(rmr_send) call, but unlike with the send, the buffer returned will have
63 the response from the application that received the message.
64
65 &space
66 Messages which are received while waiting for the response are queued internally
67 by RMR, and are returned to the user application when &cw(rmr_rcv_msg) is 
68 invoked.
69 These messages are returned in th order received, one per call to &cw(rmr_rcv_msg.)
70
71 &h3(Call Timeout)
72 The &cw(rmr_call) function implements a timeout failsafe to prevent, in most cases, the
73 function from blocking forever. 
74 The timeout period is &bold(not) based on time (calls to clock are deemed too expensive
75 for a low latency system level library, but instead the period is based on the number of
76 received messages which are not the response. 
77 Using a non-time mechanism for &ital(timeout) prevents the async queue from filling
78 (which would lead to message drops) in an environment where there is heavy message traffic.
79
80 &space
81 When the threshold number of messages have been queued without receiving a response message,
82 control is returned to the user application and a NULL pointer is returned to indicate that
83 no message was received to process.
84 Currently the threshold is fixed at 20 messages, though in future versions of the library
85 this might be extended to be a parameter which the user application may set.
86
87 .** pull in common retry text
88 .im &{lib}/man/retry.im 
89
90 &h2(RETURN VALUE)
91 The &cw(rmr_call) function returns a pointer to a message buffer with the state set to reflect
92 the overall state of call processing (see Errors below). 
93 In some cases a NULL pointer will be returned; when this is the case only &ital(errno) 
94 will be available to describe the reason for failure.
95
96 &h2(ERRORS)
97 These values are reflected in the state field of the returned message. 
98
99 &half_space
100 &beg_dlist(.75i : ^&bold_font )
101 &di(RMR_OK) The call was successful and the message buffer references the response message.
102 &half_space
103 &di(RMR_ERR_CALLFAILED) The call failed and the value of &ital(errno,) as described below, 
104                         should be checked for the specific reason.
105 &end_dlist
106
107 &space
108 The global "variable" &ital(errno) will be set to one of the following values if the 
109 overall call processing was not successful. 
110 &half_space
111
112 &beg_dlist(.75i : ^&bold_font )
113 &di(ETIMEDOUT) Too many messages were queued before receiving the expected response
114 &half_space
115 &di(ENOBUFS)   The queued message ring is full, messages were dropped
116 &half_space
117 &di(EINVAL)     A parameter was not valid
118 &half_space
119 &di(EAGAIN)    The underlying message system wsa interrupted or the device was busy;
120                the message was &bold(not) sent, and user application should call 
121                                 this function with the message again.
122 &end_dlist
123
124 &h2(EXAMPLE)
125 The following code bit shows one way of using the &cw(rmr_call) function, and illustrates
126 how the transaction ID must be set.
127
128 &space
129 &ex_start
130     int retries_left = 5;               // max retries on dev not available
131     int retry_delay = 50000;            // retry delay (usec)
132     static rmr_mbuf_t*  mbuf = NULL;    // response msg
133     msg_t*  pm;                         // private message (payload)
134
135         // get a send buffer and reference the payload 
136     mbuf = rmr_alloc_msg( mr, RMR_MAX_RCV_BYTES );
137     pm = (msg_t*) mbuf->payload;
138
139         // generate an xaction ID and fill in payload with data and msg type
140     snprintf( mbuf->xaction, RMR_MAX_XID, "%s", gen_xaction() );
141     snprintf( pm->req, sizeof( pm->req ), "{ \"req\": \"num users\"}" );
142     mbuf->mtype = MT_REQ;
143     
144     msg = rmr_call( mr, msg );
145     if( ! msg ) {               // probably a timeout and no msg received
146         return NULL;            // let errno trickle up
147     } 
148
149     if( mbuf->state != RMR_OK ) {
150         while( retries_left-- > 0 &&             // loop as long as eagain
151                errno == EAGAIN && 
152                (msg = rmr_call( mr, msg )) != NULL && 
153                mbuf->state != RMR_OK ) {
154
155             usleep( retry_delay );
156         }
157     
158         if( mbuf == NULL || mbuf->state != RMR_OK ) {
159             rmr_free_msg( mbuf );        // safe if nil
160             return NULL;
161         }
162     }
163
164     // do something with mbuf
165 &ex_end
166
167
168 &h2(SEE ALSO )
169 .ju off
170 rmr_alloc_msg(3),
171 rmr_free_msg(3),
172 rmr_init(3),
173 rmr_payload_size(3),
174 rmr_send_msg(3),
175 rmr_rcv_msg(3),
176 rmr_rcv_specific(3),
177 rmr_rts_msg(3),
178 rmr_ready(3),
179 rmr_fib(3),
180 rmr_has_str(3),
181 rmr_set_stimeout(3),
182 rmr_tokenise(3),
183 rmr_mk_ring(3),
184 rmr_ring_free(3)
185 .ju on
186
187
188 .qu
189