LogCabin
Client/Backoff.cc
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 #include "Client/Backoff.h"
00017 
00018 namespace LogCabin {
00019 namespace Client {
00020 
00021 Backoff::Backoff(uint64_t windowCount, uint64_t windowNanos)
00022     : mutex()
00023     , windowCount(std::max(1UL, windowCount))
00024     , windowDuration(windowNanos)
00025     , startTimes()
00026 {
00027     for (uint64_t i = 0; i < windowCount; ++i)
00028         startTimes.push_back(TimePoint::min());
00029 }
00030 
00031 Backoff::~Backoff()
00032 {
00033 }
00034 
00035 void
00036 Backoff::delayAndBegin(TimePoint timeout)
00037 {
00038     std::lock_guard<std::mutex> lockGuard(mutex);
00039     TimePoint now = Clock::now();
00040     if (now > timeout)
00041         return;
00042     TimePoint oldest = startTimes.at(0);
00043     TimePoint permissible = oldest + windowDuration;
00044     if (permissible > now) {
00045         if (permissible > timeout) { // now < timeout < permissible
00046             Core::Time::sleep(timeout);
00047             return;
00048         } else { // now < permissible < timeout
00049             Core::Time::sleep(permissible);
00050             now = Clock::now();
00051         }
00052     }
00053     startTimes.pop_front();
00054     startTimes.push_back(now);
00055 }
00056 
00057 } // namespace LogCabin::Client
00058 } // namespace LogCabin
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines