1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
4
<link rel="stylesheet" href="style.css" type="text/css">
5
<meta content="text/html; charset=iso-8859-1" http-equiv="Content-Type">
6
<link rel="Start" href="index.html">
7
<link rel="previous" href="Rpc_auth_gssapi.html">
8
<link rel="next" href="Rpc_intro.html">
9
<link rel="Up" href="index.html">
10
<link title="Index of types" rel=Appendix href="index_types.html">
11
<link title="Index of exceptions" rel=Appendix href="index_exceptions.html">
12
<link title="Index of values" rel=Appendix href="index_values.html">
13
<link title="Index of class attributes" rel=Appendix href="index_attributes.html">
14
<link title="Index of class methods" rel=Appendix href="index_methods.html">
15
<link title="Index of classes" rel=Appendix href="index_classes.html">
16
<link title="Index of class types" rel=Appendix href="index_class_types.html">
17
<link title="Index of modules" rel=Appendix href="index_modules.html">
18
<link title="Index of module types" rel=Appendix href="index_module_types.html">
19
<link title="Uq_gtk" rel="Chapter" href="Uq_gtk.html">
20
<link title="Uq_ssl" rel="Chapter" href="Uq_ssl.html">
21
<link title="Https_client" rel="Chapter" href="Https_client.html">
22
<link title="Uq_tcl" rel="Chapter" href="Uq_tcl.html">
23
<link title="Equeue" rel="Chapter" href="Equeue.html">
24
<link title="Unixqueue" rel="Chapter" href="Unixqueue.html">
25
<link title="Unixqueue_pollset" rel="Chapter" href="Unixqueue_pollset.html">
26
<link title="Unixqueue_select" rel="Chapter" href="Unixqueue_select.html">
27
<link title="Uq_resolver" rel="Chapter" href="Uq_resolver.html">
28
<link title="Uq_engines" rel="Chapter" href="Uq_engines.html">
29
<link title="Uq_socks5" rel="Chapter" href="Uq_socks5.html">
30
<link title="Uq_io" rel="Chapter" href="Uq_io.html">
31
<link title="Uq_lwt" rel="Chapter" href="Uq_lwt.html">
32
<link title="Uq_libevent" rel="Chapter" href="Uq_libevent.html">
33
<link title="Equeue_intro" rel="Chapter" href="Equeue_intro.html">
34
<link title="Netcamlbox" rel="Chapter" href="Netcamlbox.html">
35
<link title="Netcgi_apache" rel="Chapter" href="Netcgi_apache.html">
36
<link title="Netcgi_modtpl" rel="Chapter" href="Netcgi_modtpl.html">
37
<link title="Netcgi_plex" rel="Chapter" href="Netcgi_plex.html">
38
<link title="Netcgi_common" rel="Chapter" href="Netcgi_common.html">
39
<link title="Netcgi" rel="Chapter" href="Netcgi.html">
40
<link title="Netcgi_ajp" rel="Chapter" href="Netcgi_ajp.html">
41
<link title="Netcgi_scgi" rel="Chapter" href="Netcgi_scgi.html">
42
<link title="Netcgi_cgi" rel="Chapter" href="Netcgi_cgi.html">
43
<link title="Netcgi_fcgi" rel="Chapter" href="Netcgi_fcgi.html">
44
<link title="Netcgi_dbi" rel="Chapter" href="Netcgi_dbi.html">
45
<link title="Netcgi1_compat" rel="Chapter" href="Netcgi1_compat.html">
46
<link title="Netcgi_test" rel="Chapter" href="Netcgi_test.html">
47
<link title="Netcgi_porting" rel="Chapter" href="Netcgi_porting.html">
48
<link title="Http_client_conncache" rel="Chapter" href="Http_client_conncache.html">
49
<link title="Http_client" rel="Chapter" href="Http_client.html">
50
<link title="Telnet_client" rel="Chapter" href="Telnet_client.html">
51
<link title="Ftp_data_endpoint" rel="Chapter" href="Ftp_data_endpoint.html">
52
<link title="Ftp_client" rel="Chapter" href="Ftp_client.html">
53
<link title="Http_fs" rel="Chapter" href="Http_fs.html">
54
<link title="Ftp_fs" rel="Chapter" href="Ftp_fs.html">
55
<link title="Netclient_tut" rel="Chapter" href="Netclient_tut.html">
56
<link title="Netgssapi" rel="Chapter" href="Netgssapi.html">
57
<link title="Nethttpd_types" rel="Chapter" href="Nethttpd_types.html">
58
<link title="Nethttpd_kernel" rel="Chapter" href="Nethttpd_kernel.html">
59
<link title="Nethttpd_reactor" rel="Chapter" href="Nethttpd_reactor.html">
60
<link title="Nethttpd_engine" rel="Chapter" href="Nethttpd_engine.html">
61
<link title="Nethttpd_services" rel="Chapter" href="Nethttpd_services.html">
62
<link title="Nethttpd_plex" rel="Chapter" href="Nethttpd_plex.html">
63
<link title="Nethttpd_util" rel="Chapter" href="Nethttpd_util.html">
64
<link title="Nethttpd_intro" rel="Chapter" href="Nethttpd_intro.html">
65
<link title="Netmech_scram" rel="Chapter" href="Netmech_scram.html">
66
<link title="Netmech_scram_gssapi" rel="Chapter" href="Netmech_scram_gssapi.html">
67
<link title="Netmcore" rel="Chapter" href="Netmcore.html">
68
<link title="Netmcore_camlbox" rel="Chapter" href="Netmcore_camlbox.html">
69
<link title="Netmcore_mempool" rel="Chapter" href="Netmcore_mempool.html">
70
<link title="Netmcore_heap" rel="Chapter" href="Netmcore_heap.html">
71
<link title="Netmcore_ref" rel="Chapter" href="Netmcore_ref.html">
72
<link title="Netmcore_array" rel="Chapter" href="Netmcore_array.html">
73
<link title="Netmcore_sem" rel="Chapter" href="Netmcore_sem.html">
74
<link title="Netmcore_mutex" rel="Chapter" href="Netmcore_mutex.html">
75
<link title="Netmcore_condition" rel="Chapter" href="Netmcore_condition.html">
76
<link title="Netmcore_queue" rel="Chapter" href="Netmcore_queue.html">
77
<link title="Netmcore_buffer" rel="Chapter" href="Netmcore_buffer.html">
78
<link title="Netmcore_matrix" rel="Chapter" href="Netmcore_matrix.html">
79
<link title="Netmcore_hashtbl" rel="Chapter" href="Netmcore_hashtbl.html">
80
<link title="Netmcore_process" rel="Chapter" href="Netmcore_process.html">
81
<link title="Netmcore_tut" rel="Chapter" href="Netmcore_tut.html">
82
<link title="Netplex_types" rel="Chapter" href="Netplex_types.html">
83
<link title="Netplex_mp" rel="Chapter" href="Netplex_mp.html">
84
<link title="Netplex_mt" rel="Chapter" href="Netplex_mt.html">
85
<link title="Netplex_log" rel="Chapter" href="Netplex_log.html">
86
<link title="Netplex_controller" rel="Chapter" href="Netplex_controller.html">
87
<link title="Netplex_container" rel="Chapter" href="Netplex_container.html">
88
<link title="Netplex_sockserv" rel="Chapter" href="Netplex_sockserv.html">
89
<link title="Netplex_workload" rel="Chapter" href="Netplex_workload.html">
90
<link title="Netplex_main" rel="Chapter" href="Netplex_main.html">
91
<link title="Netplex_config" rel="Chapter" href="Netplex_config.html">
92
<link title="Netplex_kit" rel="Chapter" href="Netplex_kit.html">
93
<link title="Rpc_netplex" rel="Chapter" href="Rpc_netplex.html">
94
<link title="Netplex_cenv" rel="Chapter" href="Netplex_cenv.html">
95
<link title="Netplex_semaphore" rel="Chapter" href="Netplex_semaphore.html">
96
<link title="Netplex_sharedvar" rel="Chapter" href="Netplex_sharedvar.html">
97
<link title="Netplex_mutex" rel="Chapter" href="Netplex_mutex.html">
98
<link title="Netplex_encap" rel="Chapter" href="Netplex_encap.html">
99
<link title="Netplex_intro" rel="Chapter" href="Netplex_intro.html">
100
<link title="Netplex_advanced" rel="Chapter" href="Netplex_advanced.html">
101
<link title="Netplex_admin" rel="Chapter" href="Netplex_admin.html">
102
<link title="Netshm" rel="Chapter" href="Netshm.html">
103
<link title="Netshm_data" rel="Chapter" href="Netshm_data.html">
104
<link title="Netshm_hashtbl" rel="Chapter" href="Netshm_hashtbl.html">
105
<link title="Netshm_array" rel="Chapter" href="Netshm_array.html">
106
<link title="Netshm_intro" rel="Chapter" href="Netshm_intro.html">
107
<link title="Netconversion" rel="Chapter" href="Netconversion.html">
108
<link title="Netchannels" rel="Chapter" href="Netchannels.html">
109
<link title="Netstream" rel="Chapter" href="Netstream.html">
110
<link title="Mimestring" rel="Chapter" href="Mimestring.html">
111
<link title="Netmime" rel="Chapter" href="Netmime.html">
112
<link title="Netsendmail" rel="Chapter" href="Netsendmail.html">
113
<link title="Neturl" rel="Chapter" href="Neturl.html">
114
<link title="Netaddress" rel="Chapter" href="Netaddress.html">
115
<link title="Netbuffer" rel="Chapter" href="Netbuffer.html">
116
<link title="Netdate" rel="Chapter" href="Netdate.html">
117
<link title="Netencoding" rel="Chapter" href="Netencoding.html">
118
<link title="Netulex" rel="Chapter" href="Netulex.html">
119
<link title="Netaccel" rel="Chapter" href="Netaccel.html">
120
<link title="Netaccel_link" rel="Chapter" href="Netaccel_link.html">
121
<link title="Nethtml" rel="Chapter" href="Nethtml.html">
122
<link title="Netstring_str" rel="Chapter" href="Netstring_str.html">
123
<link title="Netstring_pcre" rel="Chapter" href="Netstring_pcre.html">
124
<link title="Netmappings" rel="Chapter" href="Netmappings.html">
125
<link title="Netaux" rel="Chapter" href="Netaux.html">
126
<link title="Nethttp" rel="Chapter" href="Nethttp.html">
127
<link title="Netpagebuffer" rel="Chapter" href="Netpagebuffer.html">
128
<link title="Netfs" rel="Chapter" href="Netfs.html">
129
<link title="Netglob" rel="Chapter" href="Netglob.html">
130
<link title="Netauth" rel="Chapter" href="Netauth.html">
131
<link title="Netsockaddr" rel="Chapter" href="Netsockaddr.html">
132
<link title="Netnumber" rel="Chapter" href="Netnumber.html">
133
<link title="Rtypes" rel="Chapter" href="Rtypes.html">
134
<link title="Xdr_mstring" rel="Chapter" href="Xdr_mstring.html">
135
<link title="Xdr" rel="Chapter" href="Xdr.html">
136
<link title="Netcompression" rel="Chapter" href="Netcompression.html">
137
<link title="Netchannels_tut" rel="Chapter" href="Netchannels_tut.html">
138
<link title="Netmime_tut" rel="Chapter" href="Netmime_tut.html">
139
<link title="Netsendmail_tut" rel="Chapter" href="Netsendmail_tut.html">
140
<link title="Netulex_tut" rel="Chapter" href="Netulex_tut.html">
141
<link title="Neturl_tut" rel="Chapter" href="Neturl_tut.html">
142
<link title="Netsys" rel="Chapter" href="Netsys.html">
143
<link title="Netsys_posix" rel="Chapter" href="Netsys_posix.html">
144
<link title="Netsys_pollset" rel="Chapter" href="Netsys_pollset.html">
145
<link title="Netlog" rel="Chapter" href="Netlog.html">
146
<link title="Netexn" rel="Chapter" href="Netexn.html">
147
<link title="Netsys_win32" rel="Chapter" href="Netsys_win32.html">
148
<link title="Netsys_pollset_posix" rel="Chapter" href="Netsys_pollset_posix.html">
149
<link title="Netsys_pollset_win32" rel="Chapter" href="Netsys_pollset_win32.html">
150
<link title="Netsys_pollset_generic" rel="Chapter" href="Netsys_pollset_generic.html">
151
<link title="Netsys_signal" rel="Chapter" href="Netsys_signal.html">
152
<link title="Netsys_oothr" rel="Chapter" href="Netsys_oothr.html">
153
<link title="Netsys_xdr" rel="Chapter" href="Netsys_xdr.html">
154
<link title="Netsys_rng" rel="Chapter" href="Netsys_rng.html">
155
<link title="Netsys_types" rel="Chapter" href="Netsys_types.html">
156
<link title="Netsys_mem" rel="Chapter" href="Netsys_mem.html">
157
<link title="Netsys_tmp" rel="Chapter" href="Netsys_tmp.html">
158
<link title="Netgzip" rel="Chapter" href="Netgzip.html">
159
<link title="Netpop" rel="Chapter" href="Netpop.html">
160
<link title="Rpc_auth_dh" rel="Chapter" href="Rpc_auth_dh.html">
161
<link title="Rpc_key_service" rel="Chapter" href="Rpc_key_service.html">
162
<link title="Rpc_time" rel="Chapter" href="Rpc_time.html">
163
<link title="Rpc_auth_local" rel="Chapter" href="Rpc_auth_local.html">
164
<link title="Rpc_ssl" rel="Chapter" href="Rpc_ssl.html">
165
<link title="Rpc_xti_client" rel="Chapter" href="Rpc_xti_client.html">
166
<link title="Rpc" rel="Chapter" href="Rpc.html">
167
<link title="Rpc_program" rel="Chapter" href="Rpc_program.html">
168
<link title="Rpc_util" rel="Chapter" href="Rpc_util.html">
169
<link title="Rpc_portmapper_aux" rel="Chapter" href="Rpc_portmapper_aux.html">
170
<link title="Rpc_packer" rel="Chapter" href="Rpc_packer.html">
171
<link title="Rpc_transport" rel="Chapter" href="Rpc_transport.html">
172
<link title="Rpc_client" rel="Chapter" href="Rpc_client.html">
173
<link title="Rpc_simple_client" rel="Chapter" href="Rpc_simple_client.html">
174
<link title="Rpc_portmapper_clnt" rel="Chapter" href="Rpc_portmapper_clnt.html">
175
<link title="Rpc_portmapper" rel="Chapter" href="Rpc_portmapper.html">
176
<link title="Rpc_server" rel="Chapter" href="Rpc_server.html">
177
<link title="Rpc_auth_sys" rel="Chapter" href="Rpc_auth_sys.html">
178
<link title="Rpc_auth_gssapi" rel="Chapter" href="Rpc_auth_gssapi.html">
179
<link title="Rpc_proxy" rel="Chapter" href="Rpc_proxy.html">
180
<link title="Rpc_intro" rel="Chapter" href="Rpc_intro.html">
181
<link title="Rpc_mapping_ref" rel="Chapter" href="Rpc_mapping_ref.html">
182
<link title="Rpc_intro_gss" rel="Chapter" href="Rpc_intro_gss.html">
183
<link title="Shell_sys" rel="Chapter" href="Shell_sys.html">
184
<link title="Shell" rel="Chapter" href="Shell.html">
185
<link title="Shell_uq" rel="Chapter" href="Shell_uq.html">
186
<link title="Shell_fs" rel="Chapter" href="Shell_fs.html">
187
<link title="Shell_intro" rel="Chapter" href="Shell_intro.html">
188
<link title="Netsmtp" rel="Chapter" href="Netsmtp.html">
189
<link title="Intro" rel="Chapter" href="Intro.html">
190
<link title="Platform" rel="Chapter" href="Platform.html">
191
<link title="Foreword" rel="Chapter" href="Foreword.html">
192
<link title="Ipv6" rel="Chapter" href="Ipv6.html"><link title="The Rpc_proxy tutorial" rel="Section" href="#tut">
193
<link title="Managed clients" rel="Subsection" href="#mclient">
194
<link title="Managed Sets" rel="Subsection" href="#2_ManagedSets">
195
<link title="Caching reliability data" rel="Subsection" href="#2_Cachingreliabilitydata">
196
<link title="Idempotent calls" rel="Subsection" href="#2_Idempotentcalls">
197
<title>Ocamlnet 3 Reference Manual : Rpc_proxy</title>
200
<div class="navbar"><a href="Rpc_auth_gssapi.html">Previous</a>
201
<a href="index.html">Up</a>
202
<a href="Rpc_intro.html">Next</a>
204
<center><h1>Module <a href="type_Rpc_proxy.html">Rpc_proxy</a></h1></center>
206
<pre><span class="keyword">module</span> Rpc_proxy: <code class="code">sig</code> <a href="Rpc_proxy.html">..</a> <code class="code">end</code></pre>RPC proxies<br>
209
The <code class="code">Rpc_proxy</code> module provides an improved reliability layer on
210
top of <a href="Rpc_client.html"><code class="code">Rpc_client</code></a>. This layer especially features:<ul>
211
<li>automatic connection management: TCP connections are started
212
and terminated as needed</li>
213
<li>multiple connections can be held in parallel to a remote
214
server to increase concurrency on the server</li>
215
<li>failover to other servers when the orignal servers time out</li>
216
<li>support for an initial ping at connection establishment time
217
to test the availability of the connection</li>
218
<li>retransmission of idempotent RPC calls</li>
221
Proxies can only handle stream connections (TCP and Unix Domain).
222
Also, the remote endpoints must already be specified by socket
223
addresses. (No portmapper and other indirect lookup methods.)
226
The proxy functionality is implemented in two layers, the managed
227
clients, and the managed sets. The former layer can handle only
228
one TCP connection (with reconnect), whereas the latter is able to
229
manage a bunch of connections to the same service. Both layers
230
can profit from a reliability cache that knows which services had
234
See below for a tutorial.
237
There is also a blog article explaining RPC proxies:
238
<a href="http://blog.camlcity.org/blog/ocamlnet3_ha.html"> The next server,
240
<pre><span class="keyword">module</span> <a href="Rpc_proxy.ReliabilityCache.html">ReliabilityCache</a>: <code class="code">sig</code> <a href="Rpc_proxy.ReliabilityCache.html">..</a> <code class="code">end</code></pre><pre><span class="keyword">module</span> <a href="Rpc_proxy.ManagedClient.html">ManagedClient</a>: <code class="code">sig</code> <a href="Rpc_proxy.ManagedClient.html">..</a> <code class="code">end</code></pre><pre><span class="keyword">module</span> <a href="Rpc_proxy.ManagedSet.html">ManagedSet</a>: <code class="code">sig</code> <a href="Rpc_proxy.ManagedSet.html">..</a> <code class="code">end</code></pre><br>
241
<span id="tut"><h1>The <code class="code">Rpc_proxy</code> tutorial</h1></span>
244
<span id="mclient"><h2>Managed clients</h2></span>
247
A normal RPC client has a very limited lifecylce: It is created,
248
then a connection is made to an RPC service, messages are exchanged,
249
and finally the connection is terminated. After that the client
250
becomes unusable. In short, it is "use once" client.
253
In contrast to this, managed clients can be recycled. This is
254
especially useful for dealing with socket errors, and
255
connection terminations triggered by the RPC server.
258
<b>How to use managed clients:</b> For a <i>normal</i> RPC client the
259
generator <code class="code">ocamlrpcgen</code> creates all required glue code to easily
260
start RPC calls. For example, if a file <code class="code">proto.x</code> is taken as input
261
for <code class="code">ocamlrpcgen</code>, a piece of code doing a call could look like:
264
<pre><code class="code">
266
Proto_clnt.PROG.VERS.create_client connector protocol
268
Proto_clnt.PROG.VERS.procedure client argument
272
(Here, <code class="code">PROG</code>, <code class="code">VERS</code>, <code class="code">procedure</code> are just placeholders for the
273
name of the program, the version identifier, and the procedure name.)
276
For RPC proxies, however, this is slightly more complicated. <code class="code">ocamlrpcgen</code>
277
does not produce a managed client that is ready for use. Instead,
278
only a functor is provided that can take the
279
<code class="code">Rpc_proxy.ManagedlClient</code> module as input:
282
<pre><code class="code"> module M = Proto_clnt.Make'PROG(Rpc_proxy.ManagedClient)
285
Unixqueue.create_unix_event_system()
287
Rpc_proxy.ManagedClient.create_mclient_config
288
~programs:[ Proto_clnt.PROG.VERS._program ]
291
Rpc_proxy.ManagedClient.create_mclient mclient_config connector esys
293
M.VERS.procedure mclient argument
297
(The functor approach has been chosen, because it gives the
298
user more flexibility - it is possible to apply the functor
299
on other implementations of improved clients than
300
<a href="Rpc_proxy.ManagedClient.html"><code class="code">Rpc_proxy.ManagedClient</code></a>.)
303
Note that <code class="code">esys</code> is always explicit, even in the case the
304
user only performs synchronous calls - the user should create
305
a new <code class="code">esys</code> then, pass it to <code class="code">mclient</code>, and ignore it otherwise.
308
Now, how does the recycling feature work? The managed client can be
309
in one of three states:<ul>
310
<li><code class="code">`Down</code>: The client is not connected. This is the initial state,
311
and the state after errors and terminated connections (no matter
312
whether triggered by the client or by the server)</li>
313
<li><code class="code">`Connecting</code>: The client is busy (re)connecting (only used in
315
<li><code class="code">`Up sockaddr</code>: The client is connected and has the socket address
316
<code class="code">sockaddr</code></li>
319
The state can be queried with <a href="Rpc_proxy.ManagedClient.html#VALmclient_state"><code class="code">Rpc_proxy.ManagedClient.mclient_state</code></a>.
320
When it is <code class="code">`Down</code>, the next RPC call automatically starts the
321
reconnect to the service. When the connection is established, the
322
call is done, and the messages are exchanged that are representing
323
the call. After that, the state remains <code class="code">`Up</code> after the call.
326
When the call stops because of an error, the error is reported to
327
the user in the normal way, and the client is shut down, i.e. after
328
an error the state is <code class="code">`Down</code>. If the user decides to try the call
329
again, the client automatically reconnects following the outlined
330
rules. Note that managed clients never automatically retry calls
334
When the TCP connection is regularly shut down (either by the server
335
or by the client calling <a href="Rpc_proxy.ManagedClient.html#VALshut_down"><code class="code">Rpc_proxy.ManagedClient.shut_down</code></a>), the
336
client state is changed to <code class="code">`Down</code> at the next opportunity. Especially
337
a server-driven shutdown may first be detected when the next RPC call
338
is tried on the connection. This may or may not lead to an error
339
depending on the exact timing. In any way, the connection is finally
343
Of course, managed clients must be shut down after use, because
344
there is no other (automatic) way of recognizing that they are no
345
longer used. Call <a href="Rpc_proxy.ManagedClient.html#VALshut_down"><code class="code">Rpc_proxy.ManagedClient.shut_down</code></a> for this.
348
Managed client also have a few more features that can be
349
enabled in <code class="code">mclient_config</code>, especially:<ul>
350
<li><b>Initial ping</b>: This means that the TCP connection is tested
351
before being used for user operations. The test is done by pinging
352
the service once (via the RPC null procedure). This is recommended
353
because some connectivity problems can first be detected when the
354
TCP connection is actually used.</li>
355
<li><b>Idle timeout</b>: The TCP connection is closed after it is
356
idle for some period of time. "Idle" means here that nothing is
357
being transmitted, and that no response from the server is expected.
358
The connection is closed at the first opportunity. The user should
359
be aware that this can only happen when the event loop for <code class="code">esys</code>
360
is running. Especially for synchronous calls this is typically
361
not the case, so one would have to call <code class="code">Unixqueue.run esys</code> now
362
and then to create opportunities for detecting the idle timeout.</li>
363
<li><b>Reliability cache</b>: The cache object counts errors, and can
364
disable certain service endpoints if they only produce errors.
365
This mostly makes sense when there are alternative endpoints,
366
i.e. in the context of a managed set (see below).</li>
370
<span id="2_ManagedSets"><h2>Managed Sets</h2></span>
373
Managed sets are another layer on top of the managed
374
clients. These sets are able to manage several connections where
375
each is implemented as managed client. The connections can go to
376
the same server endpoint in order to parallelize RPCs at the
377
client side, or to several server endpoints that provide the same
378
service. The latter can be used for client-driven load balancing,
379
and for client-driven failover management of HA setups (HA = high
383
For creating a managed set, the code looks like
386
<pre><code class="code"> module M = Proto_clnt.Make'PROG(Rpc_proxy.ManagedClient)
389
Unixqueue.create_unix_event_system()
391
Rpc_proxy.ManagedClient.create_mclient_config
392
~programs:[ Proto_clnt.PROG.VERS._program ]
395
Rpc_proxy.ManagedSet.create_mset_config
399
[| connector, n_connections; ... |] in
401
Rpc_proxy.ManagedSet.create_mset
406
Rpc_proxy.ManagedSet.mset_pick mset in
408
M.VERS.procedure mclient argument
412
The managed clients are internally created by the set - one
413
only should pass in <code class="code">mclient_config</code> so the set knows what kind of
414
client is preferred. For the simple application of maintaining
415
several connections to the same server, one would create the <code class="code">mset</code>
416
with a one-element service array:
419
<pre><code class="code"> let services =
420
[| connector, n_connections |]
424
where <code class="code">connector</code> describes the server port, and <code class="code">n_connections</code> is
425
the maximum number of connections to create and maintain.
426
The <a href="Rpc_proxy.ManagedSet.html#VALmset_pick"><code class="code">Rpc_proxy.ManagedSet.mset_pick</code></a>
427
function creates internally up to <code class="code">n_connections</code> managed clients,
428
and returns one of them. By default, it is not guaranteed that the
429
client is idle (meaning no previous call is pending) -
430
if the connections are all already busy, <code class="code">mset_pick</code>
431
starts returning busy connections (but the least busy one first).
434
There are a number of options allowing to modify the default
436
<li>One can enforce that only idle clients are returned by <code class="code">mset_pick</code>.
437
To do this, pass the argument <code class="code">~mset_pending_calls_max:1</code> to
438
<a href="Rpc_proxy.ManagedSet.html#VALcreate_mset_config"><code class="code">Rpc_proxy.ManagedSet.create_mset_config</code></a>. It can then happen
439
that no client is idle, and <code class="code">mset_pick</code> will raise
440
<a href="Rpc_proxy.ManagedSet.html#EXCEPTIONCluster_service_unavailable"><code class="code">Rpc_proxy.ManagedSet.Cluster_service_unavailable</code></a>.</li>
441
<li>If the <code class="code">services</code> array has more than one element, they are
442
considered as equivalent service endpoints. <code class="code">mset_pick</code> will
443
pick one of the endpoints. There are two policies controlling
444
the selection: With <code class="code">~policy:`Balance_load</code> it is aimed at
445
sending roughly the same number of calls to all endpoints. With
446
<code class="code">~policy:`Failover</code> the services are assigned precedences by the position
447
in the array (i.e. the first service is used as long as possible,
448
then the second service is used, etc.). The <code class="code">policy</code> argument
449
is again to be passed to <a href="Rpc_proxy.ManagedSet.html#VALcreate_mset_config"><code class="code">Rpc_proxy.ManagedSet.create_mset_config</code></a>.</li>
452
Of course, managed sets must be shut down after use, because
453
there is no other (automatic) way of recognizing that they are no
454
longer used. Call <a href="Rpc_proxy.ManagedSet.html#VALshut_down"><code class="code">Rpc_proxy.ManagedSet.shut_down</code></a> for this.
457
<span id="2_Cachingreliabilitydata"><h2>Caching reliability data</h2></span>
460
The cache allows to disable certain hosts or ports when the error
461
counter reaches a limit. The service is disabled for a limited time span.
462
This is especially useful when there is an alternate port that can
463
jump in for the failing one, i.e. when the <code class="code">services</code> array of a
464
managed set has two or more elements.
467
There is a single global cache object, but one can also create
468
specific cache objects. Generally, cache objects can be shared by
469
many managed clients and managed sets. The hope is that sharing
470
is useful because more data can be made available to users of
471
services. If you do not want to use the global cache object, you
472
can create your own, and configure it in <code class="code">mclient_config</code>.
475
The global cache object is automatically used when nothing else
476
is specified. The global cache object is by default configured in
477
a way so it does not have any effect, though. So we have to
478
change this in order to enable the cache:
481
<pre><code class="code"> let rcache_config =
482
Rpc_proxy.ReliabilityCache.create_rcache_config
486
Rpc_proxy.ReliabilityCache.set_global_rcache_config rcache_config
490
This means that 3 errors in sequence disable a service port. <code class="code">`Independent</code>
491
means that each port is handled independently in this respect.
494
At the first time, the port is only disabled for one second. The
495
duration of the time span is increased by each additional error
496
until it reaches 64 seconds. These durations can be changed, of
500
As the impact of changing the global cache object is sometimes
501
unpredictable, one can also create a private cache object
502
(<a href="Rpc_proxy.ReliabilityCache.html#VALcreate_rcache"><code class="code">Rpc_proxy.ReliabilityCache.create_rcache</code></a>). Another way is
503
to derive a semi-private object from the global one. This means
504
that the error counters are global, but the interpretation can
505
be set individually in each use. This would look like:
508
<pre><code class="code"> let rcache_config =
509
Rpc_proxy.ReliabilityCache.create_rcache_config
514
Rpc_proxy.ReliabilityCache.derive_rcache
515
(Rpc_proxy.ReliabilityCache.global_rcache())
519
Rpc_proxy.ManagedClient.create_mclient_config
527
<span id="2_Idempotentcalls"><h2>Idempotent calls</h2></span>
530
In the layer of managed sets there is some limited support for
531
automatically repeating failing idempotent RPC calls.
534
Instead of calling the RPC with
537
<pre><code class="code"> let mclient, idx =
538
Rpc_proxy.ManagedSet.mset_pick mset in
540
M.VERS.procedure mclient argument
547
<pre><code class="code"> let result =
548
Rpc_proxy.ManagedSet.idempotent_sync_call
550
M.VERS.procedure'async
555
The effet is that <a href="Rpc_proxy.ManagedSet.html#VALidempotent_sync_call"><code class="code">Rpc_proxy.ManagedSet.idempotent_sync_call</code></a>
556
repeats automatically the call when an error occurs. It is
557
assumed that the call is idempotent so it can be repeated
558
without changing the meaning.
561
The call may be repeated several times. This is configured in
562
the managed set <code class="code">mset</code> (parameter <code class="code">mset_idempotent_max</code>).
565
Note that one has to pass the asynchronous version (suffix <code class="code">'async</code>)
566
of the RPC wrapper even when doing a synchronous call.
569
Also see the documentation for
570
<a href="Rpc_proxy.ManagedSet.html#VALidempotent_async_call"><code class="code">Rpc_proxy.ManagedSet.idempotent_async_call</code></a>.<br>
b'\\ No newline at end of file'