Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

first commit. pluton framework

  • Loading branch information...
commit f42d421d18df3a9fc81d06c8e50e79bf637224ad 0 parents
@yathin yathin authored
Showing with 42,924 additions and 0 deletions.
  1. +590 −0 Docs/FAQ.html
  2. +54 −0 Docs/about.html
  3. +609 −0 Docs/background.html
  4. +85 −0 Docs/catalog.html
  5. +844 −0 Docs/cclientAPI.html
  6. +1,367 −0 Docs/clientAPI.html
  7. +792 −0 Docs/clientAPINonBlock.html
  8. +540 −0 Docs/commands.html
  9. +503 −0 Docs/configuration.html
  10. +399 −0 Docs/cserviceAPI.html
  11. +417 −0 Docs/design.html
  12. +155 −0 Docs/fault.html
  13. +255 −0 Docs/future.html
  14. +167 −0 Docs/howToStructureService.html
  15. +235 −0 Docs/howToTestService.html
  16. BIN  Docs/images/overview_client_service.jpg
  17. BIN  Docs/images/pluto-charon.jpg
  18. BIN  Docs/images/pluto-symbol.jpg
  19. +10,414 −0 Docs/images/pluton.graffle
  20. BIN  Docs/images/plutonOverview1.jpg
  21. BIN  Docs/images/plutonRemoteProxy.jpg
  22. BIN  Docs/images/plutonThreads1.jpg
  23. BIN  Docs/images/responseTimes.jpg
  24. BIN  Docs/images/responseTimes2.jpg
  25. +350 −0 Docs/index.html
  26. +277 −0 Docs/javaClientAPI.html
  27. +230 −0 Docs/javaServiceAPI.html
  28. +209 −0 Docs/logs.html
  29. +107 −0 Docs/overview.html
  30. +99 −0 Docs/performance.html
  31. +300 −0 Docs/perlAPI.html
  32. +263 −0 Docs/phpAPI.html
  33. +463 −0 Docs/plutonManager.html
  34. +98 −0 Docs/sampleClient.cc.txt
  35. +113 −0 Docs/sampleClient.html
  36. +208 −0 Docs/sampleEventClient.cc.txt
  37. +85 −0 Docs/sampleProxyClient.cc.txt
  38. +57 −0 Docs/sampleService.cc.txt
  39. +159 −0 Docs/serialization.html
  40. +1,080 −0 Docs/serviceAPI.html
  41. +81 −0 Docs/serviceKey.html
  42. +335 −0 Docs/threading.html
  43. +10 −0 HOWTO.build.txt
  44. +26 −0 HOWTO.run.txt
  45. +29 −0 LICENSE.txt
  46. +41 −0 Makefile
  47. +21 −0 README.txt
  48. +15 −0 TODO.txt
  49. +64 −0 clientServiceLibrary/Makefile
  50. +547 −0 clientServiceLibrary/client.cc
  51. +74 −0 clientServiceLibrary/clientEvent.cc
  52. +262 −0 clientServiceLibrary/clientEventImpl.cc
  53. +1,628 −0 clientServiceLibrary/clientImpl.cc
  54. +165 −0 clientServiceLibrary/clientImpl.h
  55. +134 −0 clientServiceLibrary/clientRequest.cc
  56. +374 −0 clientServiceLibrary/clientRequestImpl.cc
  57. +157 −0 clientServiceLibrary/clientRequestImpl.h
  58. +373 −0 clientServiceLibrary/client_C.cc
  59. +204 −0 clientServiceLibrary/decodePacket.cc
  60. +62 −0 clientServiceLibrary/decodePacket.h
  61. +55 −0 clientServiceLibrary/fault.cc
  62. +142 −0 clientServiceLibrary/faultImpl.cc
  63. +67 −0 clientServiceLibrary/faultImpl.h
  64. +30 −0 clientServiceLibrary/generate_FaultEnglish.pl
  65. +142 −0 clientServiceLibrary/perCallerClient.cc
  66. +123 −0 clientServiceLibrary/perCallerClient.h
  67. +490 −0 clientServiceLibrary/requestImpl.cc
  68. +202 −0 clientServiceLibrary/requestImpl.h
  69. +73 −0 clientServiceLibrary/requestQueue.cc
  70. +31 −0 clientServiceLibrary/requestQueue.h
  71. +184 −0 clientServiceLibrary/service.cc
  72. +1,249 −0 clientServiceLibrary/serviceImpl.cc
  73. +173 −0 clientServiceLibrary/serviceImpl.h
  74. +166 −0 clientServiceLibrary/service_C.cc
  75. +170 −0 clientServiceLibrary/shmLookupReader.cc
  76. +56 −0 clientServiceLibrary/timeoutClock.cc
  77. +24 −0 clientServiceLibrary/timeoutClock.h
  78. +49 −0 commands/Makefile
  79. +357 −0 commands/plBatch.cc
  80. +42 −0 commands/plKillOldServices
  81. +152 −0 commands/plLookup.cc
  82. +136 −0 commands/plNetStringGrep.cc
  83. +423 −0 commands/plPing.cc
  84. +337 −0 commands/plReceiver.cc
  85. +71 −0 commands/plReloadManager
  86. +222 −0 commands/plSend.cc
  87. +383 −0 commands/plTest.cc
  88. +539 −0 commands/plTransmitter.cc
  89. +61 −0 commands/plVersion.cc
  90. +38 −0 commonLibrary/Makefile
  91. +133 −0 commonLibrary/lineToArgv.cc
  92. +113 −0 commonLibrary/misc.cc
  93. +1,359 −0 commonLibrary/netString.cc
  94. +31 −0 commonLibrary/rateLimit.cc
  95. +175 −0 commonLibrary/serviceKey.cc
  96. +27 −0 commonLibrary/shmLookupCommon.cc
  97. +305 −0 commonLibrary/shmServiceCommon.cc
  98. +40 −0 commonLibrary/splitInterface.cc
  99. +443 −0 commonLibrary/util.cc
  100. +85 −0 include/global.h
  101. +19 −0 include/hashPointer.h
  102. +24 −0 include/hashString.h
  103. +17 −0 include/hash_mapWrapper.h
  104. +14 −0 include/istreamWrapper.h
  105. +14 −0 include/lineToArgv.h
  106. +16 −0 include/localeWrapper.h
  107. +31 −0 include/misc.h
  108. +350 −0 include/netString.h
  109. +14 −0 include/ostreamWrapper.h
  110. +137 −0 include/pluton/client.h
  111. +63 −0 include/pluton/clientEvent.h
  112. +81 −0 include/pluton/clientRequest.h
  113. +97 −0 include/pluton/client_C.h
  114. +46 −0 include/pluton/common.h
  115. +146 −0 include/pluton/fault.h
  116. +81 −0 include/pluton/service.h
  117. +47 −0 include/pluton/service_C.h
  118. +16 −0 include/processExitReason.h
  119. +34 −0 include/rateLimit.h
  120. +71 −0 include/reportingChannel.h
  121. +12 −0 include/serviceAttributes.h
  122. +82 −0 include/serviceKey.h
  123. +45 −0 include/shmLookup.h
  124. +101 −0 include/shmLookupPrivate.h
  125. +239 −0 include/shmService.h
  126. +15 −0 include/stdintWrapper.h
  127. +16 −0 include/streambufWrapper.h
  128. +95 −0 include/util.h
  129. +8 −0 include/version.h
  130. +57 −0 install.sh
  131. +60 −0 make.config
  132. +42 −0 manager/Makefile
  133. +33 −0 manager/bitmask.cc
  134. +24 −0 manager/bitmask.h
  135. +350 −0 manager/calibrateProcesses.cc
  136. +451 −0 manager/commandPort.cc
  137. +32 −0 manager/commandPort.h
  138. +297 −0 manager/configParser.cc
  139. +43 −0 manager/configParser.h
  140. +49 −0 manager/debug.cc
  141. +51 −0 manager/debug.h
  142. +12 −0 manager/listenBacklog.cc
  143. +27 −0 manager/listenBacklog.h
  144. +66 −0 manager/listenBacklog_kqueue.cc
  145. +38 −0 manager/listenBacklog_st.cc
  146. +116 −0 manager/listenInterface.cc
  147. +27 −0 manager/listenInterface.h
  148. +401 −0 manager/loadConfigurations.cc
  149. +42 −0 manager/logging.cc
  150. +44 −0 manager/logging.h
  151. +388 −0 manager/manager.cc
  152. +161 −0 manager/manager.h
  153. +120 −0 manager/periodicReports.cc
  154. +80 −0 manager/pidMap.cc
  155. +23 −0 manager/pidMap.h
  156. +313 −0 manager/plutonManager.cc
  157. +923 −0 manager/process.cc
  158. +144 −0 manager/process.h
  159. +863 −0 manager/service.cc
  160. +220 −0 manager/service.h
  161. +41 −0 manager/serviceConfig.h
  162. +193 −0 manager/shmLookupWriter.cc
  163. +238 −0 manager/shmServiceWriter.cc
