12 #include "aegis/config.hpp"
16 #include <unordered_map>
23 #include <spdlog/fmt/fmt.h>
27 #define WIN32_LEAN_AND_MEAN
30 #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
32 #include <sys/resource.h>
33 #if defined(__APPLE__) && defined(__MACH__)
34 #include <mach/mach.h>
35 #elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__)))
38 #elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
42 #error "Cannot define getPeakRSS( ) or getCurrentRSS( ) for an unknown OS."
57 enum class shard_status
70 enum class heartbeat_status
80 std::string perf_run(
const std::string & name, Func f)
83 ss <<
"Running [" << name <<
"]\n";
84 auto n = std::chrono::steady_clock::now();
88 auto n_end = std::chrono::steady_clock::now();
90 ss <<
"Time: [" << std::chrono::duration_cast<std::chrono::microseconds>(n_end - n).count() <<
"us]\n";
99 template<
class Duration,
class int_type,
typename ratio = std::nano>
100 constexpr Duration to_t(
const std::chrono::duration<int_type, ratio> & t)
102 return std::chrono::duration_cast<Duration>(t);
110 template<
typename Duration,
typename T = std::chrono::steady_clock::time_po
int>
111 constexpr Duration to_t(
const T & t)
113 return std::chrono::duration_cast<Duration>(t.time_since_epoch());
123 template<
class S,
typename ratio = std::nano>
124 constexpr S to_ms(
const std::chrono::duration<S, ratio> & t)
126 return to_t<std::chrono::milliseconds>(t).count();
136 template<
typename T = std::chrono::steady_clock::time_po
int>
137 constexpr
typename T::rep to_ms(
const T & t)
139 return to_t<std::chrono::duration<typename T::rep, std::milli>>(t.time_since_epoch()).count();
147 inline std::chrono::system_clock::time_point from_iso8601(
const std::string & _time_t)
150 std::istringstream ss(_time_t);
151 ss >> std::get_time(&tm,
"%Y-%m-%dT%H:%M:%S");
152 return std::chrono::system_clock::from_time_t(std::mktime(&tm));
155 inline std::string to_iso8601(std::chrono::system_clock::time_point tp)
157 auto itt = std::chrono::system_clock::to_time_t(tp);
158 std::ostringstream ss;
159 ss << std::put_time(gmtime(&itt),
"%FT%TZ");
163 inline std::string to_iso8601(int64_t tp)
165 auto itt = std::chrono::system_clock::to_time_t(std::chrono::time_point<std::chrono::system_clock>(std::chrono::milliseconds(tp)));
166 std::ostringstream ss;
167 ss << std::put_time(gmtime(&itt),
"%FT%TZ");
176 inline std::chrono::system_clock::time_point from_http_date(
const std::string & _time_t)
179 std::istringstream ss(_time_t);
180 ss >> std::get_time(&tm,
"%a, %d %b %Y %T");
181 return std::chrono::system_clock::from_time_t(std::mktime(&tm));
185 inline std::string url_encode(
const std::string & value)
187 std::ostringstream escaped;
191 for (std::string::value_type c : value)
194 if (isalnum(c) || c ==
'-' || c ==
'_' || c ==
'.' || c ==
'~')
201 escaped << std::uppercase;
202 escaped <<
'%' << std::setw(2) << int((
unsigned char)c);
203 escaped << std::nouppercase;
206 return escaped.str();
209 inline std::string escape_quotes(
const std::string & value)
211 std::ostringstream escaped;
213 for (std::string::value_type c : value)
219 return escaped.str();
222 inline char random_letter()
224 return (rand() % 2) ? (rand() % 26 +
'a') : (rand() % 26 +
'A');
227 inline std::string random_string(
const std::size_t length)
230 temp.reserve(length);
232 for (
int i = 0; i < length; ++i)
233 temp.push_back(random_letter());
238 inline std::string uptime_str(std::chrono::steady_clock::time_point _start) noexcept
240 using seconds = std::chrono::duration<int, std::ratio<1, 1>>;
241 using minutes = std::chrono::duration<int, std::ratio<60, 1>>;
242 using hours = std::chrono::duration<int, std::ratio<3600, 1>>;
243 using days = std::chrono::duration<int, std::ratio<24 * 3600, 1>>;
245 std::stringstream ss;
246 std::chrono::time_point<std::chrono::steady_clock> now_t = std::chrono::steady_clock::now();
248 auto time_is = now_t - _start;
249 auto d = std::chrono::duration_cast<days>(time_is).count();
251 auto h = std::chrono::duration_cast<hours>(time_is).count();
253 auto m = std::chrono::duration_cast<minutes>(time_is).count();
254 time_is -= minutes(m);
255 auto s = std::chrono::duration_cast<seconds>(time_is).count();
267 inline std::string format_bytes(uint64_t size)
269 if ((size > 1024ull * 5) && (size < 1024ull * 1024 * 5))
271 return fmt::format(
"{:.3f} KB",
double(size) / 1024);
273 if ((size > 1024ull * 1024 * 5) && (size < 1024ull * 1024 * 1024 * 5))
275 return fmt::format(
"{:.3f} MB", (
double(size) / 1024) / 1024);
277 if (size > 1024ull * 1024 * 1024 * 5)
279 return fmt::format(
"{:.3f} GB", ((
double(size) / 1024) / 1024) / 1024);
281 return fmt::format(
"{} B", size);
300 #if defined(__clang__) || defined(__GNUC__)
301 # if (__cplusplus >= 201703)
302 # define CXX_VERSION 17
304 # define CXX_VERSION 14
306 #elif defined(AEGIS_MSVC)
307 # if _MSVC_LANG == 201703L || _HAS_CXX17 == 1
308 # define CXX_VERSION 17
310 # define CXX_VERSION 14
316 constexpr
const char * m_platform =
"Windows x64";
317 constexpr OS m_os = OS::Windows64;
318 #elif defined(_WIN32)
319 constexpr
const char * m_platform =
"Windows x86";
320 constexpr OS m_os = OS::Windows32;
321 #elif defined(__CYGWIN__) && !defined(_WIN32)
322 constexpr
const char * m_platform =
"Windows (Cygwin)";
323 constexpr OS m_os = OS::undefined;
324 #elif defined(__linux__)
325 constexpr
const char * m_platform =
"Linux";
326 constexpr OS m_os = OS::Linux;
327 #elif defined(__unix__) || defined(__APPLE__) && defined(__MACH__)
328 #include <sys/param.h>
330 constexpr
const char * m_platform =
"*BSD";
331 constexpr OS m_os = OS::BSD;
333 #elif defined(__APPLE__) && defined(__MACH__) // Apple OSX and iOS (Darwin)
334 #include <TargetConditionals.h>
335 constexpr
const char * m_platform =
"OSX";
336 constexpr OS m_os = OS::Mac;
338 constexpr
const char * m_platform =
"undefined";
339 constexpr OS m_os = OS::undefined;
345 inline const std::string get_platform()
347 return std::string(m_platform);
365 size_t getCurrentRSS();
367 inline size_t getPeakRSS()
371 PROCESS_MEMORY_COUNTERS info;
372 GetProcessMemoryInfo(GetCurrentProcess(), &info,
sizeof(info));
373 return (
size_t)info.PeakWorkingSetSize;
375 #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
377 struct rusage rusage;
378 getrusage(RUSAGE_SELF, &rusage);
379 #if defined(__APPLE__) && defined(__MACH__)
380 return (
size_t)rusage.ru_maxrss;
382 return (
size_t)(rusage.ru_maxrss * 1024L);
395 inline size_t getCurrentRSS()
399 PROCESS_MEMORY_COUNTERS info;
400 GetProcessMemoryInfo(GetCurrentProcess(), &info,
sizeof(info));
401 return (
size_t)info.WorkingSetSize;
403 #elif defined(__APPLE__) && defined(__MACH__)
405 struct mach_task_basic_info info;
406 mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
407 if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO,
408 (task_info_t)&info, &infoCount) != KERN_SUCCESS)
410 return (
size_t)info.resident_size;
412 #elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
416 if ((fp = fopen(
"/proc/self/statm",
"r")) == NULL)
418 if (fscanf(fp,
"%*s%ld", &rss) != 1)
424 return (
size_t)rss * (size_t)sysconf(_SC_PAGESIZE);