aboutsummaryrefslogtreecommitdiff
path: root/src/zen/zen.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2024-11-06 09:08:02 +0100
committerGitHub Enterprise <[email protected]>2024-11-06 09:08:02 +0100
commit9285f6d0b00d720957b69b5ecd464cce1dee89bf (patch)
tree08518888b701e54059cfec0de5f56223c332d538 /src/zen/zen.cpp
parentsponsor process attach hardening (#208) (diff)
downloadarchived-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.cpp101
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
//////////////////////////////////////////////////////////////////////////