LogCabin
include/LogCabin/Client.h
Go to the documentation of this file.
00001 /* Copyright (c) 2011-2014 Stanford University
00002  * Copyright (c) 2014-2015 Diego Ongaro
00003  *
00004  * Permission to use, copy, modify, and distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
00009  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00010  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
00011  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00012  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00013  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
00014  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00015  */
00016 
00017 /**
00018  * \file
00019  * This file declares the interface for LogCabin's client library.
00020  */
00021 
00022 #include <cstddef>
00023 #include <memory>
00024 #include <map>
00025 #include <mutex>
00026 #include <string>
00027 #include <vector>
00028 
00029 #ifndef LOGCABIN_INCLUDE_LOGCABIN_CLIENT_H
00030 #define LOGCABIN_INCLUDE_LOGCABIN_CLIENT_H
00031 
00032 namespace LogCabin {
00033 
00034 // forward declarations
00035 namespace Core {
00036 namespace Debug {
00037 } // namespace LogCabin::Core::Debug
00038 } // namespace LogCabin::Core
00039 
00040 // forward declarations
00041 namespace Protocol {
00042 class ServerStats;
00043 namespace Client {
00044 class StateMachineQuery_Request;
00045 class StateMachineQuery_Response;
00046 class StateMachineCommand_Request;
00047 class StateMachineCommand_Response;
00048 } // namespace LogCabin::Protocol::Client
00049 } // namespace LogCabin::Protocol
00050 
00051 namespace Client {
00052 
00053 class ClientImpl; // forward declaration
00054 class TreeDetails; // forward declaration
00055 
00056 // To control how the debug log operates, clients should
00057 // #include <LogCabin/Debug.h>
00058 // and access it through
00059 // LogCabin::Client::Debug.
00060 namespace Debug = Core::Debug;
00061 
00062 /**
00063  * A member of the cluster Configuration.
00064  */
00065 struct Server {
00066     /// Constructor.
00067     Server(uint64_t serverId, const std::string& addresses);
00068     /// Default constructor.
00069     Server();
00070     /// Copy constructor.
00071     Server(const Server& other);
00072     /// Destructor.
00073     ~Server();
00074     /// Copy assignment.
00075     Server& operator=(const Server& other);
00076 
00077     /**
00078      * The unique ID of the server.
00079      */
00080     uint64_t serverId;
00081 
00082     /**
00083      * The network addresses of the server (comma-delimited).
00084      */
00085     std::string addresses;
00086 };
00087 
00088 /**
00089  * Defines the members of the cluster.
00090  * Used in Cluster::getConfiguration and Cluster::setConfiguration.
00091  */
00092 typedef std::vector<Server> Configuration;
00093 
00094 /**
00095  * Returned by Cluster::setConfiguration.
00096  */
00097 struct ConfigurationResult {
00098     ConfigurationResult();
00099     ~ConfigurationResult();
00100 
00101     enum Status {
00102         /**
00103          * The operation succeeded.
00104          */
00105         OK = 0,
00106         /**
00107          * The supplied 'oldId' is no longer current.
00108          * Call GetConfiguration, re-apply your changes, and try again.
00109          */
00110         CHANGED = 1,
00111         /**
00112          * The reconfiguration was aborted because some servers are
00113          * unavailable.
00114          */
00115         BAD = 2,
00116         /**
00117          * The reconfiguration could not be completed in the requested
00118          * timeframe.
00119          * \since LogCabin v1.2.0
00120          */
00121         TIMEOUT = 3,
00122     } status;
00123 
00124     /**
00125      * If status is BAD, the servers that were unavailable to join the cluster.
00126      */
00127     Configuration badServers;
00128 
00129     /**
00130      * Error message, if status is not OK.
00131      */
00132     std::string error;
00133 };
00134 
00135 /**
00136  * Returned by Cluster::getConfiguration2().
00137  * \since LogCabin v1.2.0
00138  */
00139 struct GetConfigurationResult {
00140     GetConfigurationResult();
00141     ~GetConfigurationResult();
00142 
00143     enum Status {
00144         /**
00145          * The operation succeeded.
00146          */
00147         OK = 0,
00148         /**
00149          * The call could not be completed in the requested timeframe.
00150          */
00151         TIMEOUT = 1,
00152     } status;
00153 
00154     /**
00155      * If status is OK, identifies the configuration. Pass this to
00156      * setConfiguration later.
00157      */
00158     uint64_t configuration;
00159 
00160     /**
00161      * If status is OK, the list of servers in the configuration.
00162      */
00163     Configuration servers;
00164 
00165     /**
00166      * Error message, if status is not OK.
00167      */
00168     std::string error;
00169 };
00170 
00171 /**
00172  * Status codes returned by Tree operations.
00173  */
00174 enum class Status {
00175 
00176     /**
00177      * The operation completed successfully.
00178      */
00179     OK = 0,
00180 
00181     /**
00182      * If an argument is malformed (for example, a path that does not start
00183      * with a slash).
00184      */
00185     INVALID_ARGUMENT = 1,
00186 
00187     /**
00188      * If a file or directory that is required for the operation does not
00189      * exist.
00190      */
00191     LOOKUP_ERROR = 2,
00192 
00193     /**
00194      * If a directory exists where a file is required or a file exists where
00195      * a directory is required.
00196      */
00197     TYPE_ERROR = 3,
00198 
00199     /**
00200      * A predicate which was previously set on operations with
00201      * Tree::setCondition() was not satisfied.
00202      */
00203     CONDITION_NOT_MET = 4,
00204 
00205     /**
00206      * A timeout specified by Tree::setTimeout() elapsed while waiting for
00207      * an operation to complete. It is not known whether the operation has or
00208      * will complete, only that a positive acknowledgment was not received
00209      * before the timeout elapsed.
00210      */
00211     TIMEOUT = 5,
00212 };
00213 
00214 /**
00215  * Print a status code to a stream.
00216  */
00217 std::ostream&
00218 operator<<(std::ostream& os, Status status);
00219 
00220 /**
00221  * Returned by Tree operations; contain a status code and an error message.
00222  */
00223 struct Result {
00224     /**
00225      * Default constructor. Sets status to OK and error to the empty string.
00226      */
00227     Result();
00228     /**
00229      * A code for whether an operation succeeded or why it did not. This is
00230      * meant to be used programmatically.
00231      */
00232     Status status;
00233     /**
00234      * If status is not OK, this is a human-readable message describing what
00235      * went wrong.
00236      */
00237     std::string error;
00238 };
00239 
00240 /**
00241  * Base class for LogCabin client exceptions.
00242  */
00243 class Exception : public std::runtime_error {
00244   public:
00245     explicit Exception(const std::string& error);
00246 };
00247 
00248 /**
00249  * See Status::INVALID_ARGUMENT.
00250  */
00251 class InvalidArgumentException : public Exception {
00252   public:
00253     explicit InvalidArgumentException(const std::string& error);
00254 };
00255 
00256 /**
00257  * See Status::LOOKUP_ERROR.
00258  */
00259 class LookupException : public Exception {
00260   public:
00261     explicit LookupException(const std::string& error);
00262 };
00263 
00264 /**
00265  * See Status::TYPE_ERROR.
00266  */
00267 class TypeException : public Exception {
00268   public:
00269     explicit TypeException(const std::string& error);
00270 };
00271 
00272 /**
00273  * See Status::CONDITION_NOT_MET.
00274  */
00275 class ConditionNotMetException : public Exception {
00276   public:
00277     explicit ConditionNotMetException(const std::string& error);
00278 };
00279 
00280 /**
00281  * See Status::TIMEOUT.
00282  */
00283 class TimeoutException : public Exception {
00284   public:
00285     explicit TimeoutException(const std::string& error);
00286 };
00287 
00288 /**
00289  * See ConfigurationResult::BAD
00290  * \since LogCabin v1.2.0
00291  */
00292 class ConfigurationExceptionBad : public Exception {
00293   public:
00294     explicit ConfigurationExceptionBad(const std::string& error);
00295 };
00296 
00297 /**
00298  * See ConfigurationResult::CHANGED
00299  * \since LogCabin v1.2.0
00300  */
00301 class ConfigurationExceptionChanged : public Exception {
00302   public:
00303     explicit ConfigurationExceptionChanged(const std::string& error);
00304 };
00305 
00306 /**
00307  * Provides access to the hierarchical key-value store.
00308  * You can get an instance of Tree through Cluster::getTree() or by copying
00309  * an existing Tree.
00310  *
00311  * A Tree has a working directory from which all relative paths (those that do
00312  * not begin with a '/' are resolved). This allows different applications and
00313  * modules to conveniently access their own subtrees -- they can have their own
00314  * Tree instances and set their working directories accordingly.
00315  *
00316  * Methods that can fail come in two flavors. The first flavor returns Result
00317  * values with error codes and messages; the second throws exceptions upon
00318  * errors. These can be distinguished by the "Ex" suffix in the names of
00319  * methods that throw exceptions.
00320  */
00321 class Tree {
00322   private:
00323     /// Constructor.
00324     Tree(std::shared_ptr<ClientImpl> clientImpl,
00325          const std::string& workingDirectory);
00326   public:
00327     /// Copy constructor.
00328     Tree(const Tree& other);
00329     /// Assignment operator.
00330     Tree& operator=(const Tree& other);
00331 
00332     /**
00333      * Set the working directory for this object. This directory will be
00334      * created if it does not exist.
00335      * \param workingDirectory
00336      *      The new working directory, which may be relative to the current
00337      *      working directory.
00338      * \return
00339      *      Status and error message. Possible errors are:
00340      *       - INVALID_ARGUMENT if workingDirectory is malformed.
00341      *       - TYPE_ERROR if parent of workingDirectory is a file.
00342      *       - TYPE_ERROR if workingDirectory exists but is a file.
00343      *       - CONDITION_NOT_MET if predicate from setCondition() was false.
00344      *       - TIMEOUT if timeout elapsed before the operation completed.
00345      *      If this returns an error, future operations on this tree using
00346      *      relative paths will fail until a valid working directory is set.
00347      */
00348     Result setWorkingDirectory(const std::string& workingDirectory);
00349 
00350     /**
00351      * Like setWorkingDirectory but throws exceptions upon errors.
00352      */
00353     void setWorkingDirectoryEx(const std::string& workingDirectory);
00354 
00355     /**
00356      * Return the working directory for this object.
00357      * \return
00358      *      An absolute path that is the prefix for relative paths used with
00359      *      this Tree object.
00360      */
00361     std::string getWorkingDirectory() const;
00362 
00363     /**
00364      * Return the condition set by a previous call to setCondition().
00365      * \return
00366      *      First component: the absolute path corresponding to the 'path'
00367      *      argument of setCondition().
00368      *      Second component: the file contents given as the 'value' argument
00369      *      of setCondition().
00370      */
00371     std::pair<std::string, std::string> getCondition() const;
00372 
00373     /**
00374      * Set a predicate on all future operations. Future operations will return
00375      * Status::CONDITION_NOT_MET and have no effect unless the file at 'path'
00376      * has the contents 'value'. To remove the predicate, pass an empty string
00377      * as 'path'.
00378      * \param path
00379      *      The relative or absolute path to the file that must have the
00380      *      contents specified in value, or an empty string to clear the
00381      *      condition.
00382      * \param value
00383      *      The contents that the file specified by 'path' must have for future
00384      *      operations to succeed. If 'value' is the empty string and the
00385      *      file does not exist, the condition will also be satisfied.
00386      * \return
00387      *      Status and error message. Possible errors are:
00388      *       - INVALID_ARGUMENT if path is malformed.
00389      *      If this returns an error, future operations on this tree will fail
00390      *      until a new condition is set or the condition is cleared.
00391      */
00392     Result setCondition(const std::string& path, const std::string& value);
00393 
00394     /**
00395      * Like setCondition but throws exceptions upon errors.
00396      */
00397     void setConditionEx(const std::string& path, const std::string& value);
00398 
00399     /**
00400      * Return the timeout set by a previous call to setTimeout().
00401      * \return
00402      *      The maximum duration of each operation (in nanoseconds), or 0
00403      *      for no timeout.
00404      */
00405     uint64_t getTimeout() const;
00406 
00407     /**
00408      * Abort each future operation if it may not have completed within the
00409      * specified period of time.
00410      * \warning
00411      *      The client library does not currently implement timeouts for DNS
00412      *      lookups. See https://github.com/logcabin/logcabin/issues/75
00413      * \param nanoseconds
00414      *      The maximum duration of each operation (in nanoseconds). Set to 0
00415      *      for no timeout.
00416      */
00417     void setTimeout(uint64_t nanoseconds);
00418 
00419     /**
00420      * Make sure a directory exists at the given path.
00421      * Create parent directories listed in path as necessary.
00422      * \param path
00423      *      The path where there should be a directory after this call.
00424      * \return
00425      *      Status and error message. Possible errors are:
00426      *       - INVALID_ARGUMENT if path is malformed.
00427      *       - TYPE_ERROR if a parent of path is a file.
00428      *       - TYPE_ERROR if path exists but is a file.
00429      *       - CONDITION_NOT_MET if predicate from setCondition() was false.
00430      *       - TIMEOUT if timeout elapsed before the operation completed.
00431      */
00432     Result
00433     makeDirectory(const std::string& path);
00434 
00435     /**
00436      * Like makeDirectory but throws exceptions upon errors.
00437      */
00438     void makeDirectoryEx(const std::string& path);
00439 
00440     /**
00441      * List the contents of a directory.
00442      * \param path
00443      *      The directory whose direct children to list.
00444      * \param[out] children
00445      *      This will be replaced by a listing of the names of the directories
00446      *      and files that the directory at 'path' immediately contains. The
00447      *      names of directories in this listing will have a trailing slash.
00448      *      The order is first directories (sorted lexicographically), then
00449      *      files (sorted lexicographically).
00450      * \return
00451      *      Status and error message. Possible errors are:
00452      *       - INVALID_ARGUMENT if path is malformed.
00453      *       - LOOKUP_ERROR if a parent of path does not exist.
00454      *       - LOOKUP_ERROR if path does not exist.
00455      *       - TYPE_ERROR if a parent of path is a file.
00456      *       - TYPE_ERROR if path exists but is a file.
00457      *       - CONDITION_NOT_MET if predicate from setCondition() was false.
00458      *       - TIMEOUT if timeout elapsed before the operation completed.
00459      */
00460     Result
00461     listDirectory(const std::string& path,
00462                   std::vector<std::string>& children) const;
00463 
00464     /**
00465      * Like listDirectory but throws exceptions upon errors.
00466      */
00467     std::vector<std::string> listDirectoryEx(const std::string& path) const;
00468 
00469     /**
00470      * Make sure a directory does not exist.
00471      * Also removes all direct and indirect children of the directory.
00472      *
00473      * If called with the root directory, this will remove all descendants but
00474      * not actually remove the root directory; it will still return status OK.
00475      *
00476      * \param path
00477      *      The path where there should not be a directory after this call.
00478      * \return
00479      *      Status and error message. Possible errors are:
00480      *       - INVALID_ARGUMENT if path is malformed.
00481      *       - TYPE_ERROR if a parent of path is a file.
00482      *       - TYPE_ERROR if path exists but is a file.
00483      *       - CONDITION_NOT_MET if predicate from setCondition() was false.
00484      *       - TIMEOUT if timeout elapsed before the operation completed.
00485      */
00486     Result
00487     removeDirectory(const std::string& path);
00488 
00489     /**
00490      * Like removeDirectory but throws exceptions upon errors.
00491      */
00492     void
00493     removeDirectoryEx(const std::string& path);
00494 
00495     /**
00496      * Set the value of a file.
00497      * \param path
00498      *      The path where there should be a file with the given contents after
00499      *      this call.
00500      * \param contents
00501      *      The new value associated with the file.
00502      * \return
00503      *      Status and error message. Possible errors are:
00504      *       - INVALID_ARGUMENT if path is malformed.
00505      *       - INVALID_ARGUMENT if contents are too large to fit in a file.
00506      *       - LOOKUP_ERROR if a parent of path does not exist.
00507      *       - TYPE_ERROR if a parent of path is a file.
00508      *       - TYPE_ERROR if path exists but is a directory.
00509      *       - CONDITION_NOT_MET if predicate from setCondition() was false.
00510      *       - TIMEOUT if timeout elapsed before the operation completed.
00511      */
00512     Result
00513     write(const std::string& path, const std::string& contents);
00514 
00515     /**
00516      * Like write but throws exceptions upon errors.
00517      */
00518     void
00519     writeEx(const std::string& path, const std::string& contents);
00520 
00521     /**
00522      * Get the value of a file.
00523      * \param path
00524      *      The path of the file whose contents to read.
00525      * \param contents
00526      *      The current value associated with the file.
00527      * \return
00528      *      Status and error message. Possible errors are:
00529      *       - INVALID_ARGUMENT if path is malformed.
00530      *       - LOOKUP_ERROR if a parent of path does not exist.
00531      *       - LOOKUP_ERROR if path does not exist.
00532      *       - TYPE_ERROR if a parent of path is a file.
00533      *       - TYPE_ERROR if path is a directory.
00534      *       - CONDITION_NOT_MET if predicate from setCondition() was false.
00535      *       - TIMEOUT if timeout elapsed before the operation completed.
00536      */
00537     Result
00538     read(const std::string& path, std::string& contents) const;
00539 
00540     /**
00541      * Like read but throws exceptions upon errors.
00542      */
00543     std::string
00544     readEx(const std::string& path) const;
00545 
00546     /**
00547      * Make sure a file does not exist.
00548      * \param path
00549      *      The path where there should not be a file after this call.
00550      * \return
00551      *      Status and error message. Possible errors are:
00552      *       - INVALID_ARGUMENT if path is malformed.
00553      *       - TYPE_ERROR if a parent of path is a file.
00554      *       - TYPE_ERROR if path exists but is a directory.
00555      *       - CONDITION_NOT_MET if predicate from setCondition() was false.
00556      *       - TIMEOUT if timeout elapsed before the operation completed.
00557      */
00558     Result
00559     removeFile(const std::string& path);
00560 
00561     /**
00562      * Like removeFile but throws exceptions upon errors.
00563      */
00564     void
00565     removeFileEx(const std::string& path);
00566 
00567   private:
00568     /**
00569      * Get a reference to the implementation-specific members of this class.
00570      */
00571     std::shared_ptr<const TreeDetails> getTreeDetails() const;
00572     /**
00573      * Provides mutual exclusion to treeDetails pointer.
00574      */
00575     mutable std::mutex mutex;
00576     /**
00577      * Reference-counted pointer to implementation-specific members. This is
00578      * copy-on-write, so 'mutex' need not be held after taking a reference to
00579      * treeDetails.
00580      */
00581     std::shared_ptr<const TreeDetails> treeDetails;
00582     friend class Cluster;
00583 };
00584 
00585 /**
00586  * When running in testing mode, these callbacks serve as a way for the
00587  * application to interpose on requests and responses to inject failures and
00588  * model dynamic scenarios. See Cluster's constructor for more information.
00589  *
00590  * This is experimental and is not part of LogCabin's public API.
00591  */
00592 class TestingCallbacks {
00593   public:
00594 
00595     /**
00596      * Constructor. Does nothing.
00597      */
00598     TestingCallbacks();
00599 
00600     /**
00601      * Destructor. Does nothing.
00602      */
00603     virtual ~TestingCallbacks();
00604 
00605     /**
00606      * Handle a read-only state machine query, such as Tree::read or
00607      * Tree::listDirectory.
00608      * The default implementation just returns false.
00609      * \param[in,out] request
00610      *      Protocol buffer containing request details. You can modify this and
00611      *      return false to have a slightly different request executed against
00612      *      the in-memory data structure.
00613      * \param[out] response
00614      *      Protocol buffer where response details should be filled in if true
00615      *      is returned.
00616      * \return
00617      *      True if handled, false to query the in-memory data structure.
00618      */
00619     virtual bool stateMachineQuery(
00620         Protocol::Client::StateMachineQuery_Request& request,
00621         Protocol::Client::StateMachineQuery_Response& response);
00622 
00623     /**
00624      * Handle a read-write state machine command, such as Tree::read or
00625      * Tree::listDirectory.
00626      * The default implementation just returns false.
00627      * \param[in,out] request
00628      *      Protocol buffer containing request details. You can modify this and
00629      *      return false to have a slightly different request executed against
00630      *      the in-memory data structure.
00631      * \param[out] response
00632      *      Protocol buffer where response details should be filled in if true
00633      *      is returned.
00634      * \return
00635      *      True if handled, false to query the in-memory data structure.
00636      */
00637     virtual bool stateMachineCommand(
00638         Protocol::Client::StateMachineCommand_Request& request,
00639         Protocol::Client::StateMachineCommand_Response& response);
00640 };
00641 
00642 
00643 /**
00644  * A handle to the LogCabin cluster.
00645  *
00646  * If the client requests changes to the cluster's replicated state machine
00647  * (for example, by writing a value), the client library will first open a
00648  * session with the cluster. It will thereafter periodically send keep-alive
00649  * requests to the cluster during periods of inactivity to maintain this
00650  * session. If communication to the LogCabin cluster is lost for an extended
00651  * period of time, the client's session will expire, and this library will
00652  * force the client to crash.
00653  */
00654 class Cluster {
00655   public:
00656 
00657     /**
00658      * Settings for the client library. These are all optional.
00659      * Currently supported options:
00660      * - clusterUUID (see sample.conf)
00661      * - tcpHeartbeatTimeoutMilliseconds (see sample.conf)
00662      * - tcpConnectTimeoutMilliseconds (see sample.conf)
00663      * - sessionCloseTimeoutMilliseconds:
00664      *      This Cluster object opens a session with LogCabin before issuing
00665      *      any read-write commands to the replicated state machine. When this
00666      *      Cluster object is destroyed, it will attempt to close its session
00667      *      gracefully. This timeout controls the number of milliseconds that
00668      *      the client will wait until giving up on the close session RPC. It
00669      *      defaults to tcpConnectTimeoutMilliseconds, since they should be on
00670      *      the same order of magnitude.
00671      */
00672     typedef std::map<std::string, std::string> Options;
00673 
00674     /**
00675      * Construct a Cluster object for testing purposes only. Instead of
00676      * connecting to a LogCabin cluster, it will keep all state locally in
00677      * memory.
00678      *
00679      * This is experimental and is not part of LogCabin's public API.
00680      *
00681      * \param testingCallbacks
00682      *      These allow the application to interpose on requests. A
00683      *      default-constructed TestingCallbacks will execute requests against
00684      *      an in-memory structure. Applications can pass in classes derived
00685      *      from TestingCallbacks to model failures and more dynamic scenarios.
00686      * \param options
00687      *      Settings for the client library (see #Options).
00688      */
00689     explicit Cluster(std::shared_ptr<TestingCallbacks> testingCallbacks,
00690                      const Options& options = Options());
00691 
00692     /**
00693      * Constructor.
00694      * \param hosts
00695      *      A string describing the hosts in the cluster. This should be of the
00696      *      form host:port, where host is usually a DNS name that resolves to
00697      *      multiple IP addresses. Alternatively, you can pass a list of hosts
00698      *      as host1:port1,host2:port2,host3:port3.
00699      * \param options
00700      *      Settings for the client library (see #Options).
00701      */
00702     explicit Cluster(const std::string& hosts,
00703                      const Options& options = Options());
00704 
00705     /**
00706      * Destructor.
00707      */
00708     ~Cluster();
00709 
00710     /**
00711      * Get the current, stable cluster configuration.
00712      * \return
00713      *      first: configurationId: Identifies the configuration.
00714      *             Pass this to setConfiguration later.
00715      *      second: The list of servers in the configuration.
00716      */
00717     std::pair<uint64_t, Configuration> getConfiguration() const;
00718 
00719     /**
00720      * Get the current, stable cluster configuration.
00721      * \param timeoutNanoseconds
00722      *      Amount of time to wait for getConfiguration to
00723      *      complete. Passing 0 indicates that no timeout is desired.
00724      * \return
00725      *      See GetConfigurationResult
00726      * \since LogCabin v1.2.0.
00727      */
00728     GetConfigurationResult getConfiguration2(
00729                                 uint64_t timeoutNanoseconds) const;
00730 
00731     /**
00732      * Like getConfiguration2 but throws exceptions upon errors.
00733      * \since LogCabin v1.2.0.
00734      */
00735     GetConfigurationResult getConfiguration2Ex(
00736                                 uint64_t timeoutNanoseconds) const;
00737 
00738     /**
00739      * Change the cluster's configuration.
00740      * \param oldId
00741      *      The ID of the cluster's current configuration.
00742      * \param newConfiguration
00743      *      The list of servers in the new configuration.
00744      */
00745     ConfigurationResult setConfiguration(
00746                                 uint64_t oldId,
00747                                 const Configuration& newConfiguration);
00748 
00749     /**
00750      * Like setConfiguration but allows a timeout.
00751      * \param oldId
00752      *      The ID of the cluster's current configuration.
00753      * \param newConfiguration
00754      *      The list of servers in the new configuration.
00755      * \param timeoutNanoseconds
00756      *      Amount of time to wait for the call to complete. 0=wait
00757      *      forever
00758      * \since LogCabin v1.2.0.
00759      */
00760     ConfigurationResult setConfiguration2(
00761                                 uint64_t oldId,
00762                                 const Configuration& newConfiguration,
00763                                 uint64_t timeoutNanoseconds);
00764     /**
00765      * Like setConfiguration2 but throws exceptions upon errors.
00766      * \since LogCabin v1.2.0.
00767      */
00768     ConfigurationResult setConfiguration2Ex(
00769                                 uint64_t oldId,
00770                                 const Configuration& newConfiguration,
00771                                 uint64_t timeoutNanoseconds);
00772 
00773     /**
00774      * Retrieve basic information from the given server, like its ID and the
00775      * addresses on which it is listening.
00776      * \param host
00777      *      The hostname or IP address of the server to retrieve stats from. It
00778      *      is recommended that you do not use a DNS name that resolves to
00779      *      multiple hosts here.
00780      * \param timeoutNanoseconds
00781      *      Abort the operation if it has not completed within the specified
00782      *      period of time. Time is specified in nanoseconds, and the special
00783      *      value of 0 indicates no timeout.
00784      * \warning
00785      *      The client library does not currently implement timeouts for DNS
00786      *      lookups. See https://github.com/logcabin/logcabin/issues/75
00787      * \param[out] info
00788      *      Protocol buffer of Stats as retrieved from the server.
00789      * \return
00790      *      Either OK or TIMEOUT.
00791      */
00792     Result
00793     getServerInfo(const std::string& host,
00794                   uint64_t timeoutNanoseconds,
00795                   Server& info);
00796     /**
00797      * Like getServerInfo but throws exceptions upon errors.
00798      */
00799     Server
00800     getServerInfoEx(const std::string& host,
00801                     uint64_t timeoutNanoseconds);
00802 
00803     /**
00804      * Retrieve statistics from the given server, which are useful for
00805      * diagnostics.
00806      * \param host
00807      *      The hostname or IP address of the server to retrieve stats from. It
00808      *      is recommended that you do not use a DNS name that resolves to
00809      *      multiple hosts here.
00810      * \param timeoutNanoseconds
00811      *      Abort the operation if it has not completed within the specified
00812      *      period of time. Time is specified in nanoseconds, and the special
00813      *      value of 0 indicates no timeout.
00814      * \warning
00815      *      The client library does not currently implement timeouts for DNS
00816      *      lookups. See https://github.com/logcabin/logcabin/issues/75
00817      * \param[out] stats
00818      *      Protocol buffer of Stats as retrieved from the server.
00819      * \return
00820      *      Either OK or TIMEOUT.
00821      */
00822     Result
00823     getServerStats(const std::string& host,
00824                    uint64_t timeoutNanoseconds,
00825                    Protocol::ServerStats& stats);
00826     /**
00827      * Like getServerStats but throws exceptions upon errors.
00828      */
00829     Protocol::ServerStats
00830     getServerStatsEx(const std::string& host,
00831                      uint64_t timeoutNanoseconds);
00832 
00833     /**
00834      * Return an object to access the hierarchical key-value store.
00835      * \return
00836      *      A Tree object with the working directory of '/'.
00837      */
00838     Tree getTree();
00839 
00840   private:
00841     std::shared_ptr<ClientImpl> clientImpl;
00842 };
00843 
00844 } // namespace LogCabin::Client
00845 } // namespace LogCabin
00846 
00847 #endif /* LOGCABIN_INCLUDE_LOGCABIN_CLIENT_H */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines