LogCabin
|
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