Sorry, we could not display the entire diff because too many files (470) changed.
590 Docs/FAQ.html
@@ -0,0 +1,590 @@
+<html>
+<head>
+<link rel="shortcut icon" href=images/pluto-symbol.jpg type="image/x-icon">
+<title>
+The Pluton Framework: Client API
+</title>
+</head>
+
+<body>
+
+<center>
+<a href=index.html>
+<img height=100 src=images/pluto-charon.jpg ALT="[Pluto Charon Image]">
+</a>
+</center>
+
+<h2 align=center>The Pluton Framework: FAQ</h2>
+
+
+<h3>General/Philosophical</h3>
+
+<a href=#G1>G1: Can a service be too small?</a>
+<br><a href=#G2>G2: What serialization-type is best?</a>
+<br><a href=#G3>G3: Are there any issues with exchanging large
+amounts of data between clients and services?</a>
+
+<br><a href=#G99>G99: <i>It</i> doesn't work - what should I do?</a>
+
+<h3>Client API</h3>
+
+
+<a href=#C1>C1: Can you put response times into the requests so I
+can see how long a service takes?</a>
+<br><a href=#C2>C2: Is the client library thread-safe?</a>
+<br><a href=#C3>C3: Is it possible to <i>fire and forget</i> with Pluton?</a>
+
+<h3>Service API</h3>
+
+<a href=#S1>S1: How do I test a service independently of the manager?</a>
+<br><a href=#S2>S2: Should services be stateless?</a>
+<br><a href=#S3>S3: How do multiple clients avoid contention when
+accessing a service?</a>
+<br><a href=#S4>S4: Does a service have to be a stand-alone executable?</a>
+<br><a href=#S5>S5: How do I run a scripting language service written in
+ perl or PHP?</a>
+
+
+<h3>Manager</h3>
+
+<a href=#M1>M1: What user does a service normally run as?</a>
+<br><a href=#M2>M2: What happened to M2?</a>
+<br><a href=#M3>M3: When should I need to kill the manager?</a>
+<br><a href=#M4>M4: How do I stop/start/restart the manager?</a>
+<br><a href=#M5>M5: Why does the manager take so long to shut down?</a>
+<br><a href=#M6>M6: How do I find out what the manager is doing?</a>
+<br><a href=#M7>M7: The manager appears not to have started - why not?</a>
+<br><a href=#M8>M8: How do I manually run the <code>plutonManager</code>?</a>
+<br><a href=#M9>M9: Why does the manager take so long to start?</a>
+
+<h3>Configurations</h3>
+
+
+<h3>General/Philosophical</h3>
+
+<a name=G1>
+<h4>G1: Can a service be too small?</h4>
+
+Yes. The benefit to making a function into a separate service revolves
+around latency, frequency-of-use and resource usage. If a function has
+low latency, is invoked very frequently and consumes few resources, it
+is not a great candidate for making into a service.
+
+<p>As a rule of thumb, if a function consumes less than 10
+milliseconds of latency or CPU, then it is not likely to be
+significant enough to make into a service.
+
+<p>There are many exceptions though, for example if you need process
+isolation due to segfault-inducing bugs or resource leaks, then you
+might make a function into a separate service, even though there are
+no latency benefits.
+
+<a name=G2>
+<h4>G2: What serialization-type is best?</h4>
+
+There is no right answer to this question, apart from "it depends". In
+general, you should use a serialization type that works well with the
+programming environment you are using. There is rarely much point in
+using a non-native serialization type if that imposes heavy conversion
+costs at each end of the service.
+
+<p>Service output that is ultimately destined for Javascript programs
+can often benefit from the JSON format as Javascript programs can
+instantiate objects directly from JSON. Conversely, PHP serialization
+might be right for a heavy PHP environment. It all depends.
+
+<p>Obvious exceptions include company-wide standardization requirements and the
+convenience of consistency of a common serialization.
+
+<a name=G3>
+<h4>G3: Are there any issues with exchanging large
+amounts of data between clients and services?</h4>
+
+The main two issues to consider are that the data has to travel
+through a local socket so there is a transfer cost and the request and
+response has to fit in memory for the client and service.
+
+<p>Apart from that, there are no limitations intrinsic to the system.
+
+<a name=G99>
+<h4>G99: <i>It</i> doesn't work - what should I do?</h4>
+
+For some value of <i>"it"</i>, the most important thing to do is
+understand what isn't working exactly. Even if you can't fix your
+problem, having concise information makes it much easier for others
+to help you.
+
+<p>
+The typically diagnostic process includes the following:
+<ol>
+<li>Check that
+<a href=commands.html#plPing><code>plPing</code></a>
+runs
+
+<li>Make sure daemontools and the plutonManager are running (<a
+href=#M7>M7</a> and <a href=#M8>M8</a>)
+
+<li>Check that the Manager is making periodic entries to the
+log (<a href=#M6>M6</a>)
+
+<li>Ensure that all the permissions and ownership values of all
+entries in
+<code>/usr/local/var/pluton</code> match those of a working instance
+on another machine. They should look like this:
+
+<pre>
+$ ls -lRa /usr/local/var/pluton
+
+/usr/local/var/pluton:
+total 16
+drwxr-xr-x 3 puser wheel 4096 Jun 13 10:04 .
+drwxr-xr-x 13 root root 4096 May 19 13:41 ..
+-r--r--r-- 1 puser users 278 Jun 13 10:04 lookup.map
+drwxr-xr-x 2 puser wheel 4096 Jun 13 10:04 rendezvous
+
+/usr/local/var/pluton/rendezvous:
+total 20
+drwxr-xr-x 2 puser wheel 4096 Jun 13 10:04 .
+drwxr-xr-x 3 puser wheel 4096 Jun 13 10:04 ..
+-rw-r--r-- 1 puser users 4365 Jun 13 10:04 system.curl.0.raw.mmap
+srw-rw-rw- 1 puser users 0 Jun 13 10:04 system.curl.0.raw.socket
+-rw-r--r-- 1 puser users 4365 Jun 13 10:04 system.echo.0.raw.mmap
+srw-rw-rw- 1 puser users 0 Jun 13 10:04 system.echo.0.raw.socket
+</pre>
+
+<li>Make sure your service executable runs in the relatively pristine
+environment created by the plutonManager.
+<a href=commands.html#plTest><code>plTest</code></a>
+is a good tool to test out your service.
+
+</ol>
+<p>
+
+If, after all those steps, you are still no closer to understanding
+the problem, you should collect the information you gathered during
+this and ask the folk on the github.com list.
+
+
+
+<h3>Client API</h3>
+
+<a name=C1><h4>C1: Can you put response times into the requests so I
+can see how long a service takes?</h4>
+
+Tracking the response time of a request could be added to the client
+API, but you should know that the manager produces periodic reports on
+the response times of services. Average response time, slowest 10
+responses, CPU used per request, memory size, etc. The idea is that
+you can slurp these standardized reports into a database/spreadsheet
+and analyze the performance of every service over time.
+
+<p>
+Also, this sort of functionality can be easily achieved by the caller
+tracking response times thus:
+
+<p>
+<pre>
+ addRequest(R1);
+ addRequest(Rn);
+
+ struct timeval startTime;
+ gettimeofday(startTime, 0);
+ while (pluton::clientRequest R = client::executeAndWaitAny()) {
+ struct timeval now;
+ gettimeofday(now, 0);
+ calculate_response_time(R, start, now);
+ }
+
+</pre>
+
+If you simply want to know how long service takes on an ad
+hoc basis, you might want to try the <code>-e</code> option for the <a
+href=commands.html#plSend><code>plSend</code></a> command.
+
+<a name=C2><h4>C2: Is the client library thread-safe?</h4>
+<p>
+As of version 0.50 and later, the C++ client library is reentrant and
+can be used by threads if the application follows a number of rules as
+described in the <a href=threading.html>thread interface</a> document.
+
+<p>As a precaution, the client library tracks re-entrant call attempts that do
+not follow the rules via a <i>oneAtATime</i>-type flag and will generate
+an<code>assert()</code> failure if it detects re-entrant call attempts or other
+catastrophic call sequences. The <code>assert()</code> message looks something
+like one of these:
+
+<pre>
+perCallerClient.cc:66: failed assertion `_oneAtATimePerCaller == false'
+
+clientImpl.cc:75: failed assertion `_oneAtATimePerThread == false'
+</pre>
+
+<a name=C3><h4>C3: Is it possible to <i>fire and forget</i> with Pluton?</h4>
+
+By "fire and forget" if you mean to initiate a service and then not
+have to wait for the result, then sure, set the
+<a href=clientAPI.html#noWaitAttr><code>noWaitAttr</code></a>
+attribute on the request.
+
+<p>There are two caveats with using the
+<a href=clientAPI.html#noWaitAttr><code>noWaitAttr</code></a>
+attribute:
+
+<ul>
+<li>The <i>no wait</i> means no waiting for the <i>response</i> from the
+service. The client still waits until the request is sent to
+the socket buffer connected to the service instance. This means that
+the client still waits until there is a free service instance.
+
+<li>The only guarantee is
+that all of the request is sent to the service, whether the service
+even reads the complete request or whether it is
+able to complete the request is, naturally, unknown, unless the client
+and service communicate thru a side-channel of some sort.
+</ul>
+
+<h3>Service API</h3>
+
+<a name=S1>
+<h4>S1: How do I test a service independently of the manager?</h4>
+
+<p>Testing a service independently of the manager is easy and
+encouraged. There are a number of ways you can do this and it's an
+easy way to build regression tests and to verify your service in the
+early stages of development.
+
+If you are new to Pluton then you mind want to read
+<a href=howToTestService.html>How to Test Your Service</a>
+which goes into much greater detail than this FAQ entry.
+
+<p>
+If you just need a refresher, then recall that the
+<a href=commands.html#plTest><code>plTest</code></a>
+program runs services independently of the manager and generates
+requests from STDIN.
+
+<p>
+Second, if you have recorded requests for this service, then the
+service can be run from the command line by setting up fd3 as the
+input request packet and arranging the output of fd4 to be the
+response packet. This technique is commonly referred to as the
+<i>file-descriptor-redirect</i> technique.
+<p>
+<pre>
+$ /path/service 3&lt;requestFile 4&gt;responseFile
+</pre>
+This technique is particularly useful if you need to run the service
+under a debugger such as <code>gdb</code>.
+
+<p>
+If you want to feed a service a request packet from STDIN and have
+the response packet written to STDOUT, you can use this style
+of redirection:
+<p>
+<pre>
+$ /path/service 3&lt;&amp;0 4&gt;&amp;1
+</pre>
+
+<a name=S2><h4>S2: Should services be stateless?</h4>
+
+Services are normally stateless - think of them as a super
+light-weight web-services. Having said that, a recent enhancement
+request resulted in the <code>affinity</code> attributes which allows
+a client to persist a connection once established so they can get back
+to the same service instance on each subsequent request.
+
+<p>It's not clear that <code>affinity</code> is entirely consistent
+with the spirit of the original idea, but the customer is always
+right!
+
+<a name=S3><h4>S3:How do multiple clients avoid contention when
+accessing a service?</h4>
+
+Within the constraints of the <a href=configuration.html>service
+configuration</a>, the <a
+href=plutonManager.html><code>plutonManager</code></a> manages the
+number of service instances dynamically. Client's block on an
+connect() to a Unix Socket until an instance becomes free. Well, they
+block until the timeout expires.
+
+<p>The service API automatically reports concurrency and response
+times to the manager so the manager knows how busy the aggregate pool
+of service instances are. In fact, that's the primary purpose of the
+manager; to manage the pool of services and track resource usage.
+
+<p>Each service is managed as a separate pool - there is no
+relationship between separately configured services.
+
+<a name=S4><h4>S4: Does a service have to be a stand-alone
+executable?</h4>
+
+Yes. The per-process encapsulation is one of the key design principles
+of Pluton as it enables:
+
+<ul>
+<li>Automatic resource monitoring by the plutonManager
+<li>Fault isolation
+<li>Ease of debugging with gdb or similar
+<li>Memory corruption isolation, etc
+</ul>
+
+<p>The manager is largely passive as all it does is a fork/exec
+sequence to create service instances and arrange a few file
+descriptors for the service API.
+
+<a name=S5><h4>S5: How do I run a scripting language service written in perl or PHP?</h4>
+
+(Note: this is actually a general discussion that applies running any
+scripting language program in a Unix environment).
+
+<p>Scripting languages
+need to invoke their interpreter to be run and this can be done in one of
+two ways. Either the script is supplied as a command line argument to
+the interpreter, eg:
+
+<p>
+<code>
+$ php myprogram.php
+</code>
+<p>
+
+or the script is converted into a <i>self-invoking executable</i> with the
+following steps:
+
+<ol>
+<li>Add the path to the interpreter as the first <code>#!</code> line of the
+script, eg:
+<p>
+<code>
+#! /usr/local/bin/php
+<br>
+&lt;?php
+<br>
+..
+</code>
+<li>Change the file mode of the script file to be executable
+
+<p>
+<code>
+$ chmod +x myprogram.php
+</code>
+</ol>
+
+<p>
+(The <code>#!</code> magic is standard across all Unixen).
+<p>
+Once that is done, you run your script program as a regular executable
+from the shell prompt, eg:
+
+<p>
+<code>
+$ ./myprogram.php
+</code>
+
+<p>
+<h5>Scripting languages in service configuration</h5>
+
+This discussion applies for service executables when
+run via a service configuration. Recall that the
+ <a href=configuration.html#exec><code>exec</code></a>
+ line in the service
+configuration must point to an executable; this means that you can
+either run the interpreter directly, eg:
+<p>
+<code>
+exec /usr/local/bin/php path-to-your-script
+</code>
+</p>
+
+or turn your script into a <i>self-invoking executable</i> as described above
+and supply it directly in the
+ <a href=configuration.html#exec><code>exec</code></a>
+ line, eg:
+
+<p>
+<code>
+exec path-to-your-script
+</code>
+
+<h5>Scrpting languages and the
+<a href=commands.html#plTest><code>plTest</code></a> command</h5>
+
+This discussion also applies to testing scripting languages services
+with plTest; either invoke the scripting command directly, eg:
+
+<p>
+<code>
+$ plTest php myprogram.php
+</code>
+<p>
+or turn the script into a <i>self-invoking executable</i> and run it
+directly, eg:
+
+<p>
+<code>
+$ plTest ./myprogram.php
+</code>
+<p>
+
+
+<h3>Manager</h3>
+
+<a name=M1>
+<h4>M1: What user does a service normally run as?</h4>
+
+The service processes inherit the user credentials from the
+plutonManager. With a normal installation that will be the user
+'puser.
+
+<a name=M2>
+<h4>M2: What happened to M2?</h4>
+
+It got morphed and moved to <a href=#S6>S6</a>.
+
+<a name=M3>
+<h4>M3: When should I need to kill the manager?</h4>
+
+Generally, the answer is never. Recall that the manager plays a
+passive role in the client-to-service interaction so it is the
+services that are more likely to require restarting.
+
+<p>The normal action is to signal the manager to reload the
+configuration with the <code><a
+href=commands.html#plReloadManager>plReloadManager</a></code>
+command. In this case it will scan the configuration directory for any
+changes and replace changed services.
+
+<a name=M4>
+<h4>M4: How do I stop/start/restart the manager?</h4>
+
+The plutonManager is run as a <i>supervised</i> process so the usual
+<code>svc</code> invocations are available.
+
+<a name=M5>
+<h4>M5: Why does the manager take so long to shut down?</h4>
+
+After being signaled to shut down or restart, the manager tries to
+shut down all active services in an orderly manner. To achieve this,
+the manger issues a series of increasing aggressive signals to each
+service process until they exit or until the manager runs out of
+escalation options (the last being kill -9).
+
+<p>This orderly shutdown can take some time to complete as the manager
+assumes that a service may be currently processing a request and
+prefers to give it time to complete - within reason. In short please
+be patient with the slow nature of the shutdown.
+
+<p>Watching the manager log is instructive in terms of shut down
+progress. The next FAQ entry discusses logging.
+
+<a name=M6>
+<h4>M6: How do I find out what the manager is doing?</h4>
+
+The manager writes a relatively extensive log to
+<code>/usr/local/logs/pluton_manager/current</code>. This log file can me
+monitored with the following command:
+
+<pre>
+tail -F /usr/local/logs/pluton_manager/current | /usr/local/bin/tai64nlocal
+</pre>
+
+Many of these log entries are documented on <a href=logs.html>this</a>
+page. In addition, the types of log entries being generated can be
+changed dynamically via the <a
+href=plutonManager.html#CommandPort>Command Port</a>.
+
+<a name=M7>
+<h4>M7: The manager appears not to have started - why not?</h4>
+
+There are numerous reasons why the manager may not have started,
+ranging from installation issues to people <i>helpfully</i> modifying
+files and permissions in <code>/usr/local/var/pluton</code> - of course you
+should never do this
+unless you are absolutely sure of the implications.
+
+<a name=M8>
+<h4>M8: How do I manually run the <code>plutonManager</code>?</h4>
+
+If the manager appears not to be running or you suspect a problem with
+<code>daemontools</code>, you may want to run the
+manager manually to help diagnose the problem.
+
+<p>
+To run the manager manually, first make sure that the manager truly is
+not running via <code>ps</code> or similar. Then, as root, run this
+command:
+
+<pre>
+sh -x /usr/local/var/daemontools/plutonManager/run
+</pre>
+<p>
+at which point you should see the output of the manager on your screen.
+
+<a name=M9>
+<h4>M9: Why does the manager take so long to start?</h4>
+
+Or put another way: if a service is called immediately after the
+manager is started, the client can sometimes get a timeout, why is
+this?
+
+<p>
+There is usually a delay of a couple of seconds after the manager has
+been told to start before services are available. There are two main
+reasons for this.
+
+<p>
+First, the manager is itself typically managed by
+<a href=http://cr.yp.to/daemontools.html>daemontools</a>
+which only scans for new services every 5 seconds. Thus it could
+take up to 5 seconds after yinst start before daemontools notices the
+manager entry and starts it up.
+
+<p>
+Second, the startup script of the manager first runs
+the <code>plKillOldServices</code> command which cleans up the shared
+directories and any residual services that might be running. This
+latter process involves a kill/sleep/check loop which could take
+another 5 seconds or so to complete, though a normal restart after a
+normal shutdown will should not incur any delay here.
+
+<p>
+Due to <code>daemontools</code> the manager is normally started
+once when the system is booted and remains running until it
+reboots. In other words, manager restarts are rare events.
+
+<p>As a final note, installing new services (or new versions of a
+service) should not normally require restarting the manager. Rather,
+the right strategy is two either:
+
+<p>
+<ol>
+<li>Replace the service executable/file
+<li>Update the service config file (a touch does the trick)
+<li>run
+ the <a href=commands.html#plReloadManager><code>plReloadManager</code></a>
+ command which causes the manager to scan the configuration directory
+ for changes
+</ol>
+<p>
+or, in a development environment you can be lazier and go:
+
+<ol>
+<li>Replace the service executable
+<li>killall old instances of the service
+</ol>
+
+<p>
+which means that all future instances of that service can only
+possibly be the newly installed executable.
+
+
+
+<h3>Configurations</h3>
+
+<hr>
+<font size=-1>
+$Id: FAQ.html 263341 2009-11-26 17:35:13Z markd $
+&copy; Copyright Yahoo! Inc, 2007, 2008
+</font>
+</body>
+</html>
54 Docs/about.html
@@ -0,0 +1,54 @@
+<html>
+<head>
+<link rel="shortcut icon" href=images/pluto-symbol.jpg type="image/x-icon" />
+<title>
+About the Pluto-Charon Image
+</title>
+</head>
+
+<body>
+
+<center>
+<a href=index.html>
+<img src=images/pluto-charon.jpg ALT="[Pluto Charon Image]">
+</a>
+</center>
+
+<h2 align=center>About the Pluto-Charon Image</h2>
+
+This <a
+href=http://www.nasa.gov/worldbook/pluto_worldbook.html>NASA</a> image
+of Pluto and Charon was taken with the Hubble Space Telescope using
+the European Space Agency's <i>Faint Object Camera</i> or FOC. It is
+currently one of the best images available and is unlikely to be
+substantially supplanted until 2015 when the <a
+href=http://pluto.jhuapl.edu/>New Horizons probe</a>, launched in
+January 2006, is expected to fly by Pluto en-route to the Kuiper Belt.
+
+<p>Pluton <i>was</i> the proposed name for trans-Nepturian objects -
+though geologists have long used this word to mean a body of igneous
+rock. The notion of a gaggle of small planetoids revolving around a
+set of central applications seems to fit with the application model
+described here-in.
+
+<h4>Quotes from <a href=http://pluto.jhuapl.edu>The John Hopkins
+ University Applied Physics Laboratory</a> News Desk</h4>
+
+<h5><a href=http://pluto.jhuapl.edu/news_center/news/20090708.php>
+8 July, 2009</a></h5>
+
+"New Horizons is now 1.19 billion miles (nearly 1.92 billion
+kilometers) from Earth, speeding away from the Sun at just over 10
+miles per second. At that distance, radio signals (traveling at light
+speed) from home need an hour and 46 minutes to reach the
+spacecraft."
+
+
+<p>
+<hr>
+<font size=-1>
+$Id: about.html 263341 2009-11-26 17:35:13Z markd $
+&copy; Copyright Yahoo! Inc, 2007, 2009
+</font>
+</body>
+</html>
609 Docs/background.html
@@ -0,0 +1,609 @@
+<html>
+<head>
+<link rel="shortcut icon" href=images/pluto-symbol.jpg type="image/x-icon" />
+<title>
+The Pluton Framework: Background
+</title>
+</head>
+
+<body>
+
+<center>
+<a href=index.html>
+<img height=100 src=images/pluto-charon.jpg ALT="[Pluto Charon Image]">
+</a>
+</center>
+
+<h2 align=center>The Pluton Framework: Background and Motivation</h2>
+
+<p>
+<ul>
+<li><a href=#Introduction>Introduction</a>
+<ul>
+<li><a href=#networkEffectProblem>Network Effect Problem</a>
+<li><a href=#latencyProblem>The Latency Problem</a>
+<li><a href=#weakestLinkProblem>The Weakest Link Problem</a>
+<li><a href=#additionalProblems>Additional Problems</a>
+</ul>
+
+<li><a href=#Architecture>Architecture Overview</a>
+<ul>
+<li><a href=#plutonManager>The plutonManager</a>
+<li><a href=#Services>Services</a>
+<li><a href=#Clients>Clients</a>
+<li><a href=#Rendezvous>Rendezvous Sockets</a>
+<li><a href=#Lookup>Service Naming, Service Keys and Lookup Table</a>
+<li><a href=#Reporting>Reporting Sockets</a>
+</ul>
+
+<li><a href=#Together>Putting it all together</a>
+<li><a href=#Serialization>Application Serialization</a>
+<li><a href=#Benefits>Benefits</a>
+<li><a href=#Performance>Performance</a>
+</ul>
+
+<a name=Introduction>
+<h3>Introduction</h3>
+</a>
+
+Pluton is a framework which can help make web applications
+light-weight, easy to debug, faster <em>and</em> potentially less
+resource intensive.
+
+<p>
+A number of conspiring factors have resulted in many web applications
+becoming large, unwieldy, brittle and slow. These factors include the
+network effect problem, the latency problem and the weakest link
+problem.
+
+The primary goal of the Pluton Framework is to make it possible to
+replace these large, brittle web applications with smaller, flexible
+applications which use co-operative, independent services.
+
+
+<h4><a name=networkEffectProblem>The Network Effect Problem</h4>
+
+A key feature of modern web applications is that they combine data
+from numerous sources to render a rich experience. One meaning of
+<em>network effect</em> is to take advantage of a related set of
+content sources to provide a more comprehensive experience.
+
+Consider a calendar application which might consult multiple calendars
+to present an aggregate view; or an address book application which
+might want to include online presence indication; or a portal-type
+page which might render calendar status, online presence, ads, local
+weather and news headlines.
+
+<p>
+From a user perspective, combining different data sources provides a
+richer experience, but it comes at a significant increase in
+application complexity which implies more code, a bigger footprint and
+many more library dependencies.
+
+<p>
+By dividing the application into smaller, self-contained services, the
+complexity is substantially reduced as each service can be tested,
+debugged and tuned independently of each other and the main application.
+
+
+<h4><a name=latencyProblem>The Latency Problem</a></h4>
+
+Feature rich web applications often collect data from a variety of
+external data sources. Typically, access to these data sources
+involves a series of comparatively high-latency network requests which
+in aggregate can add up to a lot of user-visible delay. Consider just
+five remote data sources at 30ms each? This adds up to a distinctly
+visible 150ms of delay.
+
+<p>
+The Pluton Framework provides an easy and safe way to issue multiple
+requests in parallel such that the aggregate latency is reduced to the
+duration of the slowest request, not the sum of all requests. Within
+the Pluton Framework, those five remote requests could potentially all
+complete within an aggregate latency of just 30ms.
+
+
+<h4><a name=weakestLinkProblem>The Weakest Link Problem</a></h4>
+
+A large monolithic web application typically includes many independent
+libraries. If any one of those libraries has a memory corruption bug,
+a resource leak or a performance problem, it affects the whole
+application. Sometimes catastrophically such as randomly dumping core
+or getting stuck in some CPU loop.
+
+<p>
+If an application includes, say, ten libraries (a very small number by
+current standards), then you only need one bug in one of those ten
+libraries to cause the application to fail. Essentially, each
+additional library increases the probability of an application failure
+through no fault of the application program. To make matters worse,
+even if the current set of libraries happen to be bug-free, some
+future version may not be as well behaved, causing a previously stable
+and unchanged application to mysteriously start failing.
+
+<p>
+By encapsulating separate functions in self-contained execution
+units, bugs are contained within the encapsulated executable which protects
+the main application and makes it much easier to isolate the location
+of the fault.
+
+
+<h4><a name=additionalProblems>Additional Problems</a></h4>
+
+Above and beyond the main problems identified above, there are
+numerous, well-known disadvantages to monolithic web applications. These
+include:
+
+<ul>
+<li>Difficult performance analysis - time consuming instrumentation is
+often required to find a slow piece of functionality
+<li>Unwieldy core dumps - large executables create large core files
+<li>Difficult to debug - the inclusion of debugging symbols is outside of
+your control
+<li>Difficult to regression test - each API requires a separate and
+different regression test program
+<li>Difficult to isolate unexpected changes in behavior
+<li>Library version conflicts increases exponentially with the number
+of libraries
+</ul>
+
+Many of these difficulties are substantially reduced in the Pluton Framework.
+
+<a name=Architecture>
+<h3>Architecture Overview</h3>
+</a>
+
+The Pluton Framework consists of:
+
+<ol>
+<li>a <a href=configuration.html>configured</a> set of self-contained,
+stand-alone service executables which accept requests and send
+responses
+
+<li>the <a href=plutonManager.html>plutonManager</a> - a long-running
+daemon which manages service instances and their rendezvous sockets
+
+<li>a simple <a href=clientAPI.html>client API</a> to
+issue service requests in parallel
+
+<li>a simple <a href=serviceAPI.html>service API</a> to connect
+service programs to their corresponding rendezvous socket
+
+<li>a file-system based naming convention for service discovery
+</ol>
+
+<p>
+The following diagram shows the relationship between the major
+components and an application.
+<p>
+<center>
+<a href=images/plutonOverview1.jpg>
+<img border=1 height=400 src="images/plutonOverview1.jpg" ALT="[Overview 1]">
+</a>
+<p><font size=-1>(Click on image for a larger version).</font>
+</center>
+<p>
+Admittedly, this diagram suggests a complex set of interactions,
+however these are largely required for management functions, the
+interaction between the client and services is very simple with all
+management functions completely contained within the APIs.
+
+
+<h4><a name=plutonManager>The plutonManager</a></h4>
+
+The plutonManager is a long-running daemon which is responsible for
+managing all of the components except the client applications. For each
+configured service, the plutonManager:
+
+<ul>
+<li>creates the service Rendezvous Socket
+<li>adds a "Service Key to Rendezvous Socket" entry in the shared
+memory Lookup Table
+<li>creates the service Reporting Socket
+<li>forks and execs the service instances
+<li>monitors and logs performances statistics automatically generated
+by each service instance
+</ul>
+
+The plutonManager dynamically adjusts the number of service instances
+based on configuration limits, application demand and a number of
+performance factors. The competing goals are to provide sufficient service
+instances to maximize request concurrency while minimizing excess
+capacity and system impact.
+
+<p>One of the most important roles of the plutonManager is to generate
+a consistent set of performance log entries which can be used to analyze
+service performance over time. The log entries include:
+
+<ul>
+<li>Average elapse-time per request
+<li>Total Memory size on exit
+<li>Total CPU used on exit
+<li>Total number of successful requests
+<li>Total number of fault requests
+<li>A short list of the slowest elapse times
+</ul>
+
+This information is purposely amenable to parsing and storage in a
+database which can then be used to trend the performance of a service
+over time and over new releases.
+
+
+<h4><a name=Services>Services</a></h4>
+
+Services are stand-alone executable programs written for the
+framework. Services use the <a href=serviceAPI.html>service API</a> to
+accept requests and send responses. A service program is largely
+oblivious to the fact that it is running within this framework.
+
+<p>
+All services are implemented as a loop. Here is a skeletal "Hello
+World" service which demonstrates this loop:
+<p>
+
+<center>
+<table border=1>
+<td>
+<pre>
+ #include &lt;pluton/service.h&gt;
+
+ int
+ main(int argc, char** argv)
+ {
+ pluton::service S;
+ pluton::serviceRequest R;
+
+ S.initialize();
+
+ while (S.getRequest(R)) {
+ S.sendResponse("Hello Worlds, all eight of you!");
+ }
+
+ S.terminate();
+
+ return(0);
+ }
+</pre>
+</table>
+</center>
+
+<p>
+If you want to be lazy about checking for errors, this is literally
+all the code you need to create a service. Oh, and obviously you'll
+need some code which actually does something useful, but that's your
+problem...
+
+<p>
+Some basic attributes of service programs:
+
+<ul>
+
+<li>Connections to databases or remote services should be established
+just once and prior to calling
+<code>pluton::service::initialize()</code>. Henceforth, if any error
+occurs, a service program should simply exit. The manager is
+responsible for re-starting a new instance.
+
+<p><li>Services are expected to perpetually iterate on the
+<code>getRequest()</code> method to amortize their creation and initialized costs
+across many requests. Normally the decision to exit is made by the
+plutonManager and service API. This decision is indicated to the
+service via a false return from <code>getRequest()</code>.
+
+
+<p><li>Services should not overly concern themselves with managing
+timeouts to meet client response-time requirements. The client API
+manages this aspect of the exchange.
+
+<p><li>Services should be written as single-threaded, serial request
+processors. All parallelism is achieved by multiple instances of a
+service.
+
+</ul>
+
+Generally speaking, service programs should be simple and perform just
+one function or a set of common functions.
+
+
+<h4><a name=Clients>Clients</a></h4>
+
+Clients use the <a href=clientAPI.html>client API</a> to exchange
+requests with services. A key feature of the client API is that
+multiple service requests can be issued concurrently which greatly
+reduces aggregate latency. In fact multiple requests to the same
+service can similarly be issued in parallel - then all such requests
+are processed in parallel within the constraint of available services
+and system resources.
+
+<p>
+Unlike services, the Pluton Framework does not imply an implementation
+model for clients. This is <em>the</em> area where the programmer need
+to be creative; they should think about which functions can be
+encapsulated as a service and they should think about which services
+can be requested in parallel by the application.
+
+Generally speaking,
+a well designed client is one which maximizes the benefits of the
+Pluton Framework.
+
+<p>
+For those interest, <a href=sampleClient.html>here</a> is a sample
+client program intended to give an idea of how the client API can be
+used - it does not represent the archetypal client. The most salient
+point to note is that the sample client makes two service requests in
+parallel it then waits for all requests to complete. Other
+<code>pluton::client</code> methods allow waiting for one, any or no
+requests to complete prior to returning to the caller.
+
+
+<h4><a name=Rendezvous>Rendezvous Sockets</a></h4>
+
+Each service exchanges requests via a unique Unix Domain socket -
+called a Rendezvous Socket in pluton parlance.
+
+<p>
+The client API discovers the path to the Rendezvous Socket via the
+Lookup Table and connects to that socket to exchange the request. The
+plutonManager is responsible for managing the existence of Rendezvous
+Sockets but is not involved in the actual exchange of data.
+
+<p>
+Rendezvous Sockets are transparent to clients and
+services - at least for the reason that they conceivably may be replaced with a more efficient
+message-passing system - should one somehow spring into existence.
+
+
+<h4><a name=Lookup>Service Naming and Lookup Table</a></h4>
+
+Clients gain access to a service by their Service Key. The Lookup
+Table is a shared-memory structure which maps Service Keys to
+the path of Rendezvous Sockets. At the time of writing, the exact syntax of
+Service Keys is still under discussion, but the current thinking is
+along the lines of a dot separated set of tokens as follows:
+
+<pre>
+ <a href=serviceKey.html>Application.Function.Version.Serialization</a>
+</pre>
+
+where <code>Function</code> can be empty to indicate a wild-card. The
+Lookup Table provides an efficient means of resolving wild-card
+lookups. Example Service Keys are:
+
+<pre>
+ Mail.GetFolderList.1.XML
+or
+ AddressBook.AddEntry.0.JSON
+</pre>
+
+If a service is configured as a wild-card, it is only used
+if a more specific Service Key does not exist. For example, if two
+services are configured as:
+
+<pre>
+ AddressBook..0.JSON
+and
+
+ AddressBook.AddEntry.0.JSON
+</pre>
+
+a client request to <code>AddressBook.AddEntry.0.JSON</code>
+resolves to the second service and <code>AddressBook.GetList.0.JSON</code>
+resolves to the first service.
+
+<p>
+If a service is configured with a wild-card entry, the service is
+responsible for <code>Function</code> verification and de-multiplexing.
+
+<p>
+
+(<em>Note to Reviewers:</em>
+<i>If wild-card lookups are deemed to be of no
+utility, the Lookup Table can be eliminated to reduce complexity and
+gain a tiny performance saving for clients).
+</i>
+
+
+<h4><a name=Reporting>Reporting Sockets</a></h4>
+
+Each service is provided with a Unix socket which is used by the
+service API to write performance data back to the plutonManager. The
+plutonManager uses this data to log aggregate statistics and to
+optimize the number of service instances.
+
+<p>
+As with Rendezvous Sockets, Reporting Sockets are similarly
+transparent to the service and managed by the client API
+and plutonManager.
+
+<a name=Together>
+<h3>Putting it all together</h3>
+</a>
+
+The Pluton Framework is conceptually straightforward. Services exist
+as stand-alone executables which listen for connections on their
+Rendezvous Socket. Clients use the API to discover and connect to
+these Rendezvous Sockets to exchange requests. The
+plutonManager's role is to create these Rendezvous Sockets and to
+manage the service instances. In summary:
+
+<ul>
+<li>
+Services and their Rendezvous Sockets are created for each configured
+service
+
+<p>
+<li>When a client makes a set of requests to services, the client API
+discovers the corresponding Rendezvous Sockets via the Lookup Table
+and asynchronously connects to each service to exchange the requests
+
+<p>
+<li>Services exchange requests via the service API which in turn exchanges
+them via the Rendezvous Socket
+
+<p>
+<li>The client and service APIs co-operate to ensure that timeouts on
+either side of the exchange do not stall indefinitely
+
+<p>
+<li>The service API periodically writes performance data to the
+plutonManager via the Reporting Socket. In turn the plutonManager uses
+this data to determine the appropriate number of instances and to
+log aggregate statistics so you can conduct trend analysis.
+
+</ul>
+
+Almost all of this is completely transparent to the application
+programs and is only relevant to the APIs and the plutonManager.
+
+<a name=Serialization>
+<h3>Application Serialization</h3>
+</a>
+
+The reader may be curious as to why no mention has thus far been made
+about the format of the data exchanged between clients and
+services. There is a reason for this: the Pluton Framework is
+serialization agnostic.
+
+<p>
+While the client and service APIs use a light-weight serialization to
+exchange the request data and context, the nature of the request data
+is entirely a matter for the application. Looking at this from a
+layering perspective, the Pluton Framework is more akin to a transport
+layer than a presentation layer.
+
+<p>
+Naturally clients and services need to agree on what
+serializations they exchange and indeed the service key naming convention
+enforces the use of a well-known serialization type. But this is
+only a convention which is intended to aid understanding.
+
+<p>
+There are a number of reasons for being serialization agnostic. First,
+there is no "one true serialization"; often-times an implementation
+language strongly favors one serialization over all others. Second,
+services may simply be proxies to remote services which already have a
+well-defined serialization. Third, new serializations are invented
+or introduced somewhat more frequently than might be imagined (or
+desired).
+
+<p>
+Imposing a conversion to an arbitrary serialization in these
+circumstances seems counter-productive - particularly as many
+conversions such as JSON to XML to JSON are not reliably reversible.
+
+<p>
+Agnosticism has a consequence, of course. Namely that application
+programmers remain responsible for choosing their own serialization
+and services normally need to verify requests against the agreed
+serialization. The choice of serialization is often not easy to make
+and the wrong choice can impose significant functional and performance
+constraints. The Pluton Framework absolves itself of any
+responsibility in this regard.
+
+<a name=Benefits>
+<h3>Benefits</h3>
+</a>
+So what does this framework give us? Apart for simple parallel
+processing, the key feature is that the client application is isolated
+from the vagaries of the service implementation. This isolation
+affords a panoply of benefits:
+
+<ul>
+<li>Language independence - the client application could be written in
+PHP and the service could be written in, say, Java.
+
+<p><li>Bug isolation - if the service has bugs, then the client is fully
+insulated from problems such as random memory corruption.
+
+<p><li>Resource leak isolation - if a service is leaking a resource,
+say, memory or file descriptors, the client is insulated from these
+lost resources.
+
+<p><li>Increased application stability - a failing service no longer
+implies a failing client application. The client can safely detect
+service failure and respond accordingly.
+
+<p><li>Easier resource monitoring - each service instance is resource
+monitored by the plutonManager. This means accurate resource and
+latency costs can be determined for each type of service. Importantly,
+trends can be identified with new releases of a service.
+
+<p><li>Easier unit testing and regression testing of
+services - depending on how the services is started, the service API
+runs in one of two modes. In <em>manager mode</em> the service is run as
+a process controlled by the plutonManager. In <em>stand-alone mode</em>
+the service is run just like any other executable from a shell script
+or the command-line, with requests and responses being supplied via
+fd3 and fd4 respectively.
+<p>
+In <em>stand-alone mode</em> running a service regression
+test can be as easy as re-directing a request file to the service program
+and re-directing the service response to an output file for comparison.
+
+<p>
+Here is an example of a regression test which runs the service
+in <em>stand-alone</em> mode:
+
+<center>
+<table border=1>
+<td>
+<pre>
+#! /bin/sh
+
+/somepath/myservice 3&lt;inputRequest 4&gt;actualResponse
+cmp -s expectedResponse actualResponse && echo Success || echo Failure
+</pre>
+</table>
+</center>
+
+<p>Hopefully the simplicity speaks for itself.
+
+<p><li>Easier prototyping - a service can first be implemented in an
+quick-to-write language and subsequently re-written in a
+quick-to-execute language as needed.
+
+<p><li>Less disruptive installations - a service executable can be
+upgraded or replaced completely transparently to the client
+application. In other words, client applications can benefit from
+a newly installed service executable without needing to re-start.
+</ul>
+
+<p>
+In general, the goal is to help you follow the Unix maxim of writing
+programs which "do one thing well", then mix and match them to suit.
+
+<a name=Performance>
+<h3>Performance</h3>
+
+The Pluton Framework comes at a cost. Each service request involves
+connecting to a Unix socket and exchanging request and response data
+between processes. Looking at just the raw cost of those exchanges,
+without including any application and service overhead - such as
+serialization - suggests that a single modern CPU (circa 2006) can
+execute around 8,000 medium-sized exchanges per second. The rate is
+linear to the size of the request and response data.
+
+<p>
+Put another way, if your web application accepts, say, 100 requests
+per second and averages 5 service requests per web request, the raw
+overhead approximates 5*100/8000ths of your CPU, or about 6%. On the
+commonly deployed hyper-threaded, dual CPU server, this overhead
+reduces to around 2% of aggregate CPU capacity.
+
+<p>On a more positive note, due to the ease of parallelization, the
+Pluton Framework is especially suited to the trend towards multi-core,
+multi-cpu systems.
+
+<p>
+While this level of overhead seems tolerable, be warned that the total
+overhead is usually dominated by the type of application serialization
+used and the size and complexity of the data exchanged.
+
+<p>
+<hr>
+<font size=-1>
+$Id: background.html 260483 2009-10-16 18:47:56Z markd $
+&copy; Copyright Yahoo! Inc, 2007, 2008
+</font>
+</body>
+</html>
85 Docs/catalog.html
@@ -0,0 +1,85 @@
+<html>
+<head>
+<link rel="shortcut icon" href=images/pluto-symbol.jpg type="image/x-icon">
+<title>
+The Pluton Framework: Service Catalog
+</title>
+</head>
+
+<body>
+
+<center>
+<a href=index.html>
+<img height=100 src=images/pluto-charon.jpg ALT="[Pluto Charon Image]">
+</a>
+</center>
+
+<h2 align=center>The Pluton Framework: Service Catalog</h2>
+
+
+<h3>system.</h3>
+
+<ul>
+<li><a href=#system.echo><code>system.echo..raw</code></a> echos request data back to the client
+<li><a href=#system.curl><code>system.curl..raw</code></a> fetches a URL much like the
+<code>curl</code> command
+</ul>
+
+<h3>Mail.</h3>
+
+<h3>AddressBook.</h3>
+
+
+
+<table border=1>
+<tr><th>Name<td>system.echo.0.raw</tr>
+
+<tr valign=top><th>Description<td>
+Echo the exact contexts of the request data back as response data. The
+contents are not examined by this service.
+</tr>
+
+<tr valign=top><th>Context Variables<td>
+<ul>
+<li>echo.sleepMS - if a positive integer, sleep for this many milliseconds
+<li>echo.log - if present, log activity to clog
+</ul>
+</tr>
+
+<tr valign=top><th>Request Data<td>any</tr>
+<tr valign=top><th>Response Data<td>Copy of Request Data</tr>
+
+</table>
+
+<p>
+
+<table border=1>
+<tr><th>Name<td>system.curl.0.raw</tr>
+
+<tr valign=top><th>Description<td>
+Fetch a URL, much as the <code>curl</code> command does.
+</tr>
+
+<tr valign=top><th>Context Variables<td>*none*</tr>
+
+<tr valign=top><th>Request Data<td>getopt syntax. This service
+supports a subset of getopt options provided by <code>curl</code> to
+perform header insertion and similar. In
+particular,
+<pre>
+ [-ihL] [-A UserAgent] [-b cookieValue] [-e referrer] [-H header] [-U UserPass] URL
+</pre>
+See the <code>curl</code> command for a description of these options.
+</tr>
+<tr valign=top><th>Response Data<td>Raw data returned from URL fetch</tr>
+
+</table>
+
+<p>
+<hr>
+<font size=-1>
+$Id: catalog.html 260483 2009-10-16 18:47:56Z markd $
+&copy; Copyright Yahoo! Inc, 2007
+</font>
+</body>
+</html>
844 Docs/cclientAPI.html
@@ -0,0 +1,844 @@
+<html>
+<head>
+<link rel="shortcut icon" href=images/pluto-symbol.jpg type="image/x-icon" />
+<title>
+The Pluton Framework: C Client API
+</title>
+</head>
+
+<body>
+
+<center>
+<a href=index.html>
+<img height=100 src=images/pluto-charon.jpg ALT="[Pluto Charon Image]">
+</a>
+</center>
+
+<h2 align=center>The Pluton Framework: C Client API</h2>
+
+<h3>Contents</h3>
+
+<ol>
+<li><a href=#Introduction>Introduction</a>
+<li><a href=#Sample>Sample Program</a>
+<li><a href=#Compilation>Compilation and Libraries</a>
+<li><a href=#ClientRequest>ClientRequest methods corresponding to <code>pluton::clientRequest</code></a>
+
+<ul>
+<li><a href=#requestNew>pluton_request_C_new</a>
+<li><a href=#requestDelete>pluton_request_C_delete</a>
+<li><a href=#requestReset>pluton_request_C_reset</a>
+<li><a href=#setRequestData>pluton_request_C_setRequestData</a>
+<li><a href=#setAttribute>pluton_request_C_setAttribute</a>
+<li><a href=#getAttribute>pluton_request_C_getAttribute</a>
+<li><a href=#clearAttribute>pluton_request_C_clearAttribute</a>
+<li><a href=#setContext>pluton_request_C_setContext</a>
+<li><a href=#getResponseData>pluton_request_C_getResponseData</a>
+<li><a href=#inProgress>pluton_request_C_inProgress</a>
+<li><a href=#hasFault>pluton_request_C_hasFault</a>
+<li><a href=#getFaultCode>pluton_request_C_getFaultCode</a>
+<li><a href=#getFaultText>pluton_request_C_getFaultText</a>
+<li><a href=#getServiceName>pluton_request_C_getServiceName</a>
+<li><a href=#setClientHandle>pluton_request_C_setClientHandle</a>
+<li><a href=#getClientHandle>pluton_request_C_getClientHandle</a>
+</ul>
+
+<li><a href=#Client>Client methods corresponding to <code>pluton::client</code></a>
+
+<ul>
+<li><a href=#clientNew>pluton_client_C_new</a>
+<li><a href=#clientDelete>pluton_client_C_delete</a>
+<li><a href=#clientReset>pluton_client_C_reset</a>
+<li><a href=#getAPIVersion>pluton_client_C_getAPIVersion</a>
+<li><a href=#initialize>pluton_client_C_initialize</a>
+<li><a href=#clientHasFault>pluton_client_C_hasFault</a>
+<li><a href=#setDebug>pluton_client_C_setDebug</a>
+<li><a href=#setTimeoutMilliSeconds>pluton_client_C_setTimeoutMilliSeconds</a>
+<li><a href=#getTimeoutMilliSeconds>pluton_client_C_getTimeoutMilliSeconds</a>
+<li><a href=#addRequest>pluton_client_C_addRequest</a>
+<li><a href=#executeAndWaitSent>pluton_client_C_executeAndWaitSent</a>
+<li><a href=#executeAndWaitAll>pluton_client_C_executeAndWaitAll</a>
+<li><a href=#executeAndWaitOne>pluton_client_C_executeAndWaitOne</a>
+<li><a href=#executeAndWaitAny>pluton_client_C_executeAndWaitAny</a>
+</ul>
+
+</ol>
+
+<a name=Introduction>
+<h3>Introduction</h3>
+
+This C API is a thin wrapper around the
+C++ <a href=clientAPI.html>client</a> APIs. The primary target
+customers for this API are expected to be language wrappers
+programmers - particularly JNI and perhaps Perl. By preference, most
+people will normally use the C++ <a href=clientAPI.html>client</a>
+APIs.
+
+<p>
+While this C API has been made as similar as possible to the C++ API,
+the language differences necessarily mean a number of differences, eg,
+references and <code>std::string</code>
+<p>
+
+C programmers should familiarize themselves with the C++
+Client APIs as the semantics of the methods are discussed there, whereas this
+document is constrained to describing the syntax of the corresponding C methods
+and notes any functional differences where necessary.
+
+<a name=Sample>
+<h3>Sample Program</h3>
+
+To introduce the interface, this sample C program demonstrates what a
+simple client might look like:
+
+<p>
+<table border=1>
+<td>
+<pre>
+#include &lt;stdio.h&gt;
+
+#include &lt;pluton/client_C.h&gt;
+
+int
+main(int argc, char** argv)
+{
+ pluton_client_C_obj* C;
+ pluton_request_C_obj* R0;
+ int res;
+ const char* rp;
+ int rl;
+
+ /* Create the Client container using the default lookup map */
+
+ C = pluton_client_C_new("tc_1", 4000);
+ res = pluton_client_C_initialize(C, 0);
+ if (res != 0) exit(1);
+
+ /*
+ * Create a clientRequest and add our request data, attributes
+ * and context.
+ */
+
+ R0 = pluton_request_C_new();
+ pluton_request_C_setRequestData(R0, "Echo Request 0", 14, 0);
+ pluton_request_C_setAttribute(R0, pluton_request_C_noRemoteAttr);
+ pluton_request_C_setContext(R0, "echo.sleepMS", "600", 3);
+
+ /* Add request into container and wait for completion */
+
+ pluton_client_C_addRequest(C, "system.echo.0.raw", R0);
+
+ res = pluton_client_C_executeAndWaitSent(C);
+ if (res != 1) exit(2);
+
+ /*
+ * Get the pointer and length of the response data and write
+ * it to stderr.
+ */
+
+ rp = 0;
+ rl = 0;
+ res = pluton_request_C_getResponseData(R0, &rp, &rl);
+
+ if (rp && rl) {
+ write(2, rp, rl);
+ write(2, "\n", 1);
+ }
+
+
+ /* Delete the objects created by the client library */
+
+ pluton_request_C_delete(R0);
+ pluton_client_C_delete(C);
+
+ exit(0);
+}
+</pre>
+</table>
+
+<p>
+Some observations about this sample program that are relevant to all C
+services are:
+
+<ul>
+<li>The client include file is called
+<code>&lt;pluton/client_C.h&gt;</code>
+
+<li>Routines prefixed with <code>pluton_client_</code>
+ correspond to the
+ <a href=clientAPI.html#constructinitialize><code>pluton::client</code></a>
+ C++ methods
+
+<li>Routines prefixed with <code>pluton_request_</code>
+ correspond to the
+ <a href=clientAPI.html#preparing><code>pluton::clientRequest</code></a>
+ C++ methods
+
+<li>There are <i>new</i> and <i>delete</i> routines which approximate
+ the creation and destruction of C++ objects. Callers should only use
+ these routines to create and destroy the pluton objects. Never
+ use <code>malloc()</code> or <code>free()</code> on these objects.
+
+<li>The first parameter for most of the client routines is a pointer
+ to the opaque <code>pluton_client_C_obj</code> object.
+
+<li>
+The first parameter for most of the clientRequest routines is a pointer
+ to the opaque <code>pluton_request_C_obj</code> object.
+
+<li>Data values are exchanged as \0 terminated C-strings where possible or
+as a pointer/length pair when the data may not be \0 terminated. This
+mainly relates to the request and response data.
+
+<li>All returned pointers and the data they point to are only valid up
+until the next call into this library.
+
+</ul>
+
+
+<a name=Compilation>
+<h3>Compilation and Libraries</h3>
+
+To compile and execute a C program using this interface, compiler and
+linker need access to the standard include directory and the C wrapper
+library. The following sample <code>Makefile</code> shows how this
+might be done:
+
+<p>
+<table border=1>
+<td>
+<pre>
+CFLAGS=-I/usr/local/include
+
+yourProg: yourProg.o
+ $(CC) -o yourProg yourProg.o -lplutonC -L/usr/local/lib
+</pre>
+</table>
+
+
+<a name=ClientRequest>
+<h3>ClientRequest methods corresponding to <code>pluton::clientRequest</code></h3>
+
+In all cases, services must have a <p>
+
+<pre>
+#include &lt;pluton/service_C.h&gt;
+</pre>
+
+<p>
+line in their program to pull in the prototype definitions.
+
+<p>This table identifies all the available C methods and the corresponding C++
+methods. The C methods link to their syntactic definition.
+Almost all methods pass a pointer to the
+opaque <code>pluton_request_C_obj</code> as the first
+parameter. The <code>pluton_request_C_obj</code> object is created by
+<a href=#requestNew>pluton_request_C_new</a> and destroyed by
+<a href=#requestDelete>pluton_request_C_delete</a>.
+
+
+<p>
+<table border=1>
+<tr><th>C method<th>Corresponding C++ method</tr>
+
+<tr><td<a href=#requestNew>pluton_request_C_new</a><td><a href=clientAPI.html#preparing>pluton::clientRequest constructor</a></tr>
+<tr><td<a href=#requestDelete>pluton_request_C_delete</a><td><a href=clientAPI.html#preparing>pluton::clientRequest destructor</a></tr>
+<tr><td<a href=#requestReset>pluton_request_C_reset</a><td><a href=clientAPI.html#requestReset>pluton::clientRequest::reset</a></tr>
+<tr><td<a href=#setRequestData>pluton_request_C_setRequestData</a><td><a href=clientAPI.html#setRequestData>pluton::clientRequest::setRequestData</a></tr>
+<tr><td<a href=#setAttribute>pluton_request_C_setAttribute</a><td><a href=clientAPI.html#setAttribute>pluton::clientRequest::setAttribute</a></tr>
+<tr><td<a href=#getAttribute>pluton_request_C_getAttribute</a><td><a href=clientAPI.html#getAttribute>pluton::clientRequest::getAttribute</a></tr>
+<tr><td<a href=#clearAttribute>pluton_request_C_clearAttribute</a><td><a href=clientAPI.html#clearAttribute>pluton::clientRequest::clearAttribute</a></tr>
+<tr><td<a href=#setContext>pluton_request_C_setContext</a><td><a href=clientAPI.html#setContext>pluton::clientRequest::setContext</a></tr>
+<tr><td<a href=#getResponseData>pluton_request_C_getResponseData</a><td><a href=clientAPI.html#getResponseData>pluton::clientRequest::getResponseData</a></tr>
+<tr><td<a href=#inProgress>pluton_request_C_inProgress</a><td><a href=clientAPI.html#inProgress>pluton::clientRequest::inProgress</a></tr>
+<tr><td<a href=#hasFault>pluton_request_C_hasFault</a><td><a href=clientAPI.html#hasFault>pluton::clientRequest::hasFault</a></tr>
+<tr><td<a href=#getFaultCode>pluton_request_C_getFaultCode</a><td><a href=clientAPI.html#getFaultCode>pluton::clientRequest::getFaultCode</a></tr>
+<tr><td<a href=#getFaultText>pluton_request_C_getFaultText</a><td><a href=clientAPI.html#getFaultText>pluton::clientRequest::getFaultText</a></tr>
+<tr><td<a href=#getServiceName>pluton_request_C_getServiceName</a><td><a href=clientAPI.html#getServiceName>pluton::clientRequest::getServiceName</a></tr>
+<tr><td<a href=#setClientHandle>pluton_request_C_setClientHandle</a><td><a href=clientAPI.html#setClientHandle>pluton::clientRequest::setClientHandle</a></tr>
+<tr><td<a href=#getClientHandle>pluton_request_C_getClientHandle</a><td><a href=clientAPI.html#getClientHandle>pluton::clientRequest::getClientHandle</a></tr>
+
+</table>
+<p>
+
+
+<a name=requestNew>
+<h4>pluton_request_C_new()</h4>
+
+Create a container for the <code>pluton::clientRequest</code> object and return an opaque pointer of
+type <code>pluton_request_C_obj</code>. The correct (and only) way to delete this object is to
+call <a href=#requestDelete>pluton_request_C_delete</a>.
+
+<p>The <code>pluton_request_C_obj</code> pointer is needed for
+ virtually all other methods.
+<h5>Syntax</h5>
+
+<pre>
+ extern pluton_request_C_obj* pluton_request_C_new();
+</pre>
+
+<a name=requestDelete>
+<h4>pluton_request_C_delete()</h4>
+
+Delete the object previously created by <a href=#clientNew>pluton_request_C_new</a>.
+
+<h5>Syntax</h5>
+
+<pre>
+ extern void pluton_request_C_delete(pluton_request_C_obj*);
+</pre>
+
+The caller is responsible for destroying all objects created by calls
+to <a href=#clientNew>pluton_request_C_new</a>.
+
+<a name=requestReset>
+<h4>pluton_request_C_reset()</h4>
+
+
+See <a href=clientAPI.html#requestReset>pluton::clientRequest::reset</a> for semantics.
+
+<h5>Syntax</h5>
+
+<pre>
+ extern void pluton_request_C_reset(pluton_request_C_obj*);
+</pre>
+
+
+
+<a name=setRequestData>
+<h4>pluton_request_C_setRequestData()</h4>
+
+See <a href=clientAPI.html#setRequestData>pluton::clientRequest::setRequestData</a> for
+semantics. There is only one fingerprint for this method which
+contrasts with the multitude of fingerprints available in the C++ library.
+
+<h5>Syntax</h5>
+
+<pre>
+ extern void pluton_request_C_setRequestData(pluton_request_C_obj*,
+ const char* requestPointer,
+ int requestLength,
+ int copyDataFlag);
+</pre>
+
+<h5>PARAMETERS</h5>
+
+
+<table border=1>
+<tr><th>Name<th>Description</tr>
+
+<tr valign=top><td>requestPointer<td>A pointer to the request data.
+
+There are no constraints on the content of the data. If the data is text, it probably should be
+encoded in UTF-8 or similar but it also may be binary data. The type of data is entirely a function
+of the agreed-upon serialization between the client and service.
+
+<p>
+If <code>copyDataFlag</code> is <code>false</code> the program must not modify the data pointed to
+by <code>requestPointer</code> until after the request has completed otherwise results are
+guaranteed to be undefined and unpleasant.</tr>
+
+</tr>
+
+<tr valign=top><td>requestLength<td>The number of bytes in the request</tr>
+
+<tr valign=top><td>copyDataFlag<td>If <code>true</code>, the request data is copied into an internally
+ allocated buffer so that the caller does not have to retain the data. Copying request data is
+ obviously sub-optimal and the preferred approach is for the caller to maintain the data if possible.
+</tr>
+
+</table>
+
+
+<a name=setAttribute>
+<h4>pluton_request_C_setAttribute()</h4>
+
+See <a href=clientAPI.html#setAttribute>pluton::clientRequest::setAttribute</a> for semantics.
+
+<h5>Syntax</h5>
+
+<pre>
+ extern void pluton_request_C_setAttribute(pluton_request_C_obj*, int attrs);
+</pre>
+
+Valid attributes are:
+<p>
+<table border=1>
+<tr><th>C definition<th>Corresponding C++ Attribute</tr>
+<code>
+<tr valign=top><td>pluton_request_C_noWaitAttr<td><a href=clientAPI.html#noWaitAttr>pluton::noWaitAttr</tr>
+<tr valign=top><td>pluton_request_C_noRemoteAttr<td><a href=clientAPI.html#noRemoteAttr>pluton::noRemoteAttr</tr>
+<tr valign=top><td>pluton_request_C_noRetryAttr<td><a href=clientAPI.html#noRetryAttr>pluton::noRetryAttr</tr>
+<tr valign=top><td>pluton_request_C_keepAffinityAttr<td><a href=clientAPI.html#keepAffinityAttr>pluton::keepAffinityAttr</tr>
+<tr valign=top><td>pluton_request_C_needAffinityAttr<td><a href=clientAPI.html#needAffinityAttr>pluton::needAffinityAttr</tr>
+</code>
+</table>
+
+<h5>Example</h5>
+
+<pre>
+ pluton_request_C_obj* R0;
+
+ R0 = pluton_request_C_new();
+ pluton_request_C_setAttribute(R0, pluton_request_C_noWaitAttr | pluton_request_C_noRemoteAttr);
+</pre>
+
+<a name=getAttribute>
+<h4>pluton_request_C_getAttribute()</h4>
+
+See <a href=clientAPI.html#getAttribute>pluton::clientRequest::getAttribute</a> for semantics.
+
+<h5>Syntax</h5>
+
+<pre>
+ extern int pluton_request_C_getAttribute(pluton_request_C_obj*, int attrs);
+</pre>
+
+<p>Valid attributes as per <a href=#setAttribute><code>pluton_request_C_setAttribute()</code></a>.
+
+<a name=clearAttribute>
+<h4>pluton_request_C_clearAttribute()</h4>
+
+See <a href=clientAPI.html#clearAttribute>pluton::clientRequest::clearAttribute</a> for semantics.
+
+<h5>Syntax</h5>
+
+<pre>
+ extern void pluton_request_C_clearAttribute(pluton_request_C_obj*, int attrs);
+</pre>
+
+<p>Valid attributes as per <a href=#setAttribute><code>pluton_request_C_setAttribute()</code></a>.
+
+
+<a name=setContext>
+<h4>pluton_request_C_setContext()</h4>
+
+See <a href=clientAPI.html#setContext>pluton::clientRequest::setContext</a> for semantics.
+
+<h5>Syntax</h5>
+
+<pre>
+ extern int pluton_request_C_setContext(pluton_request_C_obj*,
+ const char* keyPointer,
+ const char* valuePointer, int valueLength);
+
+</pre>
+
+<h5>PARAMETERS</h5>
+
+
+<table border=1>
+<tr><th>Name<th>Description</tr>
+
+<tr valign=top><td>keyPointer<td>A pointer a C-string of the context key.</tr>
+
+<tr valign=top><td>valuePointer<td>A pointer to data for the context.</tr>
+
+<tr valign=top><td>valueLength<td>The number of bytes at <code>valuePointer</code></tr>
+
+</table>
+
+<h5>Example</h5>
+
+<pre>
+ pluton_request_C_obj* R0;
+ char buffer[20];
+
+ R0 = pluton_request_C_new();
+ ...fill buffer with 20 bytes of data...
+
+ pluton_request_C_setContext(R0, "payload", buffer, sizeof(buffer));
+</pre>
+
+
+
+<a name=getResponseData>
+<h4>a>pluton_request_C_getResponseData()</h4>
+
+
+See <a href=clientAPI.html#getResponseData>pluton::clientRequest::getResponseData</a>
+for semantics.
+
+<p>This routine returns a pointer and length of the response data. The pointer points at an internal
+data object which is read-only and becomes invalid at the next call to any other routine in this
+API.
+
+<h5>Syntax</h5>
+
+<pre>
+extern int
+ pluton_request_C_getResponseData(pluton_request_C_obj*,
+ const char** responsePointer, int* responseLength);
+</pre>
+
+<h5>PARAMETERS</h5>
+
+<table border=1>
+<tr><th>Name<th>Description</tr>
+
+<tr valign=top><td>respondePointer<td>A pointer to a pointer that is populated with a pointer to the
+ response data.
+</tr>
+
+<tr valign=top><td>responseLength<td>A pointer to an int that is populated with the length of the
+ response data.</tr>
+</tr>
+
+</table>
+
+<h5>RETURN VALUE</h5>
+
+The <code>pluton::faultCode</code> of this request. If not equal to zero then the request has a
+fault of some sort. The fault codes are define in the
+file <code>&lt;pluton/fault.h&gt;<code> C++ include
+file. See <a href=#getFaultText>pluton_request_C_getFaultText</a> for how to access a textual
+explanation of the fault.
+
+<h5>Example</h5>
+
+<pre>
+ pluton_request_C_obj* R0;
+ char buffer[20];
+ const char** rp;
+ int rl;
+
+ R0 = pluton_request_C_new();
+ ...Make request...
+
+ if (pluton_request_C_getResponseData(R0, &rp, &rl) == 0) {
+ write(2, rp, rl);
+ }
+</pre>
+
+
+
+<a name=inProgress>
+<h4>pluton_request_C_inProgress()</h4>
+
+See <a href=clientAPI.html#inProgress>pluton::clientRequest::inProgress</a> for semantics.
+
+<p>Returns a
+value that evaluates to <code>true</code> in C if the request has been added to
+a <code>pluton::client</code> object but not completed and thus un-available
+for returning by any of the <code>executeAndWait*</code>
+routines.
+
+<h5>Syntax</h5>
+
+<pre>
+ extern int pluton_request_C_inProgress(pluton_request_C_obj*);
+</pre>
+
+
+<a name=hasFault>
+<h4>pluton_request_C_hasFault()</h4>
+
+See <a href=clientAPI.html#hasFault>pluton::clientRequest::hasFault</a> for semantics.
+
+<h5>Syntax</h5>
+
+<pre>
+ extern int pluton_request_C_hasFault(pluton_request_C_obj*);
+</pre>
+
+
+<a name=getFaultCode>
+<h4>pluton_request_C_getFaultCode()</h4>
+
+See <a href=clientAPI.html#getFaultCode>pluton::clientRequest::getFaultCode</a> for semantics.
+
+<h5>Syntax</h5>
+
+<pre>
+ extern int pluton_request_C_getFaultCode(pluton_request_C_obj*);
+</pre>
+
+
+<a name=getFaultText>
+<h4>pluton_request_C_getFaultText()</h4>
+
+See <a href=clientAPI.html#getFaultText>pluton::clientRequest::getFaultText</a> for semantics.
+
+<h5>Syntax</h5>
+
+<pre>
+ extern const char* pluton_request_C_getFaultText(pluton_request_C_obj*);
+</pre>
+
+<h5>RETURN VALUE</h5>
+
+A pointer to a C-string describing the fault for the request. The pointer is only valid until the
+next call to any method in this API. If the request has no fault, a zero length string is returned.
+
+<a name=getServiceName>
+<h4>pluton_request_C_getServiceName()</h4>
+
+See <a href=clientAPI.html#getServiceName>pluton::clientRequest::getServiceName</a> for semantics.
+
+<h5>Syntax</h5>
+
+<pre>
+ extern const char* pluton_request_C_getServiceName(pluton_request_C_obj*);
+</pre>
+
+<h5>RETURN VALUE</h5>
+
+A pointer to a C-string describing the name of the service. The pointer is only valid until the
+next call to any method in this API.
+
+
+<a name=setClientHandle>
+<h4>pluton_request_C_setClientHandle()</h4>
+
+See <a href=clientAPI.html#setClientHandle>pluton::clientRequest::setClientHandle</a> for semantics.
+
+<h5>Syntax</h5>
+
+<pre>
+ extern void pluton_request_C_setClientHandle(pluton_request_C_obj*, int);
+</pre>
+
+
+<a name=getClientHandle>
+<h4>pluton_request_C_getClientHandle()</h4>
+
+See <a href=clientAPI.html#getClientHandle>pluton::clientRequest::getClientHandle</a> for semantics.
+
+<h5>Syntax</h5>
+
+<pre>
+ extern int pluton_request_C_getClientHandle(pluton_request_C_obj*);
+</pre>
+
+<a name=Client>
+<h3>Client methods corresponding to <code>pluton::client</code></h3>
+
+In all cases, services must have a <p>
+
+<pre>
+#include &lt;pluton/service_C.h&gt;
+</pre>
+
+<p>
+line in their program to pull in the prototype definitions.
+
+<p>This table identifies all the available C methods and the corresponding C++
+methods. The C methods link to their syntactic definition.
+
+<p>
+<table border=1>
+<tr><th>C method<th>Corresponding C++ method</tr>
+
+<tr><td<a href=#clientNew>pluton_client_C_new</a><td><a href=clientAPI.html#construction>pluton::client constructor</a></tr>
+<tr><td<a href=#clientDelete>pluton_client_C_delete</a><td><a href=clientAPI.html#preparing>pluton::client destructor</a></tr>
+<tr><td<a href=#clientReset>pluton_client_C_reset</a><td><a href=clientAPI.html#clientReset>pluton::client::reset</a></tr>
+<tr><td<a href=#getAPIVersion>pluton_client_C_getAPIVersion</a><td><a href=clientAPI.html#getAPIVersion>pluton::client::getAPIVersion</a></tr>
+<tr><td<a href=#initialize>pluton_client_C_initialize</a><td><a href=clientAPI.html#initialize>pluton::client::initialize</a></tr>
+<tr><td<a href=#clientHasFault>pluton_client_C_hasFault</a><td><a href=clientAPI.html#clientHasFault>pluton::client::hasFault</a></tr>
+<tr><td<a href=#setDebug>pluton_client_C_setDebug</a><td><a href=clientAPI.html#setDebug>pluton::client::setDebug</a></tr>
+<tr><td<a href=#setTimeoutMilliSeconds>pluton_client_C_setTimeoutMilliSeconds</a><td><a href=clientAPI.html#setTimeoutMilliSeconds>pluton::client::setTimeoutMilliSeconds</a></tr>
+<tr><td<a href=#getTimeoutMilliSeconds>pluton_client_C_getTimeoutMilliSeconds</a><td><a href=clientAPI.html#getTimeoutMilliSeconds>pluton::client::getTimeoutMilliSeconds</a></tr>
+<tr><td<a href=#addRequest>pluton_client_C_addRequest</a><td><a href=clientAPI.html#addRequest>pluton::client::addRequest</a></tr>
+<tr><td<a href=#executeAndWaitSent>pluton_client_C_executeAndWaitSent</a><td><a href=clientAPI.html#executeAndWaitSent>pluton::client::executeAndWaitSent</a></tr>
+<tr><td<a href=#executeAndWaitAll>pluton_client_C_executeAndWaitAll</a><td><a href=clientAPI.html#executeAndWaitAll>pluton::client::executeAndWaitAll</a></tr>
+<tr><td<a href=#executeAndWaitOne>pluton_client_C_executeAndWaitOne</a><td><a href=clientAPI.html#executeAndWaitOne>pluton::client::executeAndWaitOne</a></tr>
+<tr><td<a href=#executeAndWaitAny>pluton_client_C_executeAndWaitAny</a><td><a href=clientAPI.html#executeAndWaitAny>pluton::client::executeAndWaitAny</a></tr>
+
+</table>
+<p>
+
+
+
+<a name=clientNew>
+<h4>pluton_client_C_new()</h4>
+
+Create a container for the <code>pluton::client</code> object and return an opaque pointer of
+type <code>pluton_client_C_obj</code>. The correct (and only) way to delete this object is to
+call <a href=#clientDelete>pluton_client_C_delete</a>.
+
+<p>
+See <a href=clientAPI.html#construction>pluton::client constructor</a> for semantics.
+
+<h5>Syntax</h5>
+
+<pre>
+ extern pluton_client_C_obj* pluton_client_C_new(const char* yourName,
+ int defaultTimeoutMilliSeconds);
+</pre>
+
+
+<a name=clientDelete>
+<h4>pluton_client_C_delete()</h4>
+
+Delete the object previously created by <a href=#clientNew>pluton_client_C_new</a>.
+
+<h5>Syntax</h5>
+
+<pre>
+ extern void pluton_client_C_delete(pluton_client_C_obj*);
+</pre>
+
+
+<a name=clientReset>
+<h4>pluton_client_C_reset()</h4>
+
+See <a href=clientAPI.html#clientReset>pluton::client::reset</a> for semantics.
+
+<h5>Syntax</h5>
+
+<pre>
+ extern void pluton_client_C_reset(pluton_client_C_obj*);
+</pre>
+
+
+<a name=getAPIVersion>
+<h4>pluton_client_C_getAPIVersion()</h4>
+
+See <a href=clientAPI.html#getAPIVersion>pluton::client::getAPIVersion</a> for semantics.
+
+<h5>Syntax</h5>
+
+<pre>
+ extern const char* pluton_client_C_getAPIVersion();
+</pre>
+
+
+<a name=initialize>
+<h4>pluton_client_C_initialize()</h4>
+
+See <a href=clientAPI.html#initialize>pluton::client::initialize</a> for semantics.
+
+<h5>Syntax</h5>
+
+<pre>
+ extern int pluton_client_C_initialize(pluton_client_C_obj*,
+ const char* lookupMapPath);
+</pre>
+
+<p>
+If <code>lookupMapPath</code> is NULL or an empty string the default lookup map is used.
+
+<a name=clientHasFault>
+<h4>pluton_client_C_hasFault()</h4>
+
+See <a href=clientAPI.html#clientHasFault>pluton::client::hasFault</a> for semantics.
+
+<h5>Syntax</h5>
+
+<pre>
+ extern int pluton_client_C_hasFault(pluton_client_C_obj*);
+</pre>
+
+
+<a name=setDebug>
+<h4>pluton_client_C_setDebug()</h4>
+
+See <a href=clientAPI.html#setDebug>pluton::client::setDebug</a> for semantics.
+
+<h5>Syntax</h5>
+
+<pre>
+extern void pluton_client_C_setDebug(pluton_client_C_obj*, int nv);
+</pre>
+
+
+<a name=setTimeoutMilliSeconds>
+<h4>pluton_client_C_setTimeoutMilliSeconds()</h4>
+
+See <a href=clientAPI.html#setTimeoutMilliSeconds>pluton::client::setTimeoutMilliSeconds</a> for semantics.
+
+
+<h5>Syntax</h5>
+
+<pre>
+ extern void pluton_client_C_setTimeoutMilliSeconds(pluton_client_C_obj*,
+ int timeoutMilliSeconds);
+</pre>
+
+
+<a name=getTimeoutMilliSeconds>
+<h4>pluton_client_C_getTimeoutMilliSeconds()</h4>
+
+See <a href=clientAPI.html#getTimeoutMilliSeconds>pluton::client::getTimeoutMilliSeconds</a> for semantics.
+
+<h5>Syntax</h5>
+
+<pre>
+ extern int pluton_client_C_getTimeoutMilliSeconds(pluton_client_C_obj*);
+</pre>
+
+
+<a name=addRequest>
+<h4>pluton_client_C_addRequest()</h4>
+
+See <a href=clientAPI.html#addRequest>pluton::client::addRequest</a> for semantics.
+
+<h5>Syntax</h5>
+
+<pre>
+ extern int pluton_client_C_addRequest(pluton_client_C_obj*,
+ const char* serviceKey, pluton_request_C_obj*);
+</pre>
+
+
+<a name=executeAndWaitSent>
+<h4>pluton_client_C_executeAndWaitSent()</h4>
+
+See <a href=clientAPI.html#executeAndWaitSent>pluton::client::executeAndWaitSent</a> for semantics.
+
+<h5>Syntax</h5>
+
+<pre>
+ extern int pluton_client_C_executeAndWaitSent(pluton_client_C_obj*);
+</pre>
+
+
+<a name=executeAndWaitAll>
+<h4>pluton_client_C_executeAndWaitAll()</h4>
+
+See <a href=clientAPI.html#executeAndWaitAll>pluton::client::executeAndWaitAll</a> for semantics.
+
+<h5>Syntax</h5>
+
+<pre>
+ extern int pluton_client_C_executeAndWaitAll(pluton_client_C_obj*);
+</pre>
+
+
+<a name=executeAndWaitOne>
+<h4>pluton_client_C_executeAndWaitOne()</h4>
+
+See <a href=clientAPI.html#executeAndWaitOne>pluton::client::executeAndWaitOne</a> for semantics.
+
+<h5>Syntax</h5>
+
+<pre>
+ extern int pluton_client_C_executeAndWaitOne(pluton_client_C_obj*, pluton_request_C_obj*);
+</pre>
+
+
+<a name=executeAndWaitAny>
+<h4>pluton_client_C_executeAndWaitAny()</h4>
+
+See <a href=clientAPI.html#executeAndWaitAny>pluton::client::executeAndWaitAny</a> for semantics.
+
+<h5>Syntax</h5>
+
+<pre>
+ extern pluton_request_C_obj* pluton_client_C_executeAndWaitAny(pluton_client_C_obj*);
+</pre>
+
+<h5>RETURN VALUE</h5>
+
+The return value, if not NULL, is a pointer to a previously
+created <code>pluton_request_C_obj</code> object. This return value <i>not</i> a copy but a pointer
+to a pre-exiting object so be wary of double-deleting.
+
+<p>
+<hr>
+<font size=-1>
+$Id: cclientAPI.html 260483 2009-10-16 18:47:56Z markd $
+&copy; Copyright Yahoo! Inc, 2007, 2008, 2009
+</font>
+</body>
+</html>
1,367 Docs/clientAPI.html
@@ -0,0 +1,1367 @@
+<html>
+<head>
+<link rel="shortcut icon" href=images/pluto-symbol.jpg type="image/x-icon" />
+<title>
+The Pluton Framework: Client API
+</title>
+</head>
+
+<body>
+
+<center>
+<a href=index.html>
+<img height=100 src=images/pluto-charon.jpg ALT="[Pluto Charon Image]">
+</a>
+</center>
+
+<h2 align=center>The Pluton Framework: Client API</h2>
+
+<h3>Introduction</h3>
+
+This is the core client API which provides mechanism by which a client
+aggregates and send requests to services. This API is written in C++
+and provides a simple blocking interface to parallel service
+requests. The target clients for this API are programs which wish to
+avoid the complexity of parallel processing but wish to gain the
+benefits from it.
+
+<p>
+For the more sophisticated programs that use non-blocking techniques,
+there are <a href=clientAPINonBlock.html>non-blocking APIs</a> that
+let you integrate Pluton Requests with your non-blocking
+program. These non-blocking interfaces are especially designed with
+<a href=http://state-threads.sourceforge.net/>State Threads</a>
+and
+<a href=http://monkey.org/~provos/libevent/>libevent</a>
+in mind but can be used with any program which uses <code>poll(),
+select()</code> or <code>kqueue()</code>-like interfaces.
+
+<p>
+<table border=1>
+<tr><td><em>Warning about threads:</em> None of the APIs are thread-safe
+ unless the application follows
+ the <a href=threading.html>instructions and rules</a> regarding
+ thread-safe use of the client library.
+</table>
+
+<p>
+
+A <a href=sampleClient.html>sample client program</a> demonstrates the
+methods typically used by a client. Unlike a Pluton service, the
+structure of a client is expected to be more complex and less amenable
+to a prescriptive structure, consequently, this sample client should