Replace duration/timestamp formats with functions

We're defining formats for std::chrono types, which feels wrong (because
fmt itself also has these), so just replace them with functions:

short_time_from_now(...) gives a short "in 14m12s" or "5.123s ago" time
span relative to now, given a time point.  Precision gets reduced for
larger deviations from now (e.g. "4h12m ago").

ToString(Duration_t) gives a string such as "-3h22m02.123s" for a
duration.
pull/2039/head
Jason Rhinelander 2 years ago
parent 67e002c8ee
commit b6924f3ef1
No known key found for this signature in database
GPG Key ID: C4992CE7A88D4262

@ -411,13 +411,17 @@ namespace llarp
if (self->record.work && self->record.work->IsValid(now)) if (self->record.work && self->record.work->IsValid(now))
{ {
llarp::LogDebug( llarp::LogDebug(
"LRCM extended lifetime by ", self->record.work->extendedLifetime, " for ", info); "LRCM extended lifetime by ",
ToString(self->record.work->extendedLifetime),
" for ",
info);
self->hop->lifetime += self->record.work->extendedLifetime; self->hop->lifetime += self->record.work->extendedLifetime;
} }
else if (self->record.lifetime < path::default_lifetime && self->record.lifetime > 10s) else if (self->record.lifetime < path::default_lifetime && self->record.lifetime > 10s)
{ {
self->hop->lifetime = self->record.lifetime; self->hop->lifetime = self->record.lifetime;
llarp::LogDebug("LRCM short lifespan set to ", self->hop->lifetime, " for ", info); llarp::LogDebug(
"LRCM short lifespan set to ", ToString(self->hop->lifetime), " for ", info);
} }
// TODO: check if we really want to accept it // TODO: check if we really want to accept it

@ -308,7 +308,7 @@ namespace llarp
} }
else if (st == ePathEstablished && _status == ePathBuilding) else if (st == ePathEstablished && _status == ePathBuilding)
{ {
LogInfo("path ", Name(), " is built, took ", now - buildStarted); LogInfo("path ", Name(), " is built, took ", ToString(now - buildStarted));
} }
else if (st == ePathTimeout && _status == ePathEstablished) else if (st == ePathTimeout && _status == ePathEstablished)
{ {
@ -449,7 +449,7 @@ namespace llarp
const auto dlt = now - buildStarted; const auto dlt = now - buildStarted;
if (dlt >= path::build_timeout) if (dlt >= path::build_timeout)
{ {
LogWarn(Name(), " waited for ", dlt, " and no path was built"); LogWarn(Name(), " waited for ", ToString(dlt), " and no path was built");
r->routerProfiling().MarkPathFail(this); r->routerProfiling().MarkPathFail(this);
EnterState(ePathExpired, now); EnterState(ePathExpired, now);
return; return;
@ -473,7 +473,7 @@ namespace llarp
dlt = now - m_LastRecvMessage; dlt = now - m_LastRecvMessage;
if (dlt >= path::alive_timeout) if (dlt >= path::alive_timeout)
{ {
LogWarn(Name(), " waited for ", dlt, " and path looks dead"); LogWarn(Name(), " waited for ", ToString(dlt), " and path looks dead");
r->routerProfiling().MarkPathFail(this); r->routerProfiling().MarkPathFail(this);
EnterState(ePathTimeout, now); EnterState(ePathTimeout, now);
} }

@ -461,7 +461,7 @@ namespace llarp
buildIntervalLimit = PATH_BUILD_RATE; buildIntervalLimit = PATH_BUILD_RATE;
m_router->routerProfiling().MarkPathSuccess(p.get()); m_router->routerProfiling().MarkPathSuccess(p.get());
LogInfo(p->Name(), " built latency=", p->intro.latency); LogInfo(p->Name(), " built latency=", ToString(p->intro.latency));
m_BuildStats.success++; m_BuildStats.success++;
} }
@ -478,7 +478,7 @@ namespace llarp
static constexpr std::chrono::milliseconds MaxBuildInterval = 30s; static constexpr std::chrono::milliseconds MaxBuildInterval = 30s;
// linear backoff // linear backoff
buildIntervalLimit = std::min(PATH_BUILD_RATE + buildIntervalLimit, MaxBuildInterval); buildIntervalLimit = std::min(PATH_BUILD_RATE + buildIntervalLimit, MaxBuildInterval);
LogWarn(Name(), " build interval is now ", buildIntervalLimit); LogWarn(Name(), " build interval is now ", ToString(buildIntervalLimit));
} }
void void

