Add simple cleanup of old build actions
This commit is contained in:
parent
9cf0fed450
commit
218e1f6b17
|
@ -323,6 +323,9 @@ LibPkg::StorageID BuildAction::start(ServiceSetup &setup, std::unique_ptr<Io::Pa
|
||||||
case BuildActionType::CustomCommand:
|
case BuildActionType::CustomCommand:
|
||||||
post<CustomCommand>();
|
post<CustomCommand>();
|
||||||
break;
|
break;
|
||||||
|
case BuildActionType::BuildServiceCleanup:
|
||||||
|
post<BuildServiceCleanup>();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
resultData = "not implemented yet or invalid type";
|
resultData = "not implemented yet or invalid type";
|
||||||
return conclude(BuildActionResult::Failure);
|
return conclude(BuildActionResult::Failure);
|
||||||
|
@ -409,6 +412,43 @@ LibPkg::StorageID BuildAction::conclude(BuildActionResult result)
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BuildServiceCleanup::BuildServiceCleanup(ServiceSetup &setup, const std::shared_ptr<BuildAction> &buildAction)
|
||||||
|
: InternalBuildAction(setup, buildAction)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuildServiceCleanup::run()
|
||||||
|
{
|
||||||
|
// validate parameter
|
||||||
|
if (auto error = validateParameter(RequiredDatabases::None, RequiredParameters::None); !error.empty()) {
|
||||||
|
reportError(move(error));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// iterate though build actions and delete those that are unlikely to be relevant anymore
|
||||||
|
auto count = std::size_t();
|
||||||
|
constexpr auto stopAt = 150;
|
||||||
|
m_setup.building.forEachBuildAction(
|
||||||
|
[this, &count, twoWeeksAgo = DateTime::gmtNow() - TimeSpan::fromDays(14)](
|
||||||
|
LibPkg::StorageID id, BuildAction &action, ServiceSetup::BuildSetup::VisitorBehavior &visitorBehavior) {
|
||||||
|
if (count <= stopAt) {
|
||||||
|
return true; // abort deletion if under 150 build actions anyways
|
||||||
|
}
|
||||||
|
if (m_buildAction->id == id || action.finished.isNull()) {
|
||||||
|
return false; // avoid deleting cleanup action itself as well as any unfinished actions
|
||||||
|
}
|
||||||
|
if (action.result != BuildActionResult::Success || action.finished > twoWeeksAgo) {
|
||||||
|
return false; // delete only successful actions that are at least two weeks old
|
||||||
|
}
|
||||||
|
visitorBehavior = ServiceSetup::BuildSetup::VisitorBehavior::Delete;
|
||||||
|
return --count <= stopAt;
|
||||||
|
},
|
||||||
|
&count);
|
||||||
|
|
||||||
|
const auto buildActionLock = m_setup.building.lockToWrite();
|
||||||
|
reportSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef LIBREPOMGR_DUMMY_BUILD_ACTION_ENABLED
|
#ifdef LIBREPOMGR_DUMMY_BUILD_ACTION_ENABLED
|
||||||
DummyBuildAction::DummyBuildAction(ServiceSetup &setup, const std::shared_ptr<BuildAction> &buildAction)
|
DummyBuildAction::DummyBuildAction(ServiceSetup &setup, const std::shared_ptr<BuildAction> &buildAction)
|
||||||
: InternalBuildAction(setup, buildAction)
|
: InternalBuildAction(setup, buildAction)
|
||||||
|
|
|
@ -373,6 +373,18 @@ BuildActionMetaInfo::BuildActionMetaInfo()
|
||||||
.destinationDb = false,
|
.destinationDb = false,
|
||||||
.packageNames = false,
|
.packageNames = false,
|
||||||
},
|
},
|
||||||
|
BuildActionTypeMetaInfo{
|
||||||
|
.id = BuildActionType::BuildServiceCleanup,
|
||||||
|
.category = "Misc",
|
||||||
|
.name = "Clean build-service-internal data",
|
||||||
|
.type = "build-service-cleanup",
|
||||||
|
.flags = {},
|
||||||
|
.settings = {},
|
||||||
|
.directory = false,
|
||||||
|
.sourceDb = false,
|
||||||
|
.destinationDb = false,
|
||||||
|
.packageNames = false,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
, states({
|
, states({
|
||||||
BuildActionStatusMetaInfo{
|
BuildActionStatusMetaInfo{
|
||||||
|
|
|
@ -47,7 +47,8 @@ enum class BuildActionType : std::uint64_t {
|
||||||
CleanRepository,
|
CleanRepository,
|
||||||
DummyBuildAction,
|
DummyBuildAction,
|
||||||
CustomCommand,
|
CustomCommand,
|
||||||
LastType = CustomCommand,
|
BuildServiceCleanup,
|
||||||
|
LastType = BuildServiceCleanup,
|
||||||
};
|
};
|
||||||
|
|
||||||
using BuildActionFlagType = std::uint64_t;
|
using BuildActionFlagType = std::uint64_t;
|
||||||
|
|
|
@ -656,6 +656,13 @@ private:
|
||||||
bool m_useContainer;
|
bool m_useContainer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct LIBREPOMGR_EXPORT BuildServiceCleanup : public InternalBuildAction {
|
||||||
|
BuildServiceCleanup(ServiceSetup &setup, const std::shared_ptr<BuildAction> &buildAction);
|
||||||
|
void run();
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef LIBREPOMGR_DUMMY_BUILD_ACTION_ENABLED
|
#ifdef LIBREPOMGR_DUMMY_BUILD_ACTION_ENABLED
|
||||||
struct LIBREPOMGR_EXPORT DummyBuildAction : public InternalBuildAction {
|
struct LIBREPOMGR_EXPORT DummyBuildAction : public InternalBuildAction {
|
||||||
DummyBuildAction(ServiceSetup &setup, const std::shared_ptr<BuildAction> &buildAction);
|
DummyBuildAction(ServiceSetup &setup, const std::shared_ptr<BuildAction> &buildAction);
|
||||||
|
|
|
@ -417,22 +417,30 @@ void ServiceSetup::BuildSetup::forEachBuildAction(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServiceSetup::BuildSetup::forEachBuildAction(ServiceSetup::BuildSetup::BuildActionVisitorWriteable &&func)
|
void ServiceSetup::BuildSetup::forEachBuildAction(ServiceSetup::BuildSetup::BuildActionVisitorWriteable &&func, std::size_t *count)
|
||||||
{
|
{
|
||||||
auto txn = m_storage->buildActions.getRWTransaction();
|
auto txn = m_storage->buildActions.getRWTransaction();
|
||||||
|
if (count) {
|
||||||
|
*count = txn.size();
|
||||||
|
}
|
||||||
for (auto i = txn.begin(); i != txn.end(); ++i) {
|
for (auto i = txn.begin(); i != txn.end(); ++i) {
|
||||||
const auto running = m_runningActions.find(i.getID());
|
const auto running = m_runningActions.find(i.getID());
|
||||||
auto &action = running != m_runningActions.end() ? *running->second : i.value();
|
auto &action = running != m_runningActions.end() ? *running->second : i.value();
|
||||||
auto save = false;
|
auto visitorBehavior = VisitorBehavior::DiscardChanges;
|
||||||
const auto stop = func(i.getID(), action, save);
|
const auto stop = func(i.getID(), action, visitorBehavior);
|
||||||
if (save) {
|
if (visitorBehavior == VisitorBehavior::SaveChanges) {
|
||||||
if (running != m_runningActions.end() && !action.isExecuting()) {
|
if (running != m_runningActions.end() && !action.isExecuting()) {
|
||||||
m_runningActions.erase(running);
|
m_runningActions.erase(running);
|
||||||
}
|
}
|
||||||
txn.put(action, i.getID());
|
txn.put(action, i.getID());
|
||||||
|
} else if (visitorBehavior == VisitorBehavior::Delete && !action.isExecuting()) {
|
||||||
|
if (running != m_runningActions.end()) {
|
||||||
|
m_runningActions.erase(running);
|
||||||
|
}
|
||||||
|
txn.del(i.getID());
|
||||||
}
|
}
|
||||||
if (stop) {
|
if (stop) {
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
txn.commit();
|
txn.commit();
|
||||||
|
@ -713,12 +721,12 @@ void ServiceSetup::restoreState()
|
||||||
building.initStorage(building.dbPath.data());
|
building.initStorage(building.dbPath.data());
|
||||||
|
|
||||||
// ensure no build actions are considered running anymore and populate follow up actions
|
// ensure no build actions are considered running anymore and populate follow up actions
|
||||||
building.forEachBuildAction([this](LibPkg::StorageID, BuildAction &buildAction, bool &save) {
|
building.forEachBuildAction([this](LibPkg::StorageID, BuildAction &buildAction, BuildSetup::VisitorBehavior &visitorBehavior) {
|
||||||
if (buildAction.isExecuting()) {
|
if (buildAction.isExecuting()) {
|
||||||
buildAction.status = BuildActionStatus::Finished;
|
buildAction.status = BuildActionStatus::Finished;
|
||||||
buildAction.result = BuildActionResult::Failure;
|
buildAction.result = BuildActionResult::Failure;
|
||||||
buildAction.resultData = "service crashed while exectuing";
|
buildAction.resultData = "service crashed while exectuing";
|
||||||
save = true;
|
visitorBehavior = BuildSetup::VisitorBehavior::SaveChanges;
|
||||||
} else if (buildAction.isScheduled()) {
|
} else if (buildAction.isScheduled()) {
|
||||||
for (const auto previousBuildActionId : buildAction.startAfter) {
|
for (const auto previousBuildActionId : buildAction.startAfter) {
|
||||||
building.m_followUpActions[previousBuildActionId].emplace(buildAction.id);
|
building.m_followUpActions[previousBuildActionId].emplace(buildAction.id);
|
||||||
|
@ -809,11 +817,11 @@ int ServiceSetup::run()
|
||||||
try {
|
try {
|
||||||
#endif
|
#endif
|
||||||
saveState();
|
saveState();
|
||||||
building.forEachBuildAction([](LibPkg::StorageID, BuildAction &buildAction, bool &save) {
|
building.forEachBuildAction([](LibPkg::StorageID, BuildAction &buildAction, BuildSetup::VisitorBehavior &visitorBehavior) {
|
||||||
if (buildAction.isExecuting()) {
|
if (buildAction.isExecuting()) {
|
||||||
buildAction.status = BuildActionStatus::Finished;
|
buildAction.status = BuildActionStatus::Finished;
|
||||||
buildAction.result = BuildActionResult::Aborted;
|
buildAction.result = BuildActionResult::Aborted;
|
||||||
save = true;
|
visitorBehavior = BuildSetup::VisitorBehavior::SaveChanges;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
|
@ -92,6 +92,12 @@ struct LIBREPOMGR_EXPORT ServiceSetup : public LibPkg::Lockable {
|
||||||
BuildSetup &setup;
|
BuildSetup &setup;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class VisitorBehavior {
|
||||||
|
DiscardChanges,
|
||||||
|
SaveChanges,
|
||||||
|
Delete,
|
||||||
|
};
|
||||||
|
|
||||||
explicit BuildSetup();
|
explicit BuildSetup();
|
||||||
BuildSetup(BuildSetup &&) = delete;
|
BuildSetup(BuildSetup &&) = delete;
|
||||||
~BuildSetup();
|
~BuildSetup();
|
||||||
|
@ -148,8 +154,8 @@ struct LIBREPOMGR_EXPORT ServiceSetup : public LibPkg::Lockable {
|
||||||
void rebuildDb();
|
void rebuildDb();
|
||||||
using BuildActionVisitorBase = std::function<bool(LibPkg::StorageID, BuildActionBase &&)>;
|
using BuildActionVisitorBase = std::function<bool(LibPkg::StorageID, BuildActionBase &&)>;
|
||||||
void forEachBuildAction(std::function<void(std::size_t)> count, BuildActionVisitorBase &&func, std::size_t limit, std::size_t start);
|
void forEachBuildAction(std::function<void(std::size_t)> count, BuildActionVisitorBase &&func, std::size_t limit, std::size_t start);
|
||||||
using BuildActionVisitorWriteable = std::function<bool(LibPkg::StorageID, BuildAction &, bool &)>;
|
using BuildActionVisitorWriteable = std::function<bool(LibPkg::StorageID, BuildAction &, VisitorBehavior &)>;
|
||||||
void forEachBuildAction(BuildActionVisitorWriteable &&func);
|
void forEachBuildAction(BuildActionVisitorWriteable &&func, std::size_t *count = nullptr);
|
||||||
std::vector<std::shared_ptr<BuildAction>> followUpBuildActions(BuildActionIdType forId);
|
std::vector<std::shared_ptr<BuildAction>> followUpBuildActions(BuildActionIdType forId);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in New Issue