~ubuntu-branches/ubuntu/trusty/ocamlnet/trusty

« back to all changes in this revision

Viewing changes to doc/html-main/Rpc_proxy.html

  • Committer: Bazaar Package Importer
  • Author(s): Stéphane Glondu
  • Date: 2011-09-02 14:12:33 UTC
  • mfrom: (18.2.3 sid)
  • Revision ID: james.westby@ubuntu.com-20110902141233-zbj0ygxb92u6gy4z
Tags: 3.4-1
* New upstream release
  - add a new NetcgiRequire directive to ease dependency management
    (Closes: #637147)
  - remove patches that were applied upstream:
    + Added-missing-shebang-lines-in-example-shell-scripts
    + Try-also-ocamlc-for-POSIX-threads

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 
2
<html>
 
3
<head>
 
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>
 
198
</head>
 
199
<body>
 
200
<div class="navbar"><a href="Rpc_auth_gssapi.html">Previous</a>
 
201
&nbsp;<a href="index.html">Up</a>
 
202
&nbsp;<a href="Rpc_intro.html">Next</a>
 
203
</div>
 
204
<center><h1>Module <a href="type_Rpc_proxy.html">Rpc_proxy</a></h1></center>
 
205
<br>
 
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>
 
207
<hr width="100%">
 
208
<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>
 
219
</ul>
 
220
 
 
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.)
 
224
<p>
 
225
 
 
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
 
231
    errors in the past.
 
232
<p>
 
233
 
 
234
    See below for a tutorial.
 
235
<p>
 
236
 
 
237
    There is also a blog article explaining RPC proxies:
 
238
    <a href="http://blog.camlcity.org/blog/ocamlnet3_ha.html"> The next server,
 
239
    please!</a><br>
 
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>
 
242
<p>
 
243
 
 
244
    <span id="mclient"><h2>Managed clients</h2></span>
 
245
<p>
 
246
 
 
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.
 
251
<p>
 
252
 
 
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.
 
256
<p>
 
257
 
 
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:
 
262
<p>
 
263
 
 
264
   <pre><code class="code"> 
 
265
      let client =
 
266
        Proto_clnt.PROG.VERS.create_client connector protocol
 
267
      let result =
 
268
        Proto_clnt.PROG.VERS.procedure client argument
 
269
   </code></pre>
 
270
<p>
 
271
 
 
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.)
 
274
<p>
 
275
 
 
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:
 
280
<p>
 
281
 
 
282
   <pre><code class="code">      module M = Proto_clnt.Make'PROG(Rpc_proxy.ManagedClient)
 
283
 
 
284
      let esys =
 
285
        Unixqueue.create_unix_event_system()
 
286
      let mclient_config =
 
287
        Rpc_proxy.ManagedClient.create_mclient_config
 
288
          ~programs:[ Proto_clnt.PROG.VERS._program ]
 
289
          () in
 
290
      let mclient =
 
291
        Rpc_proxy.ManagedClient.create_mclient mclient_config connector esys
 
292
      let result =
 
293
        M.VERS.procedure mclient argument
 
294
   </code></pre>
 
295
<p>
 
296
 
 
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>.)
 
301
<p>
 
302
 
 
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.
 
306
<p>
 
307
 
 
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
 
314
      some cases)</li>
 
