diff options
| author | Dan Engelbrecht <[email protected]> | 2024-11-06 09:08:02 +0100 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2024-11-06 09:08:02 +0100 |
| commit | 9285f6d0b00d720957b69b5ecd464cce1dee89bf (patch) | |
| tree | 08518888b701e54059cfec0de5f56223c332d538 /src/zen/zen.cpp | |
| parent | sponsor process attach hardening (#208) (diff) | |
| download | archived-zen-9285f6d0b00d720957b69b5ecd464cce1dee89bf.tar.xz archived-zen-9285f6d0b00d720957b69b5ecd464cce1dee89bf.zip | |
Improved oplog import/export progress indicator at commandline (#206)
Nicer progress bar during oplog import/export
Verify that oplog has not been deleted from disk behind our back
Diffstat (limited to 'src/zen/zen.cpp')
| -rw-r--r-- | src/zen/zen.cpp | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/src/zen/zen.cpp b/src/zen/zen.cpp index 026e8c84f..eb67649b8 100644 --- a/src/zen/zen.cpp +++ b/src/zen/zen.cpp @@ -25,6 +25,7 @@ #include "cmds/workspaces_cmd.h" #include <zencore/filesystem.h> +#include <zencore/fmtutils.h> #include <zencore/logging.h> #include <zencore/scopeguard.h> #include <zencore/string.h> @@ -252,6 +253,106 @@ ZenCmdBase::ResolveTargetHostSpec(const std::string& InHostSpec) return ResolveTargetHostSpec(InHostSpec, /* out */ Dummy); } +ProgressBar::ProgressBar(bool PlainProgress) : m_PlainProgress(PlainProgress), m_LastUpdateMS(m_SW.GetElapsedTimeMs() - 10000) +{ +} + +ProgressBar::~ProgressBar() +{ + try + { + Finish(); + } + catch (const std::exception& Ex) + { + ZEN_ERROR("ProgressBar::~ProgressBar() failed with {}", Ex.what()); + } +} + +void +ProgressBar::UpdateState(const State& NewState, bool DoLinebreak) +{ + if (DoLinebreak == false && m_State == NewState) + { + return; + } + + uint64_t ElapsedTimeMS = m_SW.GetElapsedTimeMs(); + if (!DoLinebreak && (NewState.Task == m_State.Task) && ((m_LastUpdateMS + 200) > ElapsedTimeMS)) + { + return; + } + + m_LastUpdateMS = ElapsedTimeMS; + + size_t PercentDone = + NewState.TotalCount > 0u ? gsl::narrow<uint8_t>((100 * (NewState.TotalCount - NewState.RemainingCount)) / NewState.TotalCount) : 0u; + + if (m_PlainProgress) + { + ZEN_CONSOLE("{} {}% ({})", NewState.Task, PercentDone, NiceTimeSpanMs(ElapsedTimeMS)); + } + else + { + size_t ProgressBarSize = 20; + + size_t ProgressBarCount = (ProgressBarSize * PercentDone) / 100; + uint64_t Completed = NewState.TotalCount - NewState.RemainingCount; + uint64_t ETAMS = (Completed > 0) ? (ElapsedTimeMS * NewState.RemainingCount) / Completed : 0; + std::string ETA = (ETAMS > 0) ? fmt::format(" ETA {}", NiceTimeSpanMs(ETAMS)) : ""; + + std::string Output = fmt::format("\r{} {:#3}%: |{}{}|: {}{}{}", + NewState.Task, + PercentDone, + std::string(ProgressBarCount, '#'), + std::string(ProgressBarSize - ProgressBarCount, ' '), + NiceTimeSpanMs(ElapsedTimeMS), + ETA, + NewState.Details.empty() ? "" : fmt::format(". {}", NewState.Details)); + std::string::size_type EraseLength = m_LastOutputLength > Output.length() ? (m_LastOutputLength - Output.length()) : 0; + printf("%s%s%s", Output.c_str(), std::string(EraseLength, ' ').c_str(), DoLinebreak ? "\n" : ""); + m_LastOutputLength = DoLinebreak ? 0 : Output.length(); + m_State = NewState; + } +} + +void +ProgressBar::ForceLinebreak() +{ + if (m_LastOutputLength > 0) + { + State NewState = m_State; + UpdateState(NewState, /*DoLinebreak*/ true); + } +} + +void +ProgressBar::Finish() +{ + if (m_LastOutputLength > 0 && m_State.RemainingCount > 0) + { + State NewState = m_State; + NewState.RemainingCount = 0; + NewState.Details = ""; + UpdateState(NewState, /*DoLinebreak*/ true); + } + m_State = State{}; + m_LastOutputLength = 0; + m_SW.Reset(); +} + +bool +ProgressBar::IsSameTask(std::string_view Task) const +{ + return Task == m_State.Task; +} + +bool +ProgressBar::HasActiveTask() const +{ + return !m_State.Task.empty(); +} + } // namespace zen ////////////////////////////////////////////////////////////////////////// |