aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2023-10-02 10:58:47 +0200
committerGitHub <[email protected]>2023-10-02 10:58:47 +0200
commit3259b5a7f90f374ea75af469f07a29020d6c9c2d (patch)
tree3437f75b24c531905cf4b4ce5957d685ce3c2e08 /src
parentSentry username fix (#435) (diff)
downloadzen-3259b5a7f90f374ea75af469f07a29020d6c9c2d.tar.xz
zen-3259b5a7f90f374ea75af469f07a29020d6c9c2d.zip
lightweight gc (#431)
- Feature: Add lightweight GC that only removes items from cache/project store without cleaning up data referenced in Cid store - Add `skipcid` parameter to http endpoint `admin/gc`, defaults to "false" - Add `--skipcid` option to `zen gc` command, defaults to false - Add `--gc-lightweight-interval-seconds` option to zenserver
Diffstat (limited to 'src')
-rw-r--r--src/zen/cmds/admin_cmd.cpp5
-rw-r--r--src/zen/cmds/admin_cmd.h1
-rw-r--r--src/zenserver/admin/admin.cpp5
-rw-r--r--src/zenserver/cache/cachedisklayer.cpp5
-rw-r--r--src/zenserver/config.cpp10
-rw-r--r--src/zenserver/config.h1
-rw-r--r--src/zenserver/projectstore/projectstore.cpp4
-rw-r--r--src/zenserver/zenserver.cpp8
-rw-r--r--src/zenstore/compactcas.cpp5
-rw-r--r--src/zenstore/filecas.cpp5
-rw-r--r--src/zenstore/gc.cpp188
-rw-r--r--src/zenstore/include/zenstore/gc.h27
12 files changed, 204 insertions, 60 deletions
diff --git a/src/zen/cmds/admin_cmd.cpp b/src/zen/cmds/admin_cmd.cpp
index b48207bec..9d8348b43 100644
--- a/src/zen/cmds/admin_cmd.cpp
+++ b/src/zen/cmds/admin_cmd.cpp
@@ -74,6 +74,7 @@ GcCommand::GcCommand()
"Collect small objects",
cxxopts::value(m_SmallObjects)->default_value("false"),
"<smallobjects>");
+ m_Options.add_option("", "", "skipcid", "Skip collection of CAS data", cxxopts::value(m_SkipCid)->default_value("false"), "<skipcid>");
m_Options.add_option("",
"m",
"maxcacheduration",
@@ -122,6 +123,10 @@ GcCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
{
Params.Add({"disksizesoftlimit", fmt::format("{}", m_DiskSizeSoftLimit)});
}
+ if (m_SkipCid)
+ {
+ Params.Add({"skipcid", "true"});
+ }
cpr::Session Session;
Session.SetHeader(cpr::Header{{"Accept", "application/json"}});
diff --git a/src/zen/cmds/admin_cmd.h b/src/zen/cmds/admin_cmd.h
index 873c230d9..af375e91b 100644
--- a/src/zen/cmds/admin_cmd.h
+++ b/src/zen/cmds/admin_cmd.h
@@ -37,6 +37,7 @@ private:
cxxopts::Options m_Options{"gc", "Garbage collect zen storage"};
std::string m_HostName;
bool m_SmallObjects{false};
+ bool m_SkipCid{false};
uint64_t m_MaxCacheDuration{0};
uint64_t m_DiskSizeSoftLimit{0};
};
diff --git a/src/zenserver/admin/admin.cpp b/src/zenserver/admin/admin.cpp
index 083086f50..89dae25af 100644
--- a/src/zenserver/admin/admin.cpp
+++ b/src/zenserver/admin/admin.cpp
@@ -228,6 +228,11 @@ HttpAdminService::HttpAdminService(GcScheduler& Scheduler,
}
}
+ if (auto Param = Params.GetValue("skipcid"); Param.empty() == false)
+ {
+ GcParams.SkipCid = Param == "true"sv;
+ }
+
const bool Started = m_GcScheduler.TriggerGc(GcParams);
CbObjectWriter Response;
diff --git a/src/zenserver/cache/cachedisklayer.cpp b/src/zenserver/cache/cachedisklayer.cpp
index 3cee3197b..d53d3f3f4 100644
--- a/src/zenserver/cache/cachedisklayer.cpp
+++ b/src/zenserver/cache/cachedisklayer.cpp
@@ -1197,6 +1197,11 @@ ZenCacheDiskLayer::CacheBucket::GatherReferences(GcContext& GcCtx)
continue;
}
+ if (GcCtx.SkipCid())
+ {
+ continue;
+ }
+
const DiskLocation& Loc = Payloads[Entry.second].Location;
if (Loc.IsFlagSet(DiskLocation::kStructured))
diff --git a/src/zenserver/config.cpp b/src/zenserver/config.cpp
index 64acdfe73..6daf7fe1c 100644
--- a/src/zenserver/config.cpp
+++ b/src/zenserver/config.cpp
@@ -920,6 +920,9 @@ ParseConfigFile(const std::filesystem::path& Path,
LuaOptions.AddOption("gc.lowdiskspacethreshold"sv,
ServerOptions.GcConfig.MinimumFreeDiskSpaceToAllowWrites,
"gc-low-diskspace-threshold"sv);
+ LuaOptions.AddOption("gc.lightweightntervalseconds"sv,
+ ServerOptions.GcConfig.LightweightIntervalSeconds,
+ "gc-lightweight-interval-seconds"sv);
////// gc
LuaOptions.AddOption("gc.cache.maxdurationseconds"sv, ServerOptions.GcConfig.Cache.MaxDurationSeconds, "gc-cache-duration-seconds"sv);
@@ -1358,6 +1361,13 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions)
options.add_option("gc",
"",
+ "gc-lightweight-interval-seconds",
+ "Lightweight garbage collection interval in seconds. Default set to 900 (30 min).",
+ cxxopts::value<int32_t>(ServerOptions.GcConfig.LightweightIntervalSeconds)->default_value("900"),
+ "");
+
+ options.add_option("gc",
+ "",
"gc-cache-duration-seconds",
"Max duration in seconds before Z$ entries get evicted. Default set to 1209600 (2 weeks)",
cxxopts::value<int32_t>(ServerOptions.GcConfig.Cache.MaxDurationSeconds)->default_value("1209600"),
diff --git a/src/zenserver/config.h b/src/zenserver/config.h
index f5438489d..bb6e20bb6 100644
--- a/src/zenserver/config.h
+++ b/src/zenserver/config.h
@@ -89,6 +89,7 @@ struct ZenGcConfig
bool Enabled = true;
uint64_t DiskReserveSize = 1ul << 28;
uint64_t DiskSizeSoftLimit = 0;
+ int32_t LightweightIntervalSeconds = 0;
uint64_t MinimumFreeDiskSpaceToAllowWrites = 1ul << 28;
};
diff --git a/src/zenserver/projectstore/projectstore.cpp b/src/zenserver/projectstore/projectstore.cpp
index 70dc678a9..4ddbdded7 100644
--- a/src/zenserver/projectstore/projectstore.cpp
+++ b/src/zenserver/projectstore/projectstore.cpp
@@ -502,6 +502,10 @@ void
ProjectStore::Oplog::GatherReferences(GcContext& GcCtx)
{
ZEN_TRACE_CPU("Store::Oplog::GatherReferences");
+ if (GcCtx.SkipCid())
+ {
+ return;
+ }
tsl::robin_set<IoHash> AttachmentHashes;
IterateOplog([&](CbObject Op) {
diff --git a/src/zenserver/zenserver.cpp b/src/zenserver/zenserver.cpp
index fa7694573..e4143dc01 100644
--- a/src/zenserver/zenserver.cpp
+++ b/src/zenserver/zenserver.cpp
@@ -449,7 +449,10 @@ public:
m_VfsService->AddService(Ref<ZenCacheStore>(m_CacheStore));
m_Http->RegisterService(*m_VfsService);
- ZEN_INFO("initializing GC, enabled '{}', interval {}s", ServerOptions.GcConfig.Enabled, ServerOptions.GcConfig.IntervalSeconds);
+ ZEN_INFO("initializing GC, enabled '{}', interval {}s, lightweight interval {}s",
+ ServerOptions.GcConfig.Enabled,
+ ServerOptions.GcConfig.IntervalSeconds,
+ ServerOptions.GcConfig.LightweightIntervalSeconds);
zen::GcSchedulerConfig GcConfig{
.RootDirectory = m_DataRoot / "gc",
.MonitorInterval = std::chrono::seconds(ServerOptions.GcConfig.MonitorIntervalSeconds),
@@ -460,7 +463,8 @@ public:
.Enabled = ServerOptions.GcConfig.Enabled,
.DiskReserveSize = ServerOptions.GcConfig.DiskReserveSize,
.DiskSizeSoftLimit = ServerOptions.GcConfig.DiskSizeSoftLimit,
- .MinimumFreeDiskSpaceToAllowWrites = ServerOptions.GcConfig.MinimumFreeDiskSpaceToAllowWrites};
+ .MinimumFreeDiskSpaceToAllowWrites = ServerOptions.GcConfig.MinimumFreeDiskSpaceToAllowWrites,
+ .LightweightInterval = std::chrono::seconds(ServerOptions.GcConfig.LightweightIntervalSeconds)};
m_GcScheduler.Initialize(GcConfig);
// Create and register admin interface last to make sure all is properly initialized
diff --git a/src/zenstore/compactcas.cpp b/src/zenstore/compactcas.cpp
index 63158f6de..a138e43e9 100644
--- a/src/zenstore/compactcas.cpp
+++ b/src/zenstore/compactcas.cpp
@@ -388,6 +388,11 @@ CasContainerStrategy::CollectGarbage(GcContext& GcCtx)
{
ZEN_TRACE_CPU("CasContainer::CollectGarbage");
+ if (GcCtx.SkipCid())
+ {
+ return;
+ }
+
// It collects all the blocks that we want to delete chunks from. For each such
// block we keep a list of chunks to retain and a list of chunks to delete.
//
diff --git a/src/zenstore/filecas.cpp b/src/zenstore/filecas.cpp
index ce0dd7ce6..c3dce2b7b 100644
--- a/src/zenstore/filecas.cpp
+++ b/src/zenstore/filecas.cpp
@@ -897,6 +897,11 @@ FileCasStrategy::CollectGarbage(GcContext& GcCtx)
ZEN_ASSERT(m_IsInitialized);
+ if (GcCtx.SkipCid())
+ {
+ return;
+ }
+
ZEN_DEBUG("collecting garbage from {}", m_RootDirectory);
std::vector<IoHash> ChunksToDelete;
diff --git a/src/zenstore/gc.cpp b/src/zenstore/gc.cpp
index a3282dde6..f8ef5de82 100644
--- a/src/zenstore/gc.cpp
+++ b/src/zenstore/gc.cpp
@@ -196,6 +196,7 @@ struct GcContext::GcState
GcClock::TimePoint m_ProjectStoreExpireTime;
bool m_DeletionMode = true;
bool m_CollectSmallObjects = false;
+ bool m_SkipCid = false;
std::filesystem::path DiskReservePath;
};
@@ -260,6 +261,18 @@ GcContext::ExpiredCacheKeys(const std::string& CacheKeyContext) const
}
bool
+GcContext::SkipCid() const
+{
+ return m_State->m_SkipCid;
+}
+
+void
+GcContext::SetSkipCid(bool NewState)
+{
+ m_State->m_SkipCid = NewState;
+}
+
+bool
GcContext::IsDeletionMode() const
{
return m_State->m_DeletionMode;
@@ -591,6 +604,11 @@ GcScheduler::Initialize(const GcSchedulerConfig& Config)
m_Config.Interval = m_Config.MonitorInterval;
}
+ if (m_Config.LightweightInterval.count() && m_Config.LightweightInterval < m_Config.MonitorInterval)
+ {
+ m_Config.LightweightInterval = m_Config.MonitorInterval;
+ }
+
std::filesystem::create_directories(Config.RootDirectory);
std::error_code Ec = CreateGCReserve(m_Config.RootDirectory / "reserve.gc", m_Config.DiskReserveSize);
@@ -604,8 +622,9 @@ GcScheduler::Initialize(const GcSchedulerConfig& Config)
CheckDiskSpace();
- m_LastGcTime = GcClock::Now();
- m_LastGcExpireTime = GcClock::TimePoint::min();
+ m_LastGcTime = GcClock::Now();
+ m_LastLightweightGcTime = m_LastGcTime;
+ m_LastGcExpireTime = GcClock::TimePoint::min();
if (CbObject SchedulerState = LoadCompactBinaryObject(Config.RootDirectory / "gc_state"))
{
@@ -615,7 +634,8 @@ GcScheduler::Initialize(const GcSchedulerConfig& Config)
if (m_LastGcTime + m_Config.Interval < GcClock::Now())
{
// TODO: Trigger GC?
- m_LastGcTime = GcClock::Now();
+ m_LastGcTime = GcClock::Now();
+ m_LastLightweightGcTime = m_LastGcTime;
}
}
@@ -631,8 +651,7 @@ GcScheduler::Initialize(const GcSchedulerConfig& Config)
},
0);
- m_NextGcTime = NextGcTime(m_LastGcTime);
- m_GcThread = std::thread(&GcScheduler::SchedulerThread, this);
+ m_GcThread = std::thread(&GcScheduler::SchedulerThread, this);
}
void
@@ -773,10 +792,17 @@ GcScheduler::SchedulerThread()
std::chrono::seconds ScrubTimeslice = std::chrono::seconds::max();
bool DoDelete = true;
bool CollectSmallObjects = m_Config.CollectSmallObjects;
+ std::chrono::seconds GcInterval = m_Config.Interval;
+ std::chrono::seconds LightwightGcInterval = m_Config.LightweightInterval;
std::chrono::seconds MaxCacheDuration = m_Config.MaxCacheDuration;
std::chrono::seconds MaxProjectStoreDuration = m_Config.MaxProjectStoreDuration;
uint64_t DiskSizeSoftLimit = m_Config.DiskSizeSoftLimit;
- GcClock::TimePoint Now = GcClock::Now();
+ bool SkipCid = false;
+
+ bool DiskSpaceGCTriggered = false;
+ bool TimeBasedGCTriggered = false;
+
+ GcClock::TimePoint Now = GcClock::Now();
if (m_TriggerGcParams)
{
@@ -797,6 +823,10 @@ GcScheduler::SchedulerThread()
{
DiskSizeSoftLimit = TriggerParams.DiskSizeSoftLimit;
}
+ if (TriggerParams.SkipCid)
+ {
+ SkipCid = true;
+ }
}
if (m_TriggerScrubParams)
@@ -859,7 +889,7 @@ GcScheduler::SchedulerThread()
LoadGraph.resize(DiskDeltas.size(), '0');
if (DiskDeltas.size() > 0 && MaxLoad > 0)
{
- char LoadIndicator[11] = "0123456789";
+ static const char LoadIndicator[11] = "0123456789";
for (size_t Index = 0; Index < DiskDeltas.size(); ++Index)
{
size_t LoadIndex = (9 * DiskDeltas[Index] + MaxLoad - 1) / MaxLoad;
@@ -884,48 +914,114 @@ GcScheduler::SchedulerThread()
}
}
- const bool DiskSpaceGCTriggered = GcDiskSpaceGoal > 0;
+ std::chrono::seconds RemaingTimeUntilGc =
+ GcInterval.count() == 0 ? std::chrono::seconds::max()
+ : std::chrono::duration_cast<std::chrono::seconds>(m_LastGcTime + GcInterval - GcClock::Now());
+ if (RemaingTimeUntilGc < std::chrono::seconds::zero())
+ {
+ RemaingTimeUntilGc = std::chrono::seconds::zero();
+ }
+ std::chrono::seconds RemaingTimeUntilLightweightGc =
+ LightwightGcInterval.count() == 0
+ ? std::chrono::seconds::max()
+ : std::chrono::duration_cast<std::chrono::seconds>(m_LastLightweightGcTime + LightwightGcInterval - GcClock::Now());
+ if (RemaingTimeUntilLightweightGc < std::chrono::seconds::zero())
+ {
+ RemaingTimeUntilLightweightGc = std::chrono::seconds::zero();
+ }
- std::chrono::seconds RemaingTime = std::chrono::duration_cast<std::chrono::seconds>(m_NextGcTime - GcClock::Now());
+ if (GcDiskSpaceGoal > 0)
+ {
+ DiskSpaceGCTriggered = true;
+ }
+ else if (RemaingTimeUntilGc.count() == 0)
+ {
+ TimeBasedGCTriggered = true;
+ }
+ else if (RemaingTimeUntilLightweightGc.count() == 0)
+ {
+ TimeBasedGCTriggered = true;
+ SkipCid = true;
+ }
- if (RemaingTime < std::chrono::seconds::zero())
+ std::string NextTriggerStatus;
+ if (GcInterval.count() != 0 || LightwightGcInterval.count() != 0 || DiskSizeSoftLimit != 0)
{
- RemaingTime = std::chrono::seconds::zero();
+ ExtendableStringBuilder<256> Sb;
+ if (DiskSpaceGCTriggered)
+ {
+ Sb.Append(fmt::format(" Disk space exceeds {}, trying to reclaim {}.",
+ NiceBytes(DiskSizeSoftLimit),
+ NiceBytes(GcDiskSpaceGoal)));
+ }
+ else if (TimeBasedGCTriggered)
+ {
+ if (SkipCid)
+ {
+ Sb.Append(fmt::format(" Lightweight GC schedule triggered."));
+ }
+ else
+ {
+ Sb.Append(fmt::format(" GC schedule triggered."));
+ }
+ }
+ else
+ {
+ if (GcInterval.count() != 0)
+ {
+ Sb.Append(fmt::format(" Full GC in {}.",
+ NiceTimeSpanMs(uint64_t(std::chrono::milliseconds(RemaingTimeUntilGc).count()))));
+ }
+ if (LightwightGcInterval.count() != 0)
+ {
+ Sb.Append(
+ fmt::format(" Lightweight GC in {}.",
+ NiceTimeSpanMs(uint64_t(std::chrono::milliseconds(RemaingTimeUntilLightweightGc).count()))));
+ }
+ if (DiskSizeSoftLimit != 0 && DiskSizeSoftLimit > TotalSize.DiskSize)
+ {
+ Sb.Append(fmt::format(" Disk usagage GC in {}.", NiceBytes(DiskSizeSoftLimit - TotalSize.DiskSize)));
+ }
+ }
+ NextTriggerStatus = Sb;
}
- bool TimeBasedGCTriggered = !DiskSpaceGCTriggered && RemaingTime.count() == 0;
ZEN_INFO(
- "{} in use,{} {} of total {} free disk space, disk writes last {} per {} [{}], peak {}/s. {}",
+ "{} used{}. '{}': {} in use, {} free. Disk writes last {} per {} [{}], peak {}/s.{}",
NiceBytes(TotalSize.DiskSize),
- DiskSizeSoftLimit == 0 ? "" : fmt::format(" {} soft limit,", NiceBytes(DiskSizeSoftLimit)),
+ DiskSizeSoftLimit == 0 ? "" : fmt::format(", {} soft limit", NiceBytes(DiskSizeSoftLimit)),
+ m_Config.RootDirectory,
NiceBytes(Space.Free),
NiceBytes(Space.Total),
NiceTimeSpanMs(uint64_t(std::chrono::milliseconds(LoadGraphTime).count())),
NiceTimeSpanMs(uint64_t(std::chrono::milliseconds(LoadGraphTime).count() / PressureGraphLength)),
LoadGraph,
NiceBytes(MaxLoad * uint64_t(std::chrono::seconds(1).count()) / uint64_t(std::chrono::seconds(LoadGraphTime).count())),
- DiskSpaceGCTriggered ? fmt::format("Disk use threshold triggered, trying to reclaim {}. ", NiceBytes(GcDiskSpaceGoal))
- : TimeBasedGCTriggered ? "GC schedule triggered."
- : m_NextGcTime == GcClock::TimePoint::max()
- ? ""
- : fmt::format("{} until next scheduled GC.",
- NiceTimeSpanMs(uint64_t(std::chrono::milliseconds(RemaingTime).count()))));
+ NextTriggerStatus);
if (!DiskSpaceGCTriggered && !TimeBasedGCTriggered)
{
- WaitTime = m_Config.MonitorInterval < RemaingTime ? m_Config.MonitorInterval : RemaingTime;
+ WaitTime = m_Config.MonitorInterval;
+ if (RemaingTimeUntilGc < WaitTime)
+ {
+ WaitTime = RemaingTimeUntilGc;
+ }
+ if (RemaingTimeUntilLightweightGc < WaitTime)
+ {
+ WaitTime = RemaingTimeUntilLightweightGc;
+ }
continue;
}
- WaitTime = m_Config.MonitorInterval;
uint32_t IdleState = static_cast<uint32_t>(GcSchedulerStatus::kIdle);
if (!m_Status.compare_exchange_strong(IdleState, static_cast<uint32_t>(GcSchedulerStatus::kRunning)))
{
+ WaitTime = m_Config.MonitorInterval;
continue;
}
}
- CollectGarbage(CacheExpireTime, ProjectStoreExpireTime, DoDelete, CollectSmallObjects);
+ CollectGarbage(CacheExpireTime, ProjectStoreExpireTime, DoDelete, CollectSmallObjects, SkipCid);
uint32_t RunningState = static_cast<uint32_t>(GcSchedulerStatus::kRunning);
if (!m_Status.compare_exchange_strong(RunningState, static_cast<uint32_t>(GcSchedulerStatus::kIdle)))
@@ -933,26 +1029,14 @@ GcScheduler::SchedulerThread()
ZEN_ASSERT(m_Status == static_cast<uint32_t>(GcSchedulerStatus::kStopped));
break;
}
+
+ WaitTime = std::chrono::seconds(0);
}
catch (std::exception& Ex)
{
ZEN_ERROR("scheduling garbage collection failed with: '{}'", Ex.what());
+ WaitTime = m_Config.MonitorInterval;
}
-
- WaitTime = m_Config.MonitorInterval;
- }
-}
-
-GcClock::TimePoint
-GcScheduler::NextGcTime(GcClock::TimePoint CurrentTime)
-{
- if (m_Config.Interval.count())
- {
- return CurrentTime + m_Config.Interval;
- }
- else
- {
- return GcClock::TimePoint::max();
}
}
@@ -990,12 +1074,14 @@ void
GcScheduler::CollectGarbage(const GcClock::TimePoint& CacheExpireTime,
const GcClock::TimePoint& ProjectStoreExpireTime,
bool Delete,
- bool CollectSmallObjects)
+ bool CollectSmallObjects,
+ bool SkipCid)
{
ZEN_TRACE_CPU("GcScheduler::CollectGarbage");
GcContext GcCtx(CacheExpireTime, ProjectStoreExpireTime);
GcCtx.SetDeletionMode(Delete);
+ GcCtx.SetSkipCid(SkipCid);
GcCtx.CollectSmallObjects(CollectSmallObjects);
GcCtx.DiskReservePath(m_Config.RootDirectory / "reserve.gc");
@@ -1027,8 +1113,9 @@ GcScheduler::CollectGarbage(const GcClock::TimePoint& CacheExpireTime,
}
}
- ZEN_INFO("garbage collection STARTING, small objects gc {}, cache cutoff time {}, project store cutoff time {}",
+ ZEN_INFO("garbage collection STARTING, small objects gc {}, CAS. Cache cutoff time {}, project store cutoff time {}",
GcCtx.CollectSmallObjects() ? "ENABLED"sv : "DISABLED"sv,
+ SkipCid ? "skip"sv : "include"sv,
CacheExpireTime,
ProjectStoreExpireTime);
{
@@ -1037,16 +1124,23 @@ GcScheduler::CollectGarbage(const GcClock::TimePoint& CacheExpireTime,
m_GcManager.CollectGarbage(GcCtx);
- if (Delete)
+ if (SkipCid)
{
- GcClock::TimePoint KeepRangeStart = Min(CacheExpireTime, ProjectStoreExpireTime);
- m_LastGcExpireTime = KeepRangeStart;
- std::unique_lock Lock(m_GcMutex);
- m_DiskUsageWindow.KeepRange(KeepRangeStart.time_since_epoch().count(), GcClock::Duration::max().count());
+ m_LastLightweightGcTime = GcClock::Now();
}
+ else
+ {
+ if (Delete)
+ {
+ GcClock::TimePoint KeepRangeStart = Min(CacheExpireTime, ProjectStoreExpireTime);
+ m_LastGcExpireTime = KeepRangeStart;
+ std::unique_lock Lock(m_GcMutex);
+ m_DiskUsageWindow.KeepRange(KeepRangeStart.time_since_epoch().count(), GcClock::Duration::max().count());
+ }
- m_LastGcTime = GcClock::Now();
- m_NextGcTime = NextGcTime(m_LastGcTime);
+ m_LastGcTime = GcClock::Now();
+ m_LastLightweightGcTime = m_LastGcTime;
+ }
try
{
diff --git a/src/zenstore/include/zenstore/gc.h b/src/zenstore/include/zenstore/gc.h
index 28e5c2ec2..2e52218f8 100644
--- a/src/zenstore/include/zenstore/gc.h
+++ b/src/zenstore/include/zenstore/gc.h
@@ -65,6 +65,9 @@ public:
std::span<const IoHash> ExpiredCacheKeys(const std::string& CacheKeyContext) const;
+ bool SkipCid() const;
+ void SetSkipCid(bool NewState);
+
bool IsDeletionMode() const;
void SetDeletionMode(bool NewState);
@@ -183,6 +186,7 @@ struct GcSchedulerConfig
uint64_t DiskReserveSize = 1ul << 28;
uint64_t DiskSizeSoftLimit = 0;
uint64_t MinimumFreeDiskSpaceToAllowWrites = 1ul << 28;
+ std::chrono::seconds LightweightInterval{};
};
class DiskUsageWindow
@@ -224,6 +228,7 @@ public:
std::chrono::seconds MaxCacheDuration = std::chrono::seconds::max();
std::chrono::seconds MaxProjectStoreDuration = std::chrono::seconds::max();
uint64_t DiskSizeSoftLimit = 0;
+ bool SkipCid = false;
};
bool TriggerGc(const TriggerGcParams& Params);
@@ -237,23 +242,23 @@ public:
bool TriggerScrub(const TriggerScrubParams& Params);
private:
- void SchedulerThread();
- void CollectGarbage(const GcClock::TimePoint& CacheExpireTime,
- const GcClock::TimePoint& ProjectStoreExpireTime,
- bool Delete,
- bool CollectSmallObjects);
- void ScrubStorage(bool DoDelete, std::chrono::seconds TimeSlice);
- GcClock::TimePoint NextGcTime(GcClock::TimePoint CurrentTime);
- spdlog::logger& Log() { return m_Log; }
- virtual bool AreDiskWritesAllowed() const override { return !m_AreDiskWritesBlocked.load(); }
- DiskSpace CheckDiskSpace();
+ void SchedulerThread();
+ void CollectGarbage(const GcClock::TimePoint& CacheExpireTime,
+ const GcClock::TimePoint& ProjectStoreExpireTime,
+ bool Delete,
+ bool CollectSmallObjects,
+ bool SkipCid);
+ void ScrubStorage(bool DoDelete, std::chrono::seconds TimeSlice);
+ spdlog::logger& Log() { return m_Log; }
+ virtual bool AreDiskWritesAllowed() const override { return !m_AreDiskWritesBlocked.load(); }
+ DiskSpace CheckDiskSpace();
spdlog::logger& m_Log;
GcManager& m_GcManager;
GcSchedulerConfig m_Config;
GcClock::TimePoint m_LastGcTime{};
+ GcClock::TimePoint m_LastLightweightGcTime{};
GcClock::TimePoint m_LastGcExpireTime{};
- GcClock::TimePoint m_NextGcTime{};
std::atomic_uint32_t m_Status{};
std::thread m_GcThread;
std::mutex m_GcMutex;