LogCabin
Client/Backoff.h
Go to the documentation of this file.
00001 /* Copyright (c) 2014-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_BACKOFF_H
00017 #define LOGCABIN_CLIENT_BACKOFF_H
00018 
00019 #include <cinttypes>
00020 #include <deque>
00021 #include <mutex>
00022 
00023 #include "Core/Time.h"
00024 
00025 namespace LogCabin {
00026 namespace Client {
00027 
00028 /**
00029  * A simple backoff mechanism. Currently used in the client library to
00030  * rate-limit the creation of new TCP connections.
00031  */
00032 class Backoff {
00033   public:
00034     /// Clock used for keeping track of when operations started.
00035     typedef Core::Time::SteadyClock Clock;
00036     /// Point in time on #Clock. Used for timeouts.
00037     typedef Clock::time_point TimePoint;
00038 
00039     /**
00040      * Constructor.
00041      * \param windowCount
00042      *      At most this many operations are allowed in any windowNanos period
00043      *      of time.
00044      * \param windowNanos
00045      *      The duration over which at most windowCount operations are allowed.
00046      * \warning
00047      *      The memory usage of this class is proportional to windowCount.
00048      */
00049     Backoff(uint64_t windowCount, uint64_t windowNanos);
00050 
00051     /**
00052      * Destructor.
00053      */
00054     ~Backoff();
00055 
00056     /**
00057      * This is invoked before beginning a new operation. If the operation may
00058      * not proceed yet, this method sleeps until starting the operation becomes
00059      * permissible.
00060      * \param timeout
00061      *      Maximum time at which to stop sleeping and return, without marking
00062      *      the operation as having started.
00063      */
00064     void delayAndBegin(TimePoint timeout);
00065 
00066   private:
00067 
00068     /**
00069      * Protects all of the following member variables in this class.
00070      */
00071     std::mutex mutex;
00072 
00073     /**
00074      * At most #windowCount operations are allowed in any #windowDuration
00075      * period of time.
00076      */
00077     uint64_t windowCount;
00078 
00079     /**
00080      * See #windowCount.
00081      */
00082     std::chrono::nanoseconds windowDuration;
00083 
00084     /**
00085      * The times when the last #windowCount operations were initiated. If fewer
00086      * than #windowCount operations have been initiated, this is padded with
00087      * negative infinity. The front time is the oldest, and the back is the
00088      * most recent.
00089      */
00090     std::deque<TimePoint> startTimes;
00091 };
00092 
00093 } // namespace LogCabin::Client
00094 } // namespace LogCabin
00095 
00096 #endif /* LOGCABIN_CLIENT_BACKOFF_H */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines