nice disable of servers
All checks were successful
Build-Test-Publish / build (linux/amd64) (push) Successful in 1m0s
Build-Test-Publish / build (linux/arm64) (push) Successful in 1m18s

This commit is contained in:
Your Name
2025-09-20 14:48:24 +12:00
parent a18e3508ce
commit 23fb68903c
3 changed files with 67 additions and 15 deletions

View File

@@ -146,6 +146,9 @@ int help_handler(const CommandContext& ctx) {
show_command("start"); show_command("start");
show_command("stop"); show_command("stop");
info << std::endl; info << std::endl;
show_command("disable");
show_command("enable");
info << std::endl;
show_command("ssh"); show_command("ssh");
info << std::endl; info << std::endl;
show_command("create-server"); show_command("create-server");

View File

@@ -15,6 +15,7 @@
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <filesystem> #include <filesystem>
#include <mutex>
#include <libassert/assert.hpp> #include <libassert/assert.hpp>
namespace dropshell { namespace dropshell {
@@ -96,6 +97,8 @@ void list_servers() {
// mutex for the tableprint // mutex for the tableprint
std::mutex tp_mutex; std::mutex tp_mutex;
// mutex for server status maps
std::mutex status_mutex;
info << "Checking "<<server_user_pairs.size() << " agents: " << std::flush; info << "Checking "<<server_user_pairs.size() << " agents: " << std::flush;
int checked = 0; int checked = 0;
@@ -103,6 +106,11 @@ void list_servers() {
// First, check which servers are online (with caching per server, not per user) // First, check which servers are online (with caching per server, not per user)
std::map<std::string, bool> server_online_status; std::map<std::string, bool> server_online_status;
// Pre-compute disabled status to avoid threading issues with config access
std::set<std::string> disabled_servers;
for (const auto& disabled : gConfig().get_disabled_servers()) {
disabled_servers.insert(disabled);
}
transwarp::parallel exec{server_user_pairs.size()}; transwarp::parallel exec{server_user_pairs.size()};
auto task = transwarp::for_each(exec, server_user_pairs.begin(), server_user_pairs.end(), [&](const server_user_pair& sup) { auto task = transwarp::for_each(exec, server_user_pairs.begin(), server_user_pairs.end(), [&](const server_user_pair& sup) {
@@ -118,21 +126,42 @@ void list_servers() {
std::string ports_used_str = ""; std::string ports_used_str = "";
std::set<int> ports_used; std::set<int> ports_used;
// Check if server is disabled // Check if server is disabled (from pre-computed set, thread-safe read)
bool is_disabled = gConfig().is_server_disabled(sup.server.get_server_name()); bool is_disabled = (disabled_servers.find(sup.server.get_server_name()) != disabled_servers.end());
// Check if server is online (with caching to avoid redundant checks for multiple users) // Check if server is online (with caching to avoid redundant checks for multiple users)
bool is_online = false; bool is_online = false;
if (!is_disabled) { if (!is_disabled) {
// First check if we already know the status
bool already_checked = false;
{
std::lock_guard<std::mutex> lock(status_mutex);
auto it = server_online_status.find(sup.server.get_server_name()); auto it = server_online_status.find(sup.server.get_server_name());
if (it != server_online_status.end()) { if (it != server_online_status.end()) {
is_online = it->second; is_online = it->second;
} else { already_checked = true;
}
}
// If not already checked, do the SSH check outside the lock
if (!already_checked) {
// Quick connectivity check // Quick connectivity check
sSSHInfo sshinfo = server_env.get_SSH_INFO(sup.user.user); sSSHInfo sshinfo = server_env.get_SSH_INFO(sup.user.user);
std::string test_cmd = "true"; std::string test_cmd = "true";
is_online = execute_ssh_command(sshinfo, sCommand("", test_cmd, {}), cMode::Silent); bool check_result = execute_ssh_command(sshinfo, sCommand("", test_cmd, {}), cMode::Silent);
server_online_status[sup.server.get_server_name()] = is_online;
// Store the result with lock
{
std::lock_guard<std::mutex> lock(status_mutex);
// Check again in case another thread checked it while we were waiting
auto it = server_online_status.find(sup.server.get_server_name());
if (it == server_online_status.end()) {
server_online_status[sup.server.get_server_name()] = check_result;
is_online = check_result;
} else {
is_online = it->second;
}
}
} }
} }
@@ -149,18 +178,22 @@ void list_servers() {
ports_used_str += std::to_string(port) + " "; ports_used_str += std::to_string(port) + " ";
} }
// Add red cross to address if server is offline or disabled // Add red cross to address if server is offline
std::string address_display = sup.server.get_SSH_HOST(); std::string address_display = sup.server.get_SSH_HOST();
if (is_disabled) { if (!is_online && !is_disabled) {
address_display += " :disabled:";
} else if (!is_online) {
address_display += " :cross:"; address_display += " :cross:";
} }
// Add disabled marker to server name (invisible, used for row coloring)
std::string server_name_display = sup.server.get_server_name();
if (is_disabled) {
server_name_display += ":disabled:";
}
// critical section // critical section
{ {
std::lock_guard<std::mutex> lock(tp_mutex); std::lock_guard<std::mutex> lock(tp_mutex);
tp.add_row({sup.server.get_server_name(), address_display, sup.user.user, serviceticks, ports_used_str}); tp.add_row({server_name_display, address_display, sup.user.user, serviceticks, ports_used_str});
++checked; ++checked;
} }
// print out a tick character for each server checked. // print out a tick character for each server checked.

View File

@@ -40,7 +40,8 @@ const std::map<std::string, coloredText> kReplacements = {
{":error:", {"!", kTextColor_Red}}, {":error:", {"!", kTextColor_Red}},
{":question:", {"?", kTextColor_DarkGrey}}, {":question:", {"?", kTextColor_DarkGrey}},
{":greytick:", {"+", kTextColor_LightGrey}}, {":greytick:", {"+", kTextColor_LightGrey}},
{":greycross:", {"x", kTextColor_LightGrey}} {":greycross:", {"x", kTextColor_LightGrey}},
{":disabled:", {"", kTextColor_DarkGrey}} // Special marker for disabled rows
}; };
// Helper function to get ANSI color code // Helper function to get ANSI color code
@@ -285,11 +286,26 @@ void tableprint::print() {
// Print rows // Print rows
for (size_t row_idx = 1; row_idx < rows.size(); ++row_idx) { for (size_t row_idx = 1; row_idx < rows.size(); ++row_idx) {
const auto& row = rows[row_idx]; const auto& row = rows[row_idx];
// Check if this row contains :disabled: marker
bool is_disabled = false;
for (const auto& cell : row) {
if (cell.find(":disabled:") != std::string::npos) {
is_disabled = true;
break;
}
}
dropshell::info << "\033[90m"; // Dark grey color for borders dropshell::info << "\033[90m"; // Dark grey color for borders
dropshell::info << "|"; dropshell::info << "|";
for (size_t i = 0; i < row.size(); ++i) { for (size_t i = 0; i < row.size(); ++i) {
// Set the appropriate color for the row // Set the appropriate color for the row
std::string rowcolor = (row_idx % 2 == 1) ? "\033[38;5;142m" : "\033[38;5;250m"; std::string rowcolor;
if (is_disabled) {
rowcolor = "\033[90m"; // Dark grey for disabled servers
} else {
rowcolor = (row_idx % 2 == 1) ? "\033[38;5;142m" : "\033[38;5;250m";
}
dropshell::info << width_print_left(row[i],col_widths[i]+2,rowcolor); dropshell::info << width_print_left(row[i],col_widths[i]+2,rowcolor);
dropshell::info << "\033[90m" << "|"; dropshell::info << "\033[90m" << "|";
} }