Release commit: move 4.0.2 to release repo
[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 .gv e LIB lib
29 .im &{lib}/man/setup.im
30
31 &line_len(6i)
32
33 &h1(RMR Library Functions)
34 &h2(NAME)
35     rmr_call
36
37 &h2(SYNOPSIS )
38 &indent
39 &ex_start
40 #include <rmr/rmr.h>
41
42 extern rmr_mbuf_t* rmr_call( void* vctx, rmr_mbuf_t* msg );
43 &ex_end
44 &uindent
45
46 &h2(DESCRIPTION)
47 The &cw(rmr_call) function sends the user application message to a remote
48 endpoint, and waits for a corresponding response message before returning
49 control to the user application.
50 The user application supplies a completed message buffer, as it would for
51 a &cw(rmr_send) call, but unlike with the send, the buffer returned will have
52 the response from the application that received the message.
53
54 &space
55 Messages which are received while waiting for the response are queued internally
56 by RMR, and are returned to the user application when &cw(rmr_rcv_msg) is
57 invoked.
58 These messages are returned in the order received, one per call to &cw(rmr_rcv_msg.)
59
60 &h3(Call Timeout)
61 The &cw(rmr_call) function implements a timeout failsafe to prevent, in most cases, the
62 function from blocking forever.
63 The timeout period is &bold(not) based on time (calls to clock are deemed too expensive
64 for a low latency system level library), but instead the period is based on the number of
65 received messages which are not the response.
66 Using a non-time mechanism for &ital(timeout) prevents the async queue from filling
67 (which would lead to message drops) in an environment where there is heavy message traffic.
68
69 &space
70 When the threshold number of messages have been queued without receiving a response message,
71 control is returned to the user application and a nil pointer is returned to indicate that
72 no message was received to process.
73 Currently the threshold is fixed at 20 messages, though in future versions of the library
74 this might be extended to be a parameter which the user application may set.
75
76 .** pull in common retry text
77 .im &{lib}/man/retry.im
78
79 &h2(RETURN VALUE)
80 The &cw(rmr_call) function returns a pointer to a message buffer with the state set to reflect
81 the overall state of call processing (see Errors below).
82 In some cases a nil pointer will be returned; when this is the case only &ital(errno)
83 will be available to describe the reason for failure.
84
85 &h2(ERRORS)
86 These values are reflected in the state field of the returned message.
87
88 &half_space
89 &beg_dlist(.75i : ^&bold_font )
90 &di(RMR_OK) The call was successful and the message buffer references the response message.
91 &half_space
92 &di(RMR_ERR_CALLFAILED) The call failed and the value of &ital(errno,) as described below,
93     should be checked for the specific reason.
94 &end_dlist
95
96 &space
97 The global "variable" &ital(errno) will be set to one of the following values if the
98 overall call processing was not successful.
99 &half_space
100
101 &beg_dlist(.75i : ^&bold_font )
102 &di(ETIMEDOUT) Too many messages were queued before receiving the expected response
103 &half_space
104 &di(ENOBUFS)   The queued message ring is full, messages were dropped
105 &half_space
106 &di(EINVAL)     A parameter was not valid
107 &half_space
108 &di(EAGAIN)    The underlying message system was interrupted or the device was busy;
109                the message was &bold(not) sent, and the user application should call
110                this function with the message again.
111 &end_dlist
112
113 &h2(EXAMPLE)
114 The following code snippet shows one way of using the &cw(rmr_call) function, and illustrates
115 how the transaction ID must be set.
116
117 &space
118 &ex_start
119     int retries_left = 5;               // max retries on dev not available
120     int retry_delay = 50000;            // retry delay (usec)
121     static rmr_mbuf_t*  mbuf = NULL;    // response msg
122     msg_t*  pm;                         // application struct for payload
123
124     // get a send buffer and reference the payload
125     mbuf = rmr_alloc_msg( mr, sizeof( pm->req ) );
126     pm = (msg_t*) mbuf->payload;
127
128     // generate an xaction ID and fill in payload with data and msg type
129     snprintf( mbuf->xaction, RMR_MAX_XID, "%s", gen_xaction() );
130     snprintf( pm->req, sizeof( pm->req ), "{ \"req\": \"num users\"}" );
131     mbuf->mtype = MT_REQ;
132
133     msg = rmr_call( mr, msg );
134     if( ! msg ) {               // probably a timeout and no msg received
135         return NULL;            // let errno trickle up
136     }
137
138     if( mbuf->state != RMR_OK ) {
139         while( retries_left-- > 0 &&             // loop as long as eagain
140                errno == EAGAIN &&
141                (msg = rmr_call( mr, msg )) != NULL &&
142                mbuf->state != RMR_OK ) {
143
144             usleep( retry_delay );
145         }
146
147         if( mbuf == NULL || mbuf->state != RMR_OK ) {
148             rmr_free_msg( mbuf );        // safe if nil
149             return NULL;
150         }
151     }
152
153     // do something with mbuf
154 &ex_end
155
156
157 &h2(SEE ALSO )
158 .ju off
159 rmr_alloc_msg(3),
160 rmr_free_msg(3),
161 rmr_init(3),
162 rmr_payload_size(3),
163 rmr_send_msg(3),
164 rmr_rcv_msg(3),
165 rmr_rcv_specific(3),
166 rmr_rts_msg(3),
167 rmr_ready(3),
168 rmr_fib(3),
169 rmr_has_str(3),
170 rmr_set_stimeout(3),
171 rmr_tokenise(3),
172 rmr_mk_ring(3),
173 rmr_ring_free(3)
174 .ju on
175