mirror of
https://github.com/CHN-beta/nixos.git
synced 2026-01-12 04:19:22 +08:00
localPackages.hpcstat: add lock only when connect to db
This commit is contained in:
@@ -147,7 +147,7 @@
|
||||
buildInputs = [ pkgs.clang-tools_18 ];
|
||||
CMAKE_EXPORT_COMPILE_COMMANDS = "1";
|
||||
};
|
||||
hpcstat = pkgs.mkShell
|
||||
hpcstat = pkgs.mkShell.override { stdenv = pkgs.gcc14Stdenv; }
|
||||
{
|
||||
inputsFrom = [ (inputs.self.packages.x86_64-linux.hpcstat.override { version = null; }) ];
|
||||
packages = [ pkgs.clang-tools_18 ];
|
||||
|
||||
@@ -69,7 +69,8 @@ inputs: rec
|
||||
{ src = inputs.topInputs.kylin-virtual-keyboard; };
|
||||
biu = inputs.pkgs.callPackage ./biu { inherit nameof zpp-bits; };
|
||||
zxorm = inputs.pkgs.callPackage ./zxorm { src = inputs.topInputs.zxorm; };
|
||||
hpcstat = inputs.pkgs.callPackage ./hpcstat { inherit nameof sqlite-orm zpp-bits date biu openxlsx; };
|
||||
hpcstat = inputs.pkgs.callPackage ./hpcstat
|
||||
{ inherit nameof sqlite-orm zpp-bits date biu openxlsx; stdenv = inputs.pkgs.gcc14Stdenv; };
|
||||
openxlsx = inputs.pkgs.callPackage ./openxlsx { src = inputs.topInputs.openxlsx; };
|
||||
sqlite-orm = inputs.pkgs.callPackage ./sqlite-orm { src = inputs.topInputs.sqlite-orm; };
|
||||
mkPnpmPackage = inputs.pkgs.callPackage ./mkPnpmPackage.nix {};
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
CompileFlags:
|
||||
Add: [ -Wall, -Wextra, -std=c++23 ]
|
||||
Add: [ -Wall, -Wextra, -std=c++26 ]
|
||||
Compiler: g++
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
# cmake_minimum_required(VERSION 3.30)
|
||||
cmake_minimum_required(VERSION 3.29)
|
||||
project(hpcstat VERSION 0.0.0 LANGUAGES CXX)
|
||||
enable_testing()
|
||||
include(GNUInstallDirs)
|
||||
@@ -25,7 +26,8 @@ find_package(OpenXLSX REQUIRED)
|
||||
|
||||
add_executable(hpcstat src/main.cpp src/env.cpp src/keys.cpp src/ssh.cpp src/sql.cpp src/lfs.cpp src/common.cpp
|
||||
src/push.cpp src/disk.cpp)
|
||||
target_compile_features(hpcstat PRIVATE cxx_std_23)
|
||||
# target_compile_features(hpcstat PRIVATE cxx_std_26)
|
||||
target_compile_options(hpcstat PRIVATE "-std=c++26")
|
||||
target_include_directories(hpcstat PRIVATE ${PROJECT_SOURCE_DIR}/include ${ZPP_BITS_INCLUDE_DIR})
|
||||
target_link_libraries(hpcstat PRIVATE Boost::headers Boost::filesystem sqlite_orm::sqlite_orm
|
||||
nlohmann_json::nlohmann_json range-v3::range-v3 date::date date::date-tz httplib::httplib
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
# include <date/date.h>
|
||||
# include <date/tz.h>
|
||||
# include <boost/interprocess/sync/file_lock.hpp>
|
||||
# include <zpp_bits.h>
|
||||
# include <biu.hpp>
|
||||
|
||||
namespace hpcstat
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
# include <hpcstat/disk.hpp>
|
||||
# include <range/v3/view.hpp>
|
||||
# include <boost/exception/diagnostic_information.hpp>
|
||||
# include <boost/filesystem.hpp>
|
||||
# include <termcolor/termcolor.hpp>
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
@@ -16,10 +15,6 @@ int main(int argc, const char** argv)
|
||||
using namespace std::literals;
|
||||
try
|
||||
{
|
||||
auto lockfile = (boost::filesystem::temp_directory_path() / "hpcstat.lock").string();
|
||||
std::ofstream{lockfile};
|
||||
boost::interprocess::file_lock lock(lockfile.c_str());
|
||||
|
||||
std::vector<std::string> args(argv, argv + argc);
|
||||
|
||||
if (args.size() == 1)
|
||||
@@ -27,11 +22,7 @@ int main(int argc, const char** argv)
|
||||
std::cout << "Usage: hpcstat initdb|login|logout|submitjob|finishjob|verify|export|version|diskstat\n";
|
||||
return 1;
|
||||
}
|
||||
else if (args[1] == "initdb")
|
||||
{
|
||||
lock.lock();
|
||||
if (!sql::initdb()) { std::cerr << "Failed to initialize database\n"; return 1; }
|
||||
}
|
||||
else if (args[1] == "initdb") { if (!sql::initdb()) { std::cerr << "Failed to initialize database\n"; return 1; } }
|
||||
else if (args[1] == "login")
|
||||
{
|
||||
if (env::interactive()) std::cout << "Communicating with the agent..." << std::flush;
|
||||
@@ -50,7 +41,6 @@ int main(int argc, const char** argv)
|
||||
auto signature = ssh::sign(biu::serialize<char>(data), *fp);
|
||||
if (!signature) return 1;
|
||||
data.Signature = *signature;
|
||||
lock.lock();
|
||||
sql::writedb(data);
|
||||
if (env::interactive())
|
||||
{
|
||||
@@ -88,7 +78,7 @@ int main(int argc, const char** argv)
|
||||
{
|
||||
if (auto session_id = env::env("XDG_SESSION_ID", true); !session_id)
|
||||
return 1;
|
||||
else { lock.lock(); sql::writedb(sql::LogoutData{ .Time = now(), .SessionId = *session_id }); }
|
||||
else sql::writedb(sql::LogoutData{ .Time = now(), .SessionId = *session_id });
|
||||
}
|
||||
else if (args[1] == "submitjob")
|
||||
{
|
||||
@@ -111,14 +101,12 @@ int main(int argc, const char** argv)
|
||||
auto signature = ssh::sign(biu::serialize<char>(data), *fp);
|
||||
if (!signature) return 1;
|
||||
data.Signature = *signature;
|
||||
lock.lock();
|
||||
sql::writedb(data);
|
||||
std::cout << "Job <{}> was submitted to <{}> by <{}>.\n"_f(bsub->first, bsub->second, Keys[*fp].Username);
|
||||
}
|
||||
}
|
||||
else if (args[1] == "finishjob")
|
||||
{
|
||||
lock.lock();
|
||||
if (auto fp = ssh::fingerprint(); !fp) return 1;
|
||||
else if (auto session = env::env("XDG_SESSION_ID", true); !session)
|
||||
return 1;
|
||||
@@ -166,12 +154,10 @@ int main(int argc, const char** argv)
|
||||
auto begin = sys_seconds(sys_days(month(month_n) / 1 / year_n)).time_since_epoch().count();
|
||||
auto end = sys_seconds(sys_days(month(month_n) / 1 / year_n + months(1)))
|
||||
.time_since_epoch().count();
|
||||
lock.lock();
|
||||
if (!sql::export_data(begin, end, "{}{}.xlsx"_f(year_n, month_n))) return 1;
|
||||
}
|
||||
else if (args[1] == "push")
|
||||
{
|
||||
lock.lock();
|
||||
if (auto jobs = sql::check_job_status(); !jobs) return 1;
|
||||
else if (!push::push(*jobs)) return 1;
|
||||
}
|
||||
|
||||
@@ -8,14 +8,16 @@
|
||||
# define SQLITE_ORM_OPTIONAL_SUPPORTED
|
||||
# include <sqlite_orm/sqlite_orm.h>
|
||||
# include <OpenXLSX.hpp>
|
||||
# include <boost/filesystem.hpp>
|
||||
|
||||
namespace hpcstat::sql
|
||||
{
|
||||
auto connect(std::optional<std::string> dbfile = std::nullopt)
|
||||
auto connect(std::optional<std::string> dbfile = std::nullopt, bool need_lock = true)
|
||||
{
|
||||
auto conn = [&]() { return std::make_optional(sqlite_orm::make_storage
|
||||
// a function to actually connecto to db
|
||||
auto conn = [](std::string dbfile) { return std::make_optional(sqlite_orm::make_storage
|
||||
(
|
||||
*dbfile,
|
||||
dbfile,
|
||||
sqlite_orm::make_table
|
||||
(
|
||||
"login",
|
||||
@@ -70,31 +72,52 @@ namespace hpcstat::sql
|
||||
sqlite_orm::make_column("status", &CheckJobData::Status)
|
||||
)
|
||||
));};
|
||||
|
||||
// a class to take care of lock
|
||||
struct conn_with_lock
|
||||
{
|
||||
// lock should be declared before conn, so that it will be destructed after conn
|
||||
boost::interprocess::file_lock lock;
|
||||
decltype(conn(std::declval<std::string>())) connection;
|
||||
};
|
||||
|
||||
// set default db path
|
||||
if (!dbfile)
|
||||
{
|
||||
if (auto datadir = env::env("HPCSTAT_DATADIR", true); !datadir)
|
||||
return decltype(conn())();
|
||||
return conn_with_lock{};
|
||||
else dbfile = std::filesystem::path(*datadir) / "hpcstat.db";
|
||||
}
|
||||
auto result = conn();
|
||||
if (!result) std::cerr << "Failed to connect to database.\n";
|
||||
else result->busy_timeout(10000);
|
||||
return result;
|
||||
|
||||
// set file lock
|
||||
auto lockfile = (boost::filesystem::temp_directory_path() / "hpcstat.lock").string();
|
||||
std::ofstream{lockfile}; // create file
|
||||
boost::interprocess::file_lock lock(lockfile.c_str());
|
||||
if (need_lock) lock.lock();
|
||||
|
||||
// try to connect
|
||||
if (auto result = conn(*dbfile); !result)
|
||||
{ std::cerr << "Failed to connect to database.\n"; return conn_with_lock{}; }
|
||||
else
|
||||
{
|
||||
result->busy_timeout(10000);
|
||||
return conn_with_lock{std::move(lock), std::move(result)};
|
||||
}
|
||||
}
|
||||
bool initdb()
|
||||
{
|
||||
if (auto conn = connect(); !conn) return false;
|
||||
if (auto [lock, conn] = connect(); !conn) return false;
|
||||
else { conn->sync_schema(); return true; }
|
||||
}
|
||||
bool writedb(auto value)
|
||||
{ if (auto conn = connect(); !conn) return false; else { conn->insert(value); return true; } }
|
||||
{ if (auto [lock, conn] = connect(); !conn) return false; else { conn->insert(value); return true; } }
|
||||
template bool writedb(LoginData);
|
||||
template bool writedb(LogoutData);
|
||||
template bool writedb(SubmitJobData);
|
||||
template bool writedb(FinishJobData);
|
||||
std::optional<std::set<unsigned>> finishjob_remove_existed(std::map<unsigned, std::string> jobid_submit_time)
|
||||
{
|
||||
if (auto conn = connect(); !conn) return std::nullopt;
|
||||
if (auto [lock, conn] = connect(); !conn) return std::nullopt;
|
||||
else
|
||||
{
|
||||
auto all_job = jobid_submit_time | ranges::views::keys | ranges::to<std::vector<unsigned>>;
|
||||
@@ -110,7 +133,8 @@ namespace hpcstat::sql
|
||||
std::optional<std::vector<std::tuple<std::string, std::string, std::string>>>
|
||||
verify(std::string old_db, std::string new_db)
|
||||
{
|
||||
auto old_conn = connect(old_db), new_conn = connect(new_db);
|
||||
auto [_, old_conn] = connect(old_db);
|
||||
auto [_, new_conn] = connect(new_db);
|
||||
if (!old_conn || !new_conn) { std::cerr << "Failed to connect to database.\n"; return std::nullopt; }
|
||||
else
|
||||
{
|
||||
@@ -153,7 +177,8 @@ namespace hpcstat::sql
|
||||
}
|
||||
}
|
||||
// search corresponding job in submit table
|
||||
std::optional<SubmitJobData> search_job_in_submit(auto connection, unsigned job_id, std::string submit_time)
|
||||
std::optional<SubmitJobData> search_job_in_submit
|
||||
(auto connection, unsigned job_id, std::string submit_time)
|
||||
{
|
||||
std::optional<SubmitJobData> result;
|
||||
long submit_date = [&]
|
||||
@@ -185,7 +210,7 @@ namespace hpcstat::sql
|
||||
}
|
||||
bool export_data(long start_time, long end_time, std::string filename)
|
||||
{
|
||||
if (auto conn = connect(); !conn) return false;
|
||||
if (auto [lock, conn] = connect(); !conn) return false;
|
||||
else
|
||||
{
|
||||
// 对于一个账户的总计
|
||||
@@ -312,7 +337,7 @@ namespace hpcstat::sql
|
||||
std::optional<std::map<unsigned, std::tuple<std::string, std::string, std::string, std::optional<std::string>>>>
|
||||
check_job_status()
|
||||
{
|
||||
if (auto conn = connect(); !conn) return std::nullopt;
|
||||
if (auto [lock, conn] = connect(); !conn) return std::nullopt;
|
||||
else if (auto jobs_current = lfs::bjobs_list(); !jobs_current) return std::nullopt;
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user