315
<li><code class="code">`Up sockaddr</code>: The client is connected and has the socket address
 
316
      <code class="code">sockaddr</code></li>
 
317
</ul>
 
318
 
 
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.
 
324
<p>
 
325
 
 
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
 
331
   by themselves.
 
332
<p>
 
333
 
 
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
 
340
   established again.
 
341
<p>
 
342
 
 
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.
 
346
<p>
 
347
 
 
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>
 
367
</ul>
 
368
<br>
 
369
<br>
 
370
<span id="2_ManagedSets"><h2>Managed Sets</h2></span>
 
371
<p>
 
372
 
 
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
 
380
    availability).
 
381
<p>
 
382
 
 
383
    For creating a managed set, the code looks like
 
384
<p>
 
385
 
 
386
    <pre><code class="code">      module M = Proto_clnt.Make'PROG(Rpc_proxy.ManagedClient)
 
387
 
 
388
      let esys =
 
389
        Unixqueue.create_unix_event_system()
 
390
      let mclient_config =
 
391
        Rpc_proxy.ManagedClient.create_mclient_config
 
392
          ~programs:[ Proto_clnt.PROG.VERS._program ]
 
393
          () in
 
394
      let mset_config =
 
395
        Rpc_proxy.ManagedSet.create_mset_config
 
396
          ~mclient_config
 
397
          () in
 
398
      let services =
 
399
        [| connector, n_connections; ... |] in
 
400
      let mset =
 
401
        Rpc_proxy.ManagedSet.create_mset 
 
402
          mset_config 
 
403
          services
 
404
          esys in
 
405
      let mclient, idx =
 
406
        Rpc_proxy.ManagedSet.mset_pick mset in
 
407
      let result =
 
408
        M.VERS.procedure mclient argument
 
409
    </code></pre>
 
410
<p>
 
411
 
 
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:
 
417
<p>
 
418
 
 
419
    <pre><code class="code">       let services =
 
420
          [| connector, n_connections |]
 
421
    </code></pre>
 
422
<p>
 
423
 
 
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).
 
432
<p>
 
433
 
 
434
    There are a number of options allowing to modify the default
 
435
    behavior:<ul>
 
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>
 
450
</ul>
 
451
 
 
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.
 
455
<p>
 
456
 
 
457
   <span id="2_Cachingreliabilitydata"><h2>Caching reliability data</h2></span>
 
458
<p>
 
459
 
 
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.
 
465
<p>
 
466
 
 
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>.
 
473
<p>
 
474
 
 
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:
 
479
<p>
 
480
 
 
481
   <pre><code class="code">     let rcache_config =
 
482
       Rpc_proxy.ReliabilityCache.create_rcache_config
 
483
        ~policy:`Independent
 
484
        ~threshold:3
 
485
        () in
 
486
     Rpc_proxy.ReliabilityCache.set_global_rcache_config rcache_config
 
487
   </code></pre>
 
488
<p>
 
489
 
 
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.
 
492
<p>
 
493
 
 
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
 
497
    course.
 
498
<p>
 
499
 
 
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:
 
506
<p>
 
507
 
 
508
    <pre><code class="code">    let rcache_config =
 
509
      Rpc_proxy.ReliabilityCache.create_rcache_config
 
510
        ~policy:`Independent
 
511
        ~threshold:3
 
512
        () in
 
513
    let rcache =
 
514
      Rpc_proxy.ReliabilityCache.derive_rcache
 
515
        (Rpc_proxy.ReliabilityCache.global_rcache())
 
516
        rcache_config in
 
517
    ...
 
518
    let mclient_config =
 
519
      Rpc_proxy.ManagedClient.create_mclient_config
 
520
        ...
 
521
        ~rcache
 
522
        ...
 
523
        ()
 
524
    </code></pre>
 
525
<p>
 
526
 
 
527
  <span id="2_Idempotentcalls"><h2>Idempotent calls</h2></span>
 
528
<p>
 
529
 
 
530
    In the layer of managed sets there is some limited support for
 
531
    automatically repeating failing idempotent RPC calls.
 
532
<p>
 
533
 
 
534
    Instead of calling the RPC with
 
535
<p>
 
536
 
 
537
    <pre><code class="code">      let mclient, idx =
 
538
        Rpc_proxy.ManagedSet.mset_pick mset in
 
539
      let result =
 
540
        M.VERS.procedure mclient argument
 
541
    </code></pre>
 
542
<p>
 
543
 
 
544
    one uses
 
545
<p>
 
546
 
 
547
    <pre><code class="code">      let result =
 
548
        Rpc_proxy.ManagedSet.idempotent_sync_call
 
549
          mset
 
550
          M.VERS.procedure'async
 
551
          argument
 
552
    </code></pre>
 
553
<p>
 
554
 
 
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.
 
559
<p>
 
560
 
 
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>).
 
563
<p>
 
564
 
 
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.
 
567
<p>
 
568
 
 
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>
 
571
</body></html>
 
 
b'\\ No newline at end of file'