@ -862,11 +862,11 @@ namespace llarp
if (IsServiceNode()) if (IsServiceNode())
{ {
LogInfo(NumberOfConnectedClients(), " client connections"); LogInfo(NumberOfConnectedClients(), " client connections");
LogInfo(_rc.Age(now), " since we last updated our RC"); LogInfo(ToString(_rc.Age(now)), " since we last updated our RC");
LogInfo(_rc.TimeUntilExpires(now), " until our RC expires"); LogInfo(ToString(_rc.TimeUntilExpires(now)), " until our RC expires");
} }
if (m_LastStatsReport > 0s) if (m_LastStatsReport > 0s)
LogInfo(now - m_LastStatsReport, " last reported stats"); LogInfo(ToString(now - m_LastStatsReport), " last reported stats");
m_LastStatsReport = now; m_LastStatsReport = now;
} }
@ -880,7 +880,7 @@ namespace llarp
if (const auto delta = now - _lastTick; _lastTick != 0s and delta > TimeskipDetectedDuration) if (const auto delta = now - _lastTick; _lastTick != 0s and delta > TimeskipDetectedDuration)
{ {
// we detected a time skip into the futre, thaw the network // we detected a time skip into the futre, thaw the network
LogWarn("Timeskip of ", delta, " detected. Resetting network state"); LogWarn("Timeskip of ", ToString(delta), " detected. Resetting network state");
Thaw(); Thaw();
} }
@ -902,14 +902,12 @@ namespace llarp
" | {} active paths | block {} ", " | {} active paths | block {} ",
pathContext().CurrentTransitPaths(), pathContext().CurrentTransitPaths(),
(m_lokidRpcClient ? m_lokidRpcClient->BlockHeight() : 0)); (m_lokidRpcClient ? m_lokidRpcClient->BlockHeight() : 0));
auto maybe_last = _rcGossiper.LastGossipAt();
fmt::format_to( fmt::format_to(
out, out,
" | gossip: (next/last) {} / ", " | gossip: (next/last) {} / {}",
time_delta<std::chrono::seconds>{_rcGossiper.NextGossipAt()}); short_time_from_now(_rcGossiper.NextGossipAt()),
if (auto maybe = _rcGossiper.LastGossipAt()) maybe_last ? short_time_from_now(*maybe_last) : "never");
fmt::format_to(out, "{}", time_delta<std::chrono::seconds>{*maybe});
else
fmt::format_to(out, "never");
} }
else else
{ {

@ -1,6 +1,7 @@
#include "time.hpp" #include "time.hpp"
#include <chrono> #include <chrono>
#include <iomanip> #include <iomanip>
#include "types.hpp"
namespace llarp namespace llarp
{ {
@ -49,4 +50,59 @@ namespace llarp
{ {
return ToMS(t); return ToMS(t);
} }
static auto
extract_h_m_s_ms(const Duration_t& dur)
{
return std::make_tuple(
std::chrono::duration_cast<std::chrono::hours>(dur).count(),
(std::chrono::duration_cast<std::chrono::minutes>(dur) % 1h).count(),
(std::chrono::duration_cast<std::chrono::seconds>(dur) % 1min).count(),
(std::chrono::duration_cast<std::chrono::milliseconds>(dur) % 1s).count());
}
std::string
short_time_from_now(const TimePoint_t& t, const Duration_t& now_threshold)
{
auto delta = std::chrono::duration_cast<Duration_t>(llarp::TimePoint_t::clock::now() - t);
bool future = delta < 0s;
if (future)
delta = -delta;
auto [hours, mins, secs, ms] = extract_h_m_s_ms(delta);
using namespace fmt::literals;
return fmt::format(
delta < now_threshold ? "now"
: delta < 10s ? "{in}{secs:d}.{ms:03d}s{ago}"
: delta < 1h ? "{in}{mins:d}m{secs:02d}s{ago}"
: "{in}{hours:d}h{mins:02d}m{ago}",
"in"_a = future ? "in " : "",
"ago"_a = future ? "" : " ago",
"hours"_a = hours,
"mins"_a = mins,
"secs"_a = secs,
"ms"_a = ms);
}
std::string
ToString(Duration_t delta)
{
bool neg = delta < 0s;
if (neg)
delta = -delta;
auto [hours, mins, secs, ms] = extract_h_m_s_ms(delta);
using namespace fmt::literals;
return fmt::format(
delta < 1min ? "{neg}{secs:d}.{ms:03d}s"
: delta < 1h ? "{neg}{mins:d}m{secs:02d}.{ms:03d}s"
: "{neg}{hours:d}h{mins:02d}m{secs:02d}.{ms:03d}s",
"neg"_a = neg ? "-" : "",
"hours"_a = hours,
"mins"_a = mins,
"secs"_a = secs,
"ms"_a = ms);
}
} // namespace llarp } // namespace llarp

@ -25,69 +25,25 @@ namespace llarp
nlohmann::json nlohmann::json
to_json(const Duration_t& t); to_json(const Duration_t& t);
template <typename Time_Duration> // Returns a string such as "27m13s ago" or "in 1h12m" or "now". You get precision of minutes
struct time_delta // (for >=1h), seconds (>=10s), or milliseconds. The `now_threshold` argument controls how close
{ // to current time (default 1s) the time has to be to get the "now" argument.
const TimePoint_t at; std::string
}; short_time_from_now(const TimePoint_t& t, const Duration_t& now_threshold = 1s);
} // namespace llarp
namespace fmt // Makes a duration human readable. This always has full millisecond precision, but formats up to
{ // hours. E.g. "-4h04m12.123s" or "1234h00m09.876s.
template <typename Time_Duration> std::string
struct formatter<llarp::time_delta<Time_Duration>> : formatter<std::string> ToString(Duration_t t);
{
template <typename FormatContext>
auto
format(const llarp::time_delta<Time_Duration>& td, FormatContext& ctx)
{
const auto dlt =
std::chrono::duration_cast<Time_Duration>(llarp::TimePoint_t::clock::now() - td.at);
using Parent = formatter<std::string>;
if (dlt > 0s)
return Parent::format(fmt::format("{} ago", dlt), ctx);
if (dlt < 0s)
return Parent::format(fmt::format("in {}", -dlt), ctx);
return Parent::format("now", ctx);
}
};
template <> } // namespace llarp
struct formatter<llarp::Duration_t> : formatter<std::string>
{
template <typename FormatContext>
auto
format(llarp::Duration_t elapsed, FormatContext& ctx)
{
bool neg = elapsed < 0s;
if (neg)
elapsed = -elapsed;
const auto hours = std::chrono::duration_cast<std::chrono::hours>(elapsed).count();
const auto mins = (std::chrono::duration_cast<std::chrono::minutes>(elapsed) % 1h).count();
const auto secs = (std::chrono::duration_cast<std::chrono::seconds>(elapsed) % 1min).count();
const auto ms = (std::chrono::duration_cast<std::chrono::milliseconds>(elapsed) % 1s).count();
return formatter<std::string>::format(
fmt::format(
elapsed >= 1h ? "{0}{1:d}h{2:02d}m{3:02d}.{4:03d}s"
: elapsed >= 1min ? "{0}{2:d}m{3:02d}.{4:03d}s"
: "{0}{3:d}.{4:03d}s",
neg ? "-" : "",
hours,
mins,
secs,
ms),
ctx);
}
};
template <> // Duration_t is currently just a typedef to std::chrono::milliseconds, and specializing
struct formatter<llarp::TimePoint_t> : formatter<std::string> // that seems wrong; leaving this here to remind us not to add it back in again.
{ // namespace fmt
template <typename FormatContext> //{
auto // template <>
format(const llarp::TimePoint_t& tp, FormatContext& ctx) // struct formatter<llarp::Duration_t>
{ // {
return formatter<std::string>::format(fmt::format("{:%c %Z}", tp), ctx); // };
} //} // namespace fmt
};
} // namespace fmt

Loading…
Cancel
Save