LogCabin
Client/SessionManager.h
Go to the documentation of this file.
00001 /* Copyright (c) 2015 Diego Ongaro
00002  *
00003  * Permission to use, copy, modify, and distribute this software for any
00004  * purpose with or without fee is hereby granted, provided that the above
00005  * copyright notice and this permission notice appear in all copies.
00006  *
00007  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
00008  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00009  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
00010  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00011  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00012  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
00013  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00014  */
00015 
00016 #ifndef LOGCABIN_CLIENT_SESSIONMANAGER_H
00017 #define LOGCABIN_CLIENT_SESSIONMANAGER_H
00018 
00019 #include <cstdint>
00020 #include <memory>
00021 #include <mutex>
00022 #include <string>
00023 
00024 #include "RPC/Address.h"
00025 
00026 namespace LogCabin {
00027 
00028 // forward declaration
00029 namespace Core {
00030 class Config;
00031 }
00032 
00033 // forward declaration
00034 namespace Event {
00035 class Loop;
00036 }
00037 
00038 // forward declaration
00039 namespace RPC {
00040 class ClientSession;
00041 }
00042 
00043 namespace Client {
00044 
00045 /**
00046  * Used to create RPC::ClientSession objects and then immediately call
00047  * VerifyRecipient RPCs on them.
00048  *
00049  * TODO(ongaro): Consider encapsulating Backoff mechanism in here as well,
00050  * since session creation ought to be paired with Backoff.
00051  */
00052 class SessionManager {
00053   public:
00054 
00055     /**
00056      * Gets and sets a value while holding a mutex.
00057      */
00058     template<typename T>
00059     class LockedAssignment {
00060       public:
00061         /**
00062          * Default constructor: empty.
00063          */
00064         LockedAssignment()
00065             : mutex()
00066             , empty(true)
00067             , value()
00068         {
00069         }
00070 
00071         /**
00072          * Constructor that initializes this object with the given value.
00073          */
00074         explicit LockedAssignment(T value)
00075             : mutex()
00076             , empty(false)
00077             , value(value)
00078         {
00079         }
00080 
00081         /**
00082          * Returns true and the value if there is one, or false and a default
00083          * constructed value otherwise.
00084          */
00085         std::pair<bool, T> get() const {
00086             std::lock_guard<std::mutex> lockGuard(mutex);
00087             if (empty)
00088                 return {false, T()};
00089             T copy = value;
00090             return {true, copy};
00091         }
00092 
00093         /**
00094          * Returns the value if there is one, or a default constructed value
00095          * otherwise.
00096          */
00097         T getOrDefault() const {
00098             std::lock_guard<std::mutex> lockGuard(mutex);
00099             if (empty)
00100                 return T();
00101             T copy = value;
00102             return copy;
00103         }
00104 
00105         /**
00106          * Clears out the value, if any.
00107          */
00108         void clear() {
00109             std::lock_guard<std::mutex> lockGuard(mutex);
00110             empty = true;
00111             value = T();
00112         }
00113 
00114         /**
00115          * Overwrites the value with the given one.
00116          */
00117         void set(const T& newValue) {
00118             std::lock_guard<std::mutex> lockGuard(mutex);
00119             empty = false;
00120             value = newValue;
00121         }
00122 
00123       private:
00124         mutable std::mutex mutex;
00125         bool empty;
00126         T value;
00127     };
00128 
00129     typedef LockedAssignment<std::string> ClusterUUID;
00130     typedef LockedAssignment<uint64_t> ServerId;
00131 
00132     /**
00133      * Construtor. Takes a couple of parameters that are common to all sessions
00134      * so that you don't have to repeatedly provide them to createSession.
00135      * \param eventLoop
00136      *      Event::Loop that will be used to find out when the session's
00137      *      underlying socket may be read from or written to without blocking.
00138      *      This object keeps a reference.
00139      * \param config
00140      *      General settings. This object keeps a reference.
00141      */
00142     SessionManager(Event::Loop& eventLoop,
00143                    const Core::Config& config);
00144 
00145 
00146     /**
00147      * Connect to the given address.
00148      * \param address
00149      *      The RPC server address on which to connect.
00150      * \param timeout
00151      *      After this time has elapsed, stop trying to initiate the connection
00152      *      and leave the session in an error state.
00153      * \param[in,out] clusterUUID
00154      *      If set, the recipient will confirm that it matches this cluster
00155      *      UUID. If empty and the recipient returns one, this will be set.
00156      * \param[in,out] serverId
00157      *      If set, the recipient will confirm that it has this server ID. If
00158      *      empty and the recipient returns one, this will be set.
00159      */
00160     std::shared_ptr<RPC::ClientSession>
00161     createSession(const RPC::Address& address,
00162                   RPC::Address::TimePoint timeout,
00163                   ClusterUUID* clusterUUID = NULL,
00164                   ServerId* serverId = NULL);
00165 
00166     Event::Loop& eventLoop;
00167   private:
00168     const Core::Config& config;
00169     /**
00170      * Used only for unit testing. Set to false, normally.
00171      */
00172     bool skipVerify;
00173 };
00174 
00175 } // namespace LogCabin::Client
00176 } // namespace LogCabin
00177 
00178 #endif /* LOGCABIN_CLIENT_SESSIONMANAGER_H */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines