diff --git a/protos/PublicDefs.proto b/protos/PublicDefs.proto index 8c328d86..cb7e3c41 100644 --- a/protos/PublicDefs.proto +++ b/protos/PublicDefs.proto @@ -340,44 +340,52 @@ enum ErrCode { ERR_PARENT_ALLOWED_PARTITION = 10017; ERR_USER_EMPTY_PARTITION = 10018; ERR_CHILD_HAS_PARTITION = 10019; - - ERR_INVALID_QOS = 10020; - ERR_DB_DUPLICATE_QOS = 10021; - ERR_DELETE_QOS = 10022; - ERR_CONVERT_TO_INTERGER = 10023; - ERR_TIME_LIMIT = 10024; - ERR_ALLOWED_QOS = 10025; - ERR_DUPLICATE_QOS = 10026; - ERR_PARENT_ALLOWED_QOS = 10027; - ERR_SET_ALLOWED_QOS = 10028; - ERR_ALLOWED_DEFAULT_QOS = 10029; - ERR_DUPLICATE_DEFAULT_QOS = 10030; - ERR_CHILD_HAS_DEFAULT_QOS = 10031; - ERR_SET_ACCOUNT_QOS = 10032; - ERR_SET_DEFAULT_QOS = 10033; - ERR_IS_DEFAULT_QOS = 10034; - - ERR_UPDATE_DATABASE = 10035; + ERR_HAS_NO_QOS_IN_PARTITION = 10020; + ERR_HAS_ALLOWED_QOS_IN_PARTITION = 10021; + + ERR_INVALID_QOS = 10022; + ERR_DB_DUPLICATE_QOS = 10023; + ERR_DELETE_QOS = 10024; + ERR_CONVERT_TO_INTERGER = 10025; + ERR_TIME_LIMIT = 10026; + ERR_ALLOWED_QOS = 10027; + ERR_DUPLICATE_QOS = 10028; + ERR_PARENT_ALLOWED_QOS = 10029; + ERR_SET_ALLOWED_QOS = 10030; + ERR_ALLOWED_DEFAULT_QOS = 10031; + ERR_DUPLICATE_DEFAULT_QOS = 10032; + ERR_CHILD_HAS_DEFAULT_QOS = 10033; + ERR_SET_ACCOUNT_QOS = 10034; + ERR_SET_DEFAULT_QOS = 10035; + ERR_IS_DEFAULT_QOS = 10036; + + ERR_UPDATE_DATABASE = 10037; ERR_GENERIC_FAILURE = 10100; ERR_NO_RESOURCE = 10101; ERR_NON_EXISTENT = 10102; ERR_INVALID_NODE_NUM = 10103; - ERR_SYSTEM_ERR = 10104; - ERR_EXISTING_TASK = 10105; - ERR_INVALID_PARAM = 10106; - ERR_STOP = 10107; - ERR_PERMISSION_DENIED = 10108; - ERR_CONNECTION_TIMEOUT = 10109; - ERR_CONNECTION_ABORTED = 10110; - ERR_RPC_FAILURE = 10111; - ERR_TOKEN_REQUEST_FAILURE = 10112; - ERR_STREAM_BROKEN = 10113; - ERR_INVALID_STUB = 10114; - ERR_CGROUP = 10115; - ERR_PROTOBUF = 10116; - ERR_LIB_EVENT = 10117; - ERR_NO_AVAIL_NODE = 10118; + ERR_INVAILD_NODE_LIST = 10104; + ERR_INVAILD_EX_NODE_LIST = 10105; + ERR_TIME_TIMIT_BEYOND = 10106; + ERR_CPUS_PER_TASK_BEYOND = 10107; + ERR_NO_ENOUGH_NODE = 10108; + + ERR_SYSTEM_ERR = 10109; + ERR_EXISTING_TASK = 10110; + ERR_INVALID_PARAM = 10111; + ERR_STOP = 10112; + ERR_PERMISSION_DENIED = 10113; + ERR_CONNECTION_TIMEOUT = 10114; + ERR_CONNECTION_ABORTED = 10115; + ERR_RPC_FAILURE = 10116; + ERR_TOKEN_REQUEST_FAILURE = 10117; + ERR_STREAM_BROKEN = 10118; + ERR_INVALID_STUB = 10119; + ERR_CGROUP = 10120; + ERR_PROTOBUF = 10121; + ERR_LIB_EVENT = 10122; + ERR_NO_AVAIL_NODE = 10123; } enum EntityType { diff --git a/src/CraneCtld/AccountManager.cpp b/src/CraneCtld/AccountManager.cpp index 75a9086f..a2fb0d59 100644 --- a/src/CraneCtld/AccountManager.cpp +++ b/src/CraneCtld/AccountManager.cpp @@ -921,7 +921,7 @@ result::result AccountManager::CheckIfUserOfAccountIsEnabled( return {}; } -CraneErr AccountManager::CheckAndApplyQosLimitOnTask(const std::string& user, +AccountManager::CraneExpected AccountManager::CheckAndApplyQosLimitOnTask(const std::string& user, const std::string& account, TaskInCtld* task) { util::read_lock_guard user_guard(m_rw_user_mutex_); @@ -930,7 +930,7 @@ CraneErr AccountManager::CheckAndApplyQosLimitOnTask(const std::string& user, const User* user_share_ptr = GetExistedUserInfoNoLock_(user); if (!user_share_ptr) { CRANE_ERROR("CheckAndApplyQosLimitOnTask error: Unknown user {}", user); - return CraneErr::kInvalidUser; + return std::unexpected(CraneErrCode::ERR_INVALID_OP_USER); } if (task->uid != 0) { @@ -941,7 +941,7 @@ CraneErr AccountManager::CheckAndApplyQosLimitOnTask(const std::string& user, CRANE_ERROR( "CheckAndApplyQosLimitOnTask error: Partition is not allowed for " "this user"); - return CraneErr::kNonExistent; + return std::unexpected(CraneErrCode::ERR_ALLOWED_PARTITION); if (task->qos.empty()) { // Default qos @@ -951,7 +951,7 @@ CraneErr AccountManager::CheckAndApplyQosLimitOnTask(const std::string& user, "CheckAndApplyQosLimitOnTask error: The user '{}' has no QOS " "available for this partition '{}' to be used", task->Username(), task->partition_id); - return CraneErr::kInvalidQos; + return std::unexpected(CraneErrCode::ERR_HAS_NO_QOS_IN_PARTITION); } } else { // Check whether task.qos in the qos list @@ -960,7 +960,7 @@ CraneErr AccountManager::CheckAndApplyQosLimitOnTask(const std::string& user, "CheckAndApplyQosLimitOnTask error: The qos '{}'" " you set is not in partition's allowed qos list", task->qos); - return CraneErr::kInvalidQos; + return std::unexpected(CraneErrCode::ERR_HAS_ALLOWED_QOS_IN_PARTITION); } } } else { @@ -972,7 +972,7 @@ CraneErr AccountManager::CheckAndApplyQosLimitOnTask(const std::string& user, const Qos* qos_share_ptr = GetExistedQosInfoNoLock_(task->qos); if (!qos_share_ptr) { CRANE_ERROR("Unknown QOS '{}'", task->qos); - return CraneErr::kInvalidQos; + return std::unexpected(CraneErrCode::ERR_INVALID_QOS); } task->qos_priority = qos_share_ptr->priority; @@ -981,16 +981,16 @@ CraneErr AccountManager::CheckAndApplyQosLimitOnTask(const std::string& user, task->time_limit = qos_share_ptr->max_time_limit_per_task; } else if (task->time_limit > qos_share_ptr->max_time_limit_per_task) { CRANE_ERROR("time-limit reached the user's limit"); - return CraneErr::kInvalidTimeLimit; + return std::unexpected(CraneErrCode::ERR_TIME_TIMIT_BEYOND); } if (static_cast(task->cpus_per_task) > qos_share_ptr->max_cpus_per_user) { CRANE_ERROR("cpus-per-task reached the user's limit"); - return CraneErr::kInvaildCpusperTask; + return std::unexpected(CraneErrCode::ERR_CPUS_PER_TASK_BEYOND); } - return CraneErr::kOk; + return {}; } result::result AccountManager::CheckUidIsAdmin( diff --git a/src/CraneCtld/AccountManager.h b/src/CraneCtld/AccountManager.h index 90b19a7c..46e1c39d 100644 --- a/src/CraneCtld/AccountManager.h +++ b/src/CraneCtld/AccountManager.h @@ -132,7 +132,7 @@ class AccountManager { result::result CheckIfUserOfAccountIsEnabled( const std::string& user, const std::string& account); - CraneErr CheckAndApplyQosLimitOnTask(const std::string& user, + CraneExpected CheckAndApplyQosLimitOnTask(const std::string& user, const std::string& account, TaskInCtld* task); diff --git a/src/CraneCtld/CtldGrpcServer.cpp b/src/CraneCtld/CtldGrpcServer.cpp index c58cefa6..3b5d8f0f 100644 --- a/src/CraneCtld/CtldGrpcServer.cpp +++ b/src/CraneCtld/CtldGrpcServer.cpp @@ -927,7 +927,6 @@ CtldServer::CtldServer(const Config::CraneCtldListenConf &listen_conf) { result::result, std::string> CtldServer::SubmitTaskToScheduler(std::unique_ptr task) { - CraneErr err; if (!task->password_entry->Valid()) { return result::fail( @@ -968,24 +967,25 @@ CtldServer::SubmitTaskToScheduler(std::unique_ptr task) { return result::fail(enable_res.error()); } - err = g_task_scheduler->AcquireTaskAttributes(task.get()); + auto result = g_task_scheduler->AcquireTaskAttributes(task.get()); - if (err == CraneErr::kOk) - err = g_task_scheduler->CheckTaskValidity(task.get()); + if (result) + result = g_task_scheduler->CheckTaskValidity(task.get()); - if (err == CraneErr::kOk) { + if (result) { task->SetSubmitTime(absl::Now()); std::future future = g_task_scheduler->SubmitTaskAsync(std::move(task)); return {std::move(future)}; } - switch (err) { - case CraneErr::kNonExistent: + switch (result.error()) { + case crane::grpc::ErrCode::ERR_INVALID_PARTITION: + case crane::grpc::ErrCode::ERR_ALLOWED_PARTITION: CRANE_DEBUG("Task submission failed. Reason: Partition doesn't exist!"); return result::fail("Partition doesn't exist"); - case CraneErr::kInvalidNodeNum: + case crane::grpc::ErrCode::ERR_INVALID_NODE_NUM: CRANE_DEBUG( "Task submission failed. Reason: --node is either invalid or greater " "than the number of nodes in its partition."); @@ -993,50 +993,59 @@ CtldServer::SubmitTaskToScheduler(std::unique_ptr task) { "--node is either invalid or greater than the number of nodes in its " "partition"); - case CraneErr::kNoResource: + case crane::grpc::ErrCode::ERR_NO_RESOURCE: CRANE_DEBUG( "Task submission failed. " "Reason: The resources of the partition are insufficient."); return result::fail("The resources of the partition are insufficient"); - case CraneErr::kNoAvailNode: + case crane::grpc::ErrCode::ERR_NO_ENOUGH_NODE: CRANE_DEBUG( "Task submission failed. " "Reason: Nodes satisfying the requirements of task are insufficient"); return result::fail( "Nodes satisfying the requirements of task are insufficient"); - case CraneErr::kInvalidUser: + case crane::grpc::ErrCode::ERR_INVALID_OP_USER: CRANE_DEBUG("Task submission failed. Reason: Unknown user"); return result::fail("Unknown user"); - case CraneErr::kInvalidQos: + case crane::grpc::ErrCode::ERR_INVALID_QOS: + CRANE_DEBUG( + "Task submission failed. Reason: Unknown Qos"); + return result::fail("Unkown Qos"); + case crane::grpc::ErrCode::ERR_HAS_ALLOWED_QOS_IN_PARTITION: + CRANE_DEBUG( + "Task submission failed. Reason: " + "The qos you set is not in partition's allowed qos list"); + return result::fail("the qos you set is not in partition's allowed qos list"); + case crane::grpc::ErrCode::ERR_HAS_NO_QOS_IN_PARTITION: CRANE_DEBUG( "Task submission failed. Reason: " - "Unknown Qos or not in partition's allowed qos list"); - return result::fail("Unkown Qos or not in partition's allowed qos list"); + "The user has no QOS available for this partition to be used"); + return result::fail("The user has no QOS available for this partition to be used"); - case CraneErr::kInvalidTimeLimit: + case crane::grpc::ErrCode::ERR_TIME_TIMIT_BEYOND: CRANE_DEBUG( "Task submission failed. Reason: time-limit reached the user's limit"); return result::fail("time-limit reached the user's limit"); - case CraneErr::kInvaildCpusperTask: + case crane::grpc::ErrCode::ERR_CPUS_PER_TASK_BEYOND: CRANE_DEBUG( "Task submission failed. Reason: cpus-per-task reached the user's " "limit"); return result::fail("cpus-per-task reached the user's limit"); - case CraneErr::kInvaildNodeList: + case crane::grpc::ErrCode::ERR_INVAILD_NODE_LIST: CRANE_DEBUG("Task submission failed. Reason: Invalid nodelist"); return result::fail("Invalid nodelist"); - case CraneErr::kInvalidExNodeList: + case crane::grpc::ErrCode::ERR_INVAILD_EX_NODE_LIST: CRANE_DEBUG("Task submission failed. Reason: Invalid excluded nodelist"); return result::fail("Invalid excluded nodelist"); default: - return result::fail(CraneErrStr(err)); + return result::fail(CraneErrCodeStr(result.error())); } } diff --git a/src/CraneCtld/TaskScheduler.cpp b/src/CraneCtld/TaskScheduler.cpp index a0ec0222..a263c487 100644 --- a/src/CraneCtld/TaskScheduler.cpp +++ b/src/CraneCtld/TaskScheduler.cpp @@ -87,8 +87,8 @@ bool TaskScheduler::Init() { CRANE_TRACE("Restore task #{} from embedded running queue.", task->TaskId()); - err = AcquireTaskAttributes(task.get()); - if (err != CraneErr::kOk || task->type == crane::grpc::Interactive) { + auto result = AcquireTaskAttributes(task.get()); + if (!result || task->type == crane::grpc::Interactive) { task->SetStatus(crane::grpc::Failed); ok = g_embedded_db_client->UpdateRuntimeAttrOfTask(0, task_db_id, task->RuntimeAttr()); @@ -98,13 +98,13 @@ bool TaskScheduler::Init() { "mark the task as FAILED.", task_id); } - if (err != CraneErr::kOk) + if (!result) CRANE_INFO( "Failed to acquire task attributes for restored running task " "#{}. " "Error Code: {}. " "Mark it as FAILED and move it to the ended queue.", - task_id, CraneErrStr(err)); + task_id, CraneErrCodeStr(result.error())); else { CRANE_INFO("Mark running interactive task {} as FAILED.", task_id); for (const CranedId& craned_id : task->CranedIds()) { @@ -324,13 +324,13 @@ bool TaskScheduler::Init() { } if (!mark_task_as_failed && - AcquireTaskAttributes(task.get()) != CraneErr::kOk) { + !(AcquireTaskAttributes(task.get()))) { CRANE_ERROR("AcquireTaskAttributes failed for task #{}", task_id); mark_task_as_failed = true; } if (!mark_task_as_failed && - CheckTaskValidity(task.get()) != CraneErr::kOk) { + !(CheckTaskValidity(task.get()))) { CRANE_ERROR("CheckTaskValidity failed for task #{}", task_id); mark_task_as_failed = true; } @@ -2724,9 +2724,10 @@ void TaskScheduler::PersistAndTransferTasksToMongodb_( } } -CraneErr TaskScheduler::AcquireTaskAttributes(TaskInCtld* task) { +CraneErrCodeExpected TaskScheduler::AcquireTaskAttributes(TaskInCtld* task) { auto part_it = g_config.Partitions.find(task->partition_id); - if (part_it == g_config.Partitions.end()) return CraneErr::kNonExistent; + if (part_it == g_config.Partitions.end()) + return std::unexpected(crane::grpc::ErrCode::ERR_INVALID_PARTITION); task->partition_priority = part_it->second.priority; @@ -2754,12 +2755,12 @@ CraneErr TaskScheduler::AcquireTaskAttributes(TaskInCtld* task) { auto check_qos_result = g_account_manager->CheckAndApplyQosLimitOnTask( task->Username(), task->account, task); - if (check_qos_result != CraneErr::kOk) return check_qos_result; + if (!check_qos_result) return check_qos_result; if (!task->TaskToCtld().nodelist().empty() && task->included_nodes.empty()) { std::list nodes; bool ok = util::ParseHostList(task->TaskToCtld().nodelist(), &nodes); - if (!ok) return CraneErr::kInvaildNodeList; + if (!ok) return std::unexpected(crane::grpc::ErrCode::ERR_INVAILD_NODE_LIST); for (auto&& node : nodes) task->included_nodes.emplace(std::move(node)); } @@ -2767,17 +2768,17 @@ CraneErr TaskScheduler::AcquireTaskAttributes(TaskInCtld* task) { if (!task->TaskToCtld().excludes().empty() && task->excluded_nodes.empty()) { std::list nodes; bool ok = util::ParseHostList(task->TaskToCtld().excludes(), &nodes); - if (!ok) return CraneErr::kInvalidExNodeList; + if (!ok) return std::unexpected(crane::grpc::ErrCode::ERR_INVAILD_EX_NODE_LIST); for (auto&& node : nodes) task->excluded_nodes.emplace(std::move(node)); } - return CraneErr::kOk; + return {}; } -CraneErr TaskScheduler::CheckTaskValidity(TaskInCtld* task) { +CraneErrCodeExpected TaskScheduler::CheckTaskValidity(TaskInCtld* task) { if (!CheckIfTimeLimitIsValid(task->time_limit)) - return CraneErr::kInvalidTimeLimit; + return std::unexpected(crane::grpc::ErrCode::ERR_TIME_TIMIT_BEYOND) ; // Check whether the selected partition is able to run this task. std::unordered_set avail_nodes; @@ -2807,7 +2808,7 @@ CraneErr TaskScheduler::CheckTaskValidity(TaskInCtld* task) { .memory_sw_bytes), util::ReadableTypedDeviceMap( metas_ptr->partition_global_meta.res_total.GetDeviceMap())); - return CraneErr::kNoResource; + return std::unexpected(crane::grpc::ErrCode::ERR_NO_RESOURCE) ; } if (task->node_num > metas_ptr->craned_ids.size()) { @@ -2815,7 +2816,7 @@ CraneErr TaskScheduler::CheckTaskValidity(TaskInCtld* task) { "Nodes not enough for task #{}. " "Partition total Nodes: {}", task->TaskId(), metas_ptr->craned_ids.size()); - return CraneErr::kInvalidNodeNum; + return std::unexpected(crane::grpc::ErrCode::ERR_INVALID_NODE_NUM); } auto craned_meta_map = g_meta_container->GetCranedMetaMapConstPtr(); @@ -2837,10 +2838,10 @@ CraneErr TaskScheduler::CheckTaskValidity(TaskInCtld* task) { "Resource not enough. Task #{} needs {} nodes, while only {} " "nodes satisfy its requirement.", task->TaskId(), task->node_num, avail_nodes.size()); - return CraneErr::kNoAvailNode; + return std::unexpected(crane::grpc::ErrCode::ERR_NO_ENOUGH_NODE); } - return CraneErr::kOk; + return {}; } void TaskScheduler::TerminateTasksOnCraned(const CranedId& craned_id, diff --git a/src/CraneCtld/TaskScheduler.h b/src/CraneCtld/TaskScheduler.h index 32eab650..269defd0 100644 --- a/src/CraneCtld/TaskScheduler.h +++ b/src/CraneCtld/TaskScheduler.h @@ -282,9 +282,9 @@ class TaskScheduler { return TerminateRunningTaskNoLock_(iter->second.get()); } - static CraneErr AcquireTaskAttributes(TaskInCtld* task); + static CraneErrCodeExpected AcquireTaskAttributes(TaskInCtld* task); - static CraneErr CheckTaskValidity(TaskInCtld* task); + static CraneErrCodeExpected CheckTaskValidity(TaskInCtld* task); private: template diff --git a/src/Utilities/PublicHeader/include/crane/PublicHeader.h b/src/Utilities/PublicHeader/include/crane/PublicHeader.h index f1d55888..55f9d5a0 100644 --- a/src/Utilities/PublicHeader/include/crane/PublicHeader.h +++ b/src/Utilities/PublicHeader/include/crane/PublicHeader.h @@ -26,6 +26,7 @@ #include #include "protos/Crane.pb.h" +#include "protos/PublicDefs.pb.h" #if !defined(CRANE_VERSION_STRING) # define CRANE_VERSION_STRING "Unknown" @@ -70,6 +71,9 @@ enum class CraneErr : uint16_t { template using CraneExpected = std::expected; +template +using CraneErrCodeExpected = std::expected; + inline const char* kCtldDefaultPort = "10011"; inline const char* kCranedDefaultPort = "10010"; inline const char* kCforedDefaultPort = "10012"; @@ -153,12 +157,86 @@ constexpr std::array "Not enough nodes which satisfy resource requirements", }; +const std::unordered_map ErrCodeStrMap = { + {crane::grpc::ErrCode::SUCCESS, "Success"}, + {crane::grpc::ErrCode::ERR_INVALID_UID, "Invalid UID"}, + {crane::grpc::ErrCode::ERR_INVALID_OP_USER, "Invalid Operation User"}, + {crane::grpc::ErrCode::ERR_INVALID_USER, "Invalid User"}, + {crane::grpc::ErrCode::ERR_PERMISSION_USER, "Permission User Error"}, + {crane::grpc::ErrCode::ERR_USER_DUPLICATE_ACCOUNT, "Duplicate User Account"}, + {crane::grpc::ErrCode::ERR_USER_ALLOWED_ACCOUNT, "Allowed User Account"}, + {crane::grpc::ErrCode::ERR_INVALID_ADMIN_LEVEL, "Invalid Admin Level"}, + {crane::grpc::ErrCode::ERR_USER_ACCOUNT_MISMATCH, "User Account Mismatch"}, + {crane::grpc::ErrCode::ERR_NO_ACCOUNT_SPECIFIED, "No Account Specified"}, + {crane::grpc::ErrCode::ERR_INVALID_ACCOUNT, "Invalid Account"}, + {crane::grpc::ErrCode::ERR_DUPLICATE_ACCOUNT, "Duplicate Account"}, + {crane::grpc::ErrCode::ERR_INVALID_PARENTACCOUNT, "Invalid Parent Account"}, + {crane::grpc::ErrCode::ERR_DELETE_ACCOUNT, "Delete Account Error"}, + {crane::grpc::ErrCode::ERR_INVALID_PARTITION, "Invalid Partition"}, + {crane::grpc::ErrCode::ERR_ALLOWED_PARTITION, "Allowed Partition Error"}, + {crane::grpc::ErrCode::ERR_DUPLICATE_PARTITION, "Duplicate Partition"}, + {crane::grpc::ErrCode::ERR_PARENT_ALLOWED_PARTITION, "Parent Allowed Partition"}, + {crane::grpc::ErrCode::ERR_USER_EMPTY_PARTITION, "User Empty Partition"}, + {crane::grpc::ErrCode::ERR_CHILD_HAS_PARTITION, "Child Has Partition"}, + {crane::grpc::ErrCode::ERR_HAS_NO_QOS_IN_PARTITION, "No QoS in Partition"}, + {crane::grpc::ErrCode::ERR_HAS_ALLOWED_QOS_IN_PARTITION, "Has Allowed QoS in Partition"}, + {crane::grpc::ErrCode::ERR_INVALID_QOS, "Invalid QoS"}, + {crane::grpc::ErrCode::ERR_DB_DUPLICATE_QOS, "Duplicate QoS in Database"}, + {crane::grpc::ErrCode::ERR_DELETE_QOS, "Delete QoS Error"}, + {crane::grpc::ErrCode::ERR_CONVERT_TO_INTERGER, "Convert to Integer Error"}, + {crane::grpc::ErrCode::ERR_TIME_LIMIT, "Time Limit Error"}, + {crane::grpc::ErrCode::ERR_ALLOWED_QOS, "Allowed QoS Error"}, + {crane::grpc::ErrCode::ERR_DUPLICATE_QOS, "Duplicate QoS"}, + {crane::grpc::ErrCode::ERR_PARENT_ALLOWED_QOS, "Parent Allowed QoS"}, + {crane::grpc::ErrCode::ERR_SET_ALLOWED_QOS, "Set Allowed QoS Error"}, + {crane::grpc::ErrCode::ERR_ALLOWED_DEFAULT_QOS, "Allowed Default QoS Error"}, + {crane::grpc::ErrCode::ERR_DUPLICATE_DEFAULT_QOS, "Duplicate Default QoS"}, + {crane::grpc::ErrCode::ERR_CHILD_HAS_DEFAULT_QOS, "Child Has Default QoS"}, + {crane::grpc::ErrCode::ERR_SET_ACCOUNT_QOS, "Set Account QoS Error"}, + {crane::grpc::ErrCode::ERR_SET_DEFAULT_QOS, "Set Default QoS Error"}, + {crane::grpc::ErrCode::ERR_IS_DEFAULT_QOS, "Is Default QoS Error"}, + {crane::grpc::ErrCode::ERR_UPDATE_DATABASE, "Update Database Error"}, + {crane::grpc::ErrCode::ERR_GENERIC_FAILURE, "Generic Failure"}, + {crane::grpc::ErrCode::ERR_NO_RESOURCE, "No Resource"}, + {crane::grpc::ErrCode::ERR_NON_EXISTENT, "Non-existent Error"}, + {crane::grpc::ErrCode::ERR_INVALID_NODE_NUM, "Invalid Node Number"}, + {crane::grpc::ErrCode::ERR_INVAILD_NODE_LIST, "Invalid Node List"}, + {crane::grpc::ErrCode::ERR_INVAILD_EX_NODE_LIST, "Invalid Ex Node List"}, + {crane::grpc::ErrCode::ERR_TIME_TIMIT_BEYOND, "Time Limit Beyond"}, + {crane::grpc::ErrCode::ERR_CPUS_PER_TASK_BEYOND, "CPUs Per Task Beyond"}, + {crane::grpc::ErrCode::ERR_NO_ENOUGH_NODE, "No Enough Node"}, + {crane::grpc::ErrCode::ERR_SYSTEM_ERR, "System Error"}, + {crane::grpc::ErrCode::ERR_EXISTING_TASK, "Existing Task"}, + {crane::grpc::ErrCode::ERR_INVALID_PARAM, "Invalid Parameter"}, + {crane::grpc::ErrCode::ERR_STOP, "Stop Error"}, + {crane::grpc::ErrCode::ERR_PERMISSION_DENIED, "Permission Denied"}, + {crane::grpc::ErrCode::ERR_CONNECTION_TIMEOUT, "Connection Timeout"}, + {crane::grpc::ErrCode::ERR_CONNECTION_ABORTED, "Connection Aborted"}, + {crane::grpc::ErrCode::ERR_RPC_FAILURE, "RPC Failure"}, + {crane::grpc::ErrCode::ERR_TOKEN_REQUEST_FAILURE, "Token Request Failure"}, + {crane::grpc::ErrCode::ERR_STREAM_BROKEN, "Stream Broken"}, + {crane::grpc::ErrCode::ERR_INVALID_STUB, "Invalid Stub"}, + {crane::grpc::ErrCode::ERR_CGROUP, "CGroup Error"}, + {crane::grpc::ErrCode::ERR_PROTOBUF, "Protobuf Error"}, + {crane::grpc::ErrCode::ERR_LIB_EVENT, "Lib Event Error"}, + {crane::grpc::ErrCode::ERR_NO_AVAIL_NODE, "No Available Node"} +}; + } inline std::string_view CraneErrStr(CraneErr err) { return Internal::CraneErrStrArr[uint16_t(err)]; } +inline std::string_view CraneErrCodeStr(crane::grpc::ErrCode err) { + auto it = Internal::ErrCodeStrMap.find(err); + if (it != Internal::ErrCodeStrMap.end()) { + return it->second; + } + return "Unknown Error"; +} + + /* ----------- Public definitions for all components */ using PartitionId = std::string;