Add installation guide with link to PackageCloud
[ric-plt/lib/rmr.git] / docs / rmr_wh_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_wh_call 
9 ============================================================================================ 
10  
11  
12
13
14 RMR LIBRARY FUNCTIONS
15 =====================
16
17
18
19 NAME
20 ----
21
22 rmr_wh_call 
23
24
25 SYNOPSIS
26 --------
27
28  
29 :: 
30  
31  #include <rmr/rmr.h>
32   
33  rmr_mbuf_t* rmr_wh_call( void* vctx, rmr_whid_t whid, rmr_mbuf_t* msg, int call_id, int max_wait )
34   
35  
36
37
38 DESCRIPTION
39 -----------
40
41 The ``rmr_wh_call`` function accepts a message buffer (msg) 
42 from the user application and attempts to send it using the 
43 wormhole ID provided (whid). If the send is successful, the 
44 call will block until either a response message is received, 
45 or the ``max_wait`` number of milliseconds has passed. In 
46 order for the response to be recognised as a response, the 
47 remote process **must** use ``rmr_rts_msg()`` to send their 
48 response. 
49  
50 Like *rmr_wh_send_msg,* this function attempts to send the 
51 message directly to a process at the other end of a wormhole 
52 which was created with *rmr_wh_open().* When sending message 
53 via wormholes, the normal RMR routing based on message type 
54 is ignored, and the caller may leave the message type 
55 unspecified in the message buffer (unless it is needed by the 
56 receiving process). The ``call_id`` parameter is a number in 
57 the range of 2 through 255 and is used to identify the 
58 calling thread in order to properly match a response message 
59 when it arrives. Providing this value, and ensuring the 
60 proper uniqueness, is the responsibility of the user 
61 application and as such the ability to use the 
62 ``rmr_wh_call()`` function from potentially non-threaded 
63 concurrent applications (such as Go's goroutines) is 
64 possible. 
65
66
67 Retries
68 -------
69
70 The send operations in RMR will retry *soft* send failures 
71 until one of three conditions occurs: 
72  
73  
74  &item The message is sent without error 
75   
76  &item The underlying transport reports a *hard* failure 
77   
78  &item The maximum number of retry loops has been attempted 
79  
80  
81 A retry loop consists of approximately 1000 send attempts 
82 **without** any intervening calls to *sleep()* or *usleep().* 
83 The number of retry loops defaults to 1, thus a maximum of 
84 1000 send attempts is performed before returning to the user 
85 application. This value can be set at any point after RMR 
86 initialisation using the *rmr_set_stimeout()* function 
87 allowing the user application to completely disable retires 
88 (set to 0), or to increase the number of retry loops. 
89
90
91 Transport Level Blocking
92 ------------------------
93
94 The underlying transport mechanism used to send messages is 
95 configured in *non-blocking* mode. This means that if a 
96 message cannot be sent immediately the transport mechanism 
97 will **not** pause with the assumption that the inability to 
98 send will clear quickly (within a few milliseconds). This 
99 means that when the retry loop is completely disabled (set to 
100 0), that the failure to accept a message for sending by the 
101 underlying mechanisms (software or hardware) will be reported 
102 immediately to the user application. 
103  
104 It should be noted that depending on the underlying transport 
105 mechanism being used, it is extremely likely that retry 
106 conditions will happen during normal operations. These are 
107 completely out of RMR's control, and there is nothing that 
108 RMR can do to avoid or mitigate these other than by allowing 
109 RMR to retry the send operation, and even then it is possible 
110 (e.g., during connection reattempts), that a single retry 
111 loop is not enough to guarantee a successful send. 
112
113
114 RETURN VALUE
115 ------------
116
117 On success, new message buffer, with the payload containing 
118 the response from the remote endpoint is returned. The state 
119 in this buffer will reflect the overall send operation state 
120 and should be ``RMR_OK.`` 
121  
122 If a message is returned with a state which is anything other 
123 than ``RMR_OK,`` the indication is that the send was not 
124 successful. The user application must check the state and 
125 determine the course of action. If the return value is NULL, 
126 no message, the indication is that there was no response 
127 received within the timeout (max_wait) period of time. 
128
129
130 ERRORS
131 ------
132
133 The following values may be passed back in the *state* field 
134 of the returned message buffer. 
135  
136  
137    .. list-table:: 
138      :widths: auto 
139      :header-rows: 0 
140      :class: borderless 
141       
142      * - **RMR_ERR_WHID** 
143        - 
144          The wormhole ID passed in was not associated with an open 
145          wormhole, or was out of range for a valid ID. 
146       
147      * - **RMR_ERR_NOWHOPEN** 
148        - 
149          No wormholes exist, further attempt to validate the ID are 
150          skipped. 
151       
152      * - **RMR_ERR_BADARG** 
153        - 
154          The message buffer pointer did not refer to a valid message. 
155       
156      * - **RMR_ERR_NOHDR** 
157        - 
158          The header in the message buffer was not valid or corrupted. 
159           
160  
161
162
163 EXAMPLE
164 -------
165
166 The following is a simple example of how the a wormhole is 
167 created (rmr_wh_open) and then how ``rmr_wh_send_msg`` 
168 function is used to send messages. Some error checking is 
169 omitted for clarity. 
170  
171  
172 :: 
173  
174   
175  #include <rmr/rmr.h>    // system headers omitted for clarity
176   
177  int main() {
178     rmr_whid_t whid = -1;   // wormhole id for sending
179     void* mrc;      //msg router context
180          int i;
181     rmr_mbuf_t*  sbuf;      // send buffer
182     int     count = 0;
183     int     norm_msg_size = 1500;    // most messages fit in this size
184   
185     mrc = rmr_init( "43086", norm_msg_size, RMRFL_NONE );
186     if( mrc == NULL ) {
187        fprintf( stderr, "[FAIL] unable to initialise RMR environment\\n" );
188        exit( 1 );
189     }
190   
191     while( ! rmr_ready( mrc ) ) {        // wait for routing table info
192        sleep( 1 );
193     }
194   
195     sbuf = rmr_alloc_msg( mrc, 2048 );
196   
197     while( 1 ) {
198       if( whid < 0 ) {
199         whid = rmr_wh_open( mrc, "localhost:6123" );  // open fails if endpoint refuses conn
200            if( RMR_WH_CONNECTED( wh ) ) {
201             snprintf( sbuf->payload, 1024, "periodic update from sender: %d", count++ );
202             sbuf->len =  strlen( sbuf->payload );
203             sbuf = rmr_wh_call( mrc, whid, sbuf, 1000 );        // expect a response in 1s or less
204             if( sbuf != NULL && sbuf->state = RMR_OK ) {
205               sprintf( stderr, "response: %s\\n", sbuf->payload );    // assume they sent a string
206             } else {
207               sprintf( stderr, "response not received, or send error\\n" );
208             }
209          }
210        }
211   
212        sleep( 5 );
213     }
214  }
215  
216
217
218 SEE ALSO
219 --------
220
221 rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3), 
222 rmr_payload_size(3), rmr_rcv_msg(3), rmr_rcv_specific(3), 
223 rmr_rts_msg(3), rmr_ready(3), rmr_fib(3), rmr_has_str(3), 
224 rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3), 
225 rmr_set_stimeout(3), rmr_wh_open(3), rmr_wh_close(3), 
226 rmr_wh_state(3)