diff --git a/src/clients/meta/MetaClient.cpp b/src/clients/meta/MetaClient.cpp index 1917a03461b..94d4e008867 100644 --- a/src/clients/meta/MetaClient.cpp +++ b/src/clients/meta/MetaClient.cpp @@ -916,7 +916,7 @@ Status MetaClient::handleResponse(const RESP& resp) { case nebula::cpp2::ErrorCode::E_INVALID_JOB: return Status::Error("No valid job!"); case nebula::cpp2::ErrorCode::E_JOB_NOT_IN_SPACE: - return Status::Error("Job not in chosen space!"); + return Status::Error("Job not existed in chosen space!"); case nebula::cpp2::ErrorCode::E_BACKUP_EMPTY_TABLE: return Status::Error("Backup empty table!"); case nebula::cpp2::ErrorCode::E_BACKUP_TABLE_FAILED: @@ -1149,8 +1149,9 @@ PartitionID MetaClient::partId(int32_t numParts, const VertexID id) const { } folly::Future> MetaClient::submitJob( - cpp2::JobOp op, cpp2::JobType type, std::vector paras) { + GraphSpaceID spaceId, cpp2::JobOp op, cpp2::JobType type, std::vector paras) { cpp2::AdminJobReq req; + req.space_id_ref() = spaceId; req.op_ref() = op; req.type_ref() = type; req.paras_ref() = std::move(paras); @@ -3235,12 +3236,14 @@ folly::Future> MetaClient::getStats(GraphSpaceID space } folly::Future> MetaClient::reportTaskFinish( + GraphSpaceID spaceId, int32_t jobId, int32_t taskId, nebula::cpp2::ErrorCode taskErrCode, cpp2::StatsItem* statisticItem) { cpp2::ReportTaskReq req; req.code_ref() = taskErrCode; + req.space_id_ref() = spaceId; req.job_id_ref() = jobId; req.task_id_ref() = taskId; if (statisticItem) { diff --git a/src/clients/meta/MetaClient.h b/src/clients/meta/MetaClient.h index 3c210ca2a92..eb089a7af6d 100644 --- a/src/clients/meta/MetaClient.h +++ b/src/clients/meta/MetaClient.h @@ -259,7 +259,8 @@ class MetaClient : public BaseMetaClient { listener_ = nullptr; } - folly::Future> submitJob(cpp2::JobOp op, + folly::Future> submitJob(GraphSpaceID spaceId, + cpp2::JobOp op, cpp2::JobType type, std::vector paras); @@ -627,6 +628,7 @@ class MetaClient : public BaseMetaClient { folly::Future> getStats(GraphSpaceID spaceId); folly::Future> reportTaskFinish( + GraphSpaceID spaceId, int32_t jobId, int32_t taskId, nebula::cpp2::ErrorCode taskErrCode, diff --git a/src/common/utils/MetaKeyUtils.cpp b/src/common/utils/MetaKeyUtils.cpp index 3ec39e59945..95ed030f2d2 100644 --- a/src/common/utils/MetaKeyUtils.cpp +++ b/src/common/utils/MetaKeyUtils.cpp @@ -55,7 +55,8 @@ static const std::unordered_map< {"balance_plan", {"__balance_plan__", nullptr}}, {"ft_index", {"__ft_index__", nullptr}}, {"local_id", {"__local_id__", MetaKeyUtils::parseLocalIdSpace}}, - {"disk_parts", {"__disk_parts__", MetaKeyUtils::parseDiskPartsSpace}}}; + {"disk_parts", {"__disk_parts__", MetaKeyUtils::parseDiskPartsSpace}}, + {"job_manager", {"__job_mgr__", nullptr}}}; // clang-format off static const std::string kSpacesTable = tableMaps.at("spaces").first; // NOLINT @@ -80,6 +81,18 @@ static const std::string kZonesTable = systemTableMaps.at("zones").firs static const std::string kListenerTable = tableMaps.at("listener").first; // NOLINT static const std::string kDiskPartsTable = tableMaps.at("disk_parts").first; // NOLINT +/* + * There will be one job, and a bunch of tasks use this prefix. + * If there are 1 job(let say 65536) which has 4 sub tasks, there will 5 records + * in kvstore which are + * __job_mgr_<65536> + * __job_mgr_<65536><0> + * __job_mgr_<65536><1> + * __job_mgr_<65536><2> + * __job_mgr_<65536><3> + * */ +static const std::string kJobTable = tableMaps.at("job_manager").first; // NOLINT + // Used to record the number of vertices and edges in the space // The number of vertices of each tag in the space // The number of edges of each edgetype in the space @@ -1354,4 +1367,138 @@ meta::cpp2::PartitionList MetaKeyUtils::parseDiskPartsVal(const folly::StringPie return partList; } +const std::string& MetaKeyUtils::jobPrefix() { + return kJobTable; +} + +std::string MetaKeyUtils::jobPrefix(GraphSpaceID spaceId) { + std::string key; + key.reserve(kJobTable.size() + sizeof(GraphSpaceID)); + key.append(kJobTable.data(), kJobTable.size()) + .append(reinterpret_cast(&spaceId), sizeof(GraphSpaceID)); + return key; +} + +std::string MetaKeyUtils::jobKey(GraphSpaceID spaceID, JobID jobId) { + std::string key; + key.reserve(kJobTable.size() + sizeof(GraphSpaceID) + sizeof(JobID)); + key.append(kJobTable.data(), kJobTable.size()) + .append(reinterpret_cast(&spaceID), sizeof(GraphSpaceID)) + .append(reinterpret_cast(&jobId), sizeof(JobID)); + return key; +} + +bool MetaKeyUtils::isJobKey(const folly::StringPiece& rawKey) { + if (!rawKey.startsWith(kJobTable)) { + return false; + } + return rawKey.size() == kJobTable.size() + sizeof(GraphSpaceID) + sizeof(JobID); +} + +std::string MetaKeyUtils::jobVal(const meta::cpp2::JobType& type, + std::vector paras, + meta::cpp2::JobStatus jobStatus, + int64_t startTime, + int64_t stopTime) { + std::string val; + val.reserve(256); + val.append(reinterpret_cast(&type), sizeof(meta::cpp2::JobType)); + auto paraSize = paras.size(); + val.append(reinterpret_cast(¶Size), sizeof(size_t)); + for (auto& para : paras) { + auto len = para.length(); + val.append(reinterpret_cast(&len), sizeof(len)) + .append(reinterpret_cast(¶[0]), len); + } + val.append(reinterpret_cast(&jobStatus), sizeof(meta::cpp2::JobStatus)) + .append(reinterpret_cast(&startTime), sizeof(int64_t)) + .append(reinterpret_cast(&stopTime), sizeof(int64_t)); + return val; +} + +std::tuple, meta::cpp2::JobStatus, int64_t, int64_t> +MetaKeyUtils::parseJobVal(folly::StringPiece rawVal) { + CHECK_GE(rawVal.size(), + sizeof(meta::cpp2::JobType) + sizeof(size_t) + sizeof(meta::cpp2::JobStatus) + + sizeof(int64_t) * 2); + auto type = *reinterpret_cast(rawVal.data()); + auto offset = sizeof(const meta::cpp2::JobType); + + std::vector paras; + auto vec_size = *reinterpret_cast(rawVal.data() + offset); + offset += sizeof(size_t); + for (size_t i = 0; i < vec_size; ++i) { + auto len = *reinterpret_cast(rawVal.data() + offset); + offset += sizeof(size_t); + paras.emplace_back(rawVal.data() + offset, len); + offset += len; + } + + auto status = *reinterpret_cast(rawVal.data() + offset); + offset += sizeof(meta::cpp2::JobStatus); + auto tStart = *reinterpret_cast(rawVal.data() + offset); + offset += sizeof(int64_t); + auto tStop = *reinterpret_cast(rawVal.data() + offset); + return std::make_tuple(type, paras, status, tStart, tStop); +} + +std::pair MetaKeyUtils::parseJobKey(folly::StringPiece key) { + auto offset = kJobTable.size(); + auto spaceId = *reinterpret_cast(key.data() + offset); + offset += sizeof(GraphSpaceID); + auto jobId = *reinterpret_cast(key.data() + offset); + return std::make_pair(spaceId, jobId); +} + +std::string MetaKeyUtils::taskKey(GraphSpaceID spaceId, JobID jobId, TaskID taskId) { + std::string key; + key.reserve(kJobTable.size() + sizeof(GraphSpaceID) + sizeof(JobID) + sizeof(TaskID)); + key.append(kJobTable.data(), kJobTable.size()) + .append(reinterpret_cast(&spaceId), sizeof(GraphSpaceID)) + .append(reinterpret_cast(&jobId), sizeof(JobID)) + .append(reinterpret_cast(&taskId), sizeof(TaskID)); + return key; +} + +std::tuple MetaKeyUtils::parseTaskKey(folly::StringPiece key) { + auto offset = kJobTable.size(); + auto spaceId = *reinterpret_cast(key.data() + offset); + offset += sizeof(GraphSpaceID); + auto jobId = *reinterpret_cast(key.data() + offset); + offset += sizeof(JobID); + auto taskId = *reinterpret_cast(key.data() + offset); + return std::make_tuple(spaceId, jobId, taskId); +} + +std::string MetaKeyUtils::taskVal(HostAddr host, + meta::cpp2::JobStatus jobStatus, + int64_t startTime, + int64_t stopTime) { + std::string val; + val.reserve(128); + val.append(MetaKeyUtils::serializeHostAddr(host)) + .append(reinterpret_cast(&jobStatus), sizeof(meta::cpp2::JobStatus)) + .append(reinterpret_cast(&startTime), sizeof(int64_t)) + .append(reinterpret_cast(&stopTime), sizeof(int64_t)); + return val; +} + +std::tuple MetaKeyUtils::parseTaskVal( + folly::StringPiece rawVal) { + CHECK_GE(rawVal.size(), + sizeof(size_t) + sizeof(Port) + sizeof(meta::cpp2::JobStatus) + sizeof(int64_t) * 2); + size_t offset = 0; + HostAddr host = MetaKeyUtils::deserializeHostAddr(rawVal); + offset += sizeof(size_t); + offset += host.host.size(); + offset += sizeof(uint32_t); + + auto status = *reinterpret_cast(rawVal.data() + offset); + offset += sizeof(meta::cpp2::JobStatus); + auto tStart = *reinterpret_cast(rawVal.data() + offset); + offset += sizeof(int64_t); + auto tStop = *reinterpret_cast(rawVal.data() + offset); + return std::make_tuple(host, status, tStart, tStop); +} + } // namespace nebula diff --git a/src/common/utils/MetaKeyUtils.h b/src/common/utils/MetaKeyUtils.h index fd2eac22ad9..c1dde6ae5fc 100644 --- a/src/common/utils/MetaKeyUtils.h +++ b/src/common/utils/MetaKeyUtils.h @@ -424,6 +424,54 @@ class MetaKeyUtils final { static std::string diskPartsVal(const meta::cpp2::PartitionList& partList); static meta::cpp2::PartitionList parseDiskPartsVal(const folly::StringPiece& rawData); + + // job related + static const std::string& jobPrefix(); + + static std::string jobPrefix(GraphSpaceID spaceId); + + /** + * @brief Encoded job key, it should be + * kJobTable+spceId+jobid + */ + static std::string jobKey(GraphSpaceID spaceId, JobID iJob); + + static bool isJobKey(const folly::StringPiece& rawKey); + + static std::string jobVal(const meta::cpp2::JobType& type, + std::vector paras, + meta::cpp2::JobStatus jobStatus, + int64_t startTime, + int64_t stopTime); + /** + * @brief Decode val from kvstore, return + * {jobType, paras, status, start time, stop time} + */ + static std:: + tuple, meta::cpp2::JobStatus, int64_t, int64_t> + parseJobVal(folly::StringPiece rawVal); + + static std::pair parseJobKey(folly::StringPiece key); + + // task related + /** + * @brief Encoded task key, it should bekJobTable+spceId+jobid+taskid + */ + static std::string taskKey(GraphSpaceID spaceId, JobID jobId, TaskID taskId); + + static std::tuple parseTaskKey(folly::StringPiece key); + + static std::string taskVal(HostAddr host, + meta::cpp2::JobStatus jobStatus, + int64_t startTime, + int64_t stopTime); + + /** + * @brief Decode task val,it should be + * {host, status, start time, stop time} + */ + static std::tuple parseTaskVal( + folly::StringPiece rawVal); }; } // namespace nebula diff --git a/src/common/utils/NebulaKeyUtils.cpp b/src/common/utils/NebulaKeyUtils.cpp index 4e155f084aa..31b24fc57ba 100644 --- a/src/common/utils/NebulaKeyUtils.cpp +++ b/src/common/utils/NebulaKeyUtils.cpp @@ -272,15 +272,37 @@ std::string NebulaKeyUtils::toEdgeKey(const folly::StringPiece& lockKey) { return ret; } -std::string NebulaKeyUtils::adminTaskKey(int32_t seqId, JobID jobId, TaskID taskId) { +std::string NebulaKeyUtils::adminTaskKey(int32_t seqId, + GraphSpaceID spaceId, + JobID jobId, + TaskID taskId) { std::string key; - key.reserve(sizeof(int32_t) + sizeof(JobID) + sizeof(TaskID)); - key.append(reinterpret_cast(&seqId), sizeof(int32_t)); - key.append(reinterpret_cast(&jobId), sizeof(JobID)); - key.append(reinterpret_cast(&taskId), sizeof(TaskID)); + key.reserve(sizeof(int32_t) + sizeof(GraphSpaceID) + sizeof(JobID) + sizeof(TaskID)); + key.append(reinterpret_cast(&seqId), sizeof(int32_t)) + .append(reinterpret_cast(&spaceId), sizeof(GraphSpaceID)) + .append(reinterpret_cast(&jobId), sizeof(JobID)) + .append(reinterpret_cast(&taskId), sizeof(TaskID)); return key; } +bool NebulaKeyUtils::isAdminTaskKey(const folly::StringPiece& rawKey) { + return rawKey.size() == sizeof(int32_t) + sizeof(GraphSpaceID) + sizeof(JobID) + sizeof(TaskID); +} + +std::tuple NebulaKeyUtils::parseAdminTaskKey( + folly::StringPiece key) { + CHECK_EQ(key.size(), sizeof(int32_t) + sizeof(GraphSpaceID) + sizeof(JobID) + sizeof(TaskID)); + size_t offset = 0; + int32_t seqId = *reinterpret_cast(key.data()); + offset += sizeof(int32_t); + GraphSpaceID spaceId = *reinterpret_cast(key.data() + offset); + offset += sizeof(GraphSpaceID); + JobID jobId = *reinterpret_cast(key.data() + offset); + offset += sizeof(JobID); + TaskID taskId = *reinterpret_cast(key.data() + offset); + return std::make_tuple(seqId, spaceId, jobId, taskId); +} + std::string NebulaKeyUtils::dataVersionKey() { return "\xFF\xFF\xFF\xFF"; } diff --git a/src/common/utils/NebulaKeyUtils.h b/src/common/utils/NebulaKeyUtils.h index 985cfe8959e..17cbd88bccc 100644 --- a/src/common/utils/NebulaKeyUtils.h +++ b/src/common/utils/NebulaKeyUtils.h @@ -275,7 +275,11 @@ class NebulaKeyUtils final { LOG(FATAL) << msg.str(); } - static std::string adminTaskKey(int32_t seqId, JobID jobId, TaskID taskId); + static std::string adminTaskKey(int32_t seqId, GraphSpaceID spaceId, JobID jobId, TaskID taskId); + + static bool isAdminTaskKey(const folly::StringPiece& rawKey); + + static std::tuple parseAdminTaskKey(folly::StringPiece key); static std::string dataVersionKey(); diff --git a/src/graph/executor/admin/SubmitJobExecutor.cpp b/src/graph/executor/admin/SubmitJobExecutor.cpp index d75464c1c15..f61ce10e58c 100644 --- a/src/graph/executor/admin/SubmitJobExecutor.cpp +++ b/src/graph/executor/admin/SubmitJobExecutor.cpp @@ -19,13 +19,14 @@ folly::Future SubmitJobExecutor::execute() { SCOPED_TIMER(&execTime_); auto *sjNode = asNode(node()); + auto spaceId = qctx()->rctx()->session()->space().id; auto jobOp = sjNode->jobOp(); auto jobType = sjNode->jobType(); auto params = sjNode->params(); return qctx() ->getMetaClient() - ->submitJob(jobOp, jobType, params) + ->submitJob(spaceId, jobOp, jobType, params) .via(runner()) .thenValue([jobOp, this](StatusOr &&resp) { SCOPED_TIMER(&execTime_); @@ -82,7 +83,7 @@ StatusOr SubmitJobExecutor::buildResult(meta::cpp2::JobOp jobOp, const auto &jobsDesc = *resp.job_desc_ref(); for (const auto &jobDesc : jobsDesc) { v.emplace_back(nebula::Row({ - jobDesc.get_id(), + jobDesc.get_job_id(), apache::thrift::util::enumNameSafe(jobDesc.get_type()), apache::thrift::util::enumNameSafe(jobDesc.get_status()), convertJobTimestampToDateTime(jobDesc.get_start_time()), @@ -117,7 +118,7 @@ nebula::DataSet SubmitJobExecutor::buildShowResultData( size_t index = std::stoul(paras.back()); uint32_t total = paras.size() - index - 1, succeeded = 0, failed = 0, inProgress = 0, invalid = 0; - v.emplace_back(Row({jd.get_id(), + v.emplace_back(Row({jd.get_job_id(), apache::thrift::util::enumNameSafe(jd.get_type()), apache::thrift::util::enumNameSafe(jd.get_status()), convertJobTimestampToDateTime(jd.get_start_time()).toString(), @@ -154,7 +155,7 @@ nebula::DataSet SubmitJobExecutor::buildShowResultData( } else { nebula::DataSet v({"Job Id(TaskId)", "Command(Dest)", "Status", "Start Time", "Stop Time"}); v.emplace_back(nebula::Row({ - jd.get_id(), + jd.get_job_id(), apache::thrift::util::enumNameSafe(jd.get_type()), apache::thrift::util::enumNameSafe(jd.get_status()), convertJobTimestampToDateTime(jd.get_start_time()), diff --git a/src/graph/executor/test/JobTest.cpp b/src/graph/executor/test/JobTest.cpp index 7dbd51e8c4e..46e83455bd5 100644 --- a/src/graph/executor/test/JobTest.cpp +++ b/src/graph/executor/test/JobTest.cpp @@ -19,7 +19,7 @@ TEST_F(JobTest, JobFinishTime) { meta::cpp2::AdminJobResult resp; resp.job_id_ref() = 0; meta::cpp2::JobDesc jobDesc; - jobDesc.id_ref() = 0; + jobDesc.job_id_ref() = 0; jobDesc.start_time_ref() = 123; jobDesc.stop_time_ref() = 0; resp.job_desc_ref() = {std::move(jobDesc)}; @@ -46,7 +46,7 @@ TEST_F(JobTest, JobFinishTime) { meta::cpp2::AdminJobResult resp; resp.job_id_ref() = 0; meta::cpp2::JobDesc jobDesc; - jobDesc.id_ref() = 0; + jobDesc.job_id_ref() = 0; jobDesc.start_time_ref() = 123; jobDesc.stop_time_ref() = 0; resp.job_desc_ref() = {std::move(jobDesc)}; diff --git a/src/graph/validator/AdminJobValidator.cpp b/src/graph/validator/AdminJobValidator.cpp index 533422d98d0..5338a8caff4 100644 --- a/src/graph/validator/AdminJobValidator.cpp +++ b/src/graph/validator/AdminJobValidator.cpp @@ -15,13 +15,14 @@ Status AdminJobValidator::validateImpl() { sentence_->getJobType() == meta::cpp2::JobType::ZONE_BALANCE) { return Status::SemanticError("Data balance not support"); } + + // Note: The last parameter of paras is no longer spacename if (sentence_->getOp() == meta::cpp2::JobOp::ADD) { auto jobType = sentence_->getJobType(); if (requireSpace()) { const auto &spaceInfo = vctx_->whichSpace(); auto spaceId = spaceInfo.id; const auto &spaceName = spaceInfo.name; - sentence_->addPara(spaceName); if (jobType == meta::cpp2::JobType::REBUILD_TAG_INDEX || jobType == meta::cpp2::JobType::REBUILD_EDGE_INDEX) { @@ -35,10 +36,10 @@ Status AdminJobValidator::validateImpl() { } auto indexes = std::move(ret).value(); const auto ¶s = sentence_->getParas(); - if (paras.size() == 1 && indexes.empty()) { + if (paras.empty() && indexes.empty()) { return Status::SemanticError("Space `%s' without indexes", spaceName.c_str()); } - for (auto i = 0u; i < paras.size() - 1; i++) { + for (auto i = 0u; i < paras.size(); i++) { const auto &indexName = paras[i]; auto it = std::find_if(indexes.begin(), indexes.end(), @@ -52,8 +53,6 @@ Status AdminJobValidator::validateImpl() { } } } - } else { - sentence_->addPara(qctx()->rctx()->session()->space().name); } return Status::OK(); } diff --git a/src/interface/meta.thrift b/src/interface/meta.thrift index e29de9612ca..8a45688bde4 100644 --- a/src/interface/meta.thrift +++ b/src/interface/meta.thrift @@ -244,9 +244,10 @@ enum JobType { } (cpp.enum_strict) struct AdminJobReq { - 1: JobOp op, - 2: JobType type, - 3: list paras, + 1: common.GraphSpaceID space_id, + 2: JobOp op, + 3: JobType type, + 4: list paras, } enum JobStatus { @@ -259,27 +260,29 @@ enum JobStatus { } (cpp.enum_strict) struct JobDesc { - 1: i32 id, - 2: JobType type, - 3: list paras, - 4: JobStatus status, - 5: i64 start_time, - 6: i64 stop_time, + 1: common.GraphSpaceID space_id, + 2: i32 job_id, + 3: JobType type, + 4: list paras, + 5: JobStatus status, + 6: i64 start_time, + 7: i64 stop_time, } struct TaskDesc { - 1: i32 task_id, - 2: common.HostAddr host, - 3: JobStatus status, - 4: i64 start_time, - 5: i64 stop_time, - 6: i32 job_id, + 1: common.GraphSpaceID space_id, + 2: i32 job_id, + 3: i32 task_id, + 4: common.HostAddr host, + 5: JobStatus status, + 6: i64 start_time, + 7: i64 stop_time, } struct AdminJobResult { // used in a new added job, e.g. "flush" "compact" // other job type which also need jobId in their result - // will use other filed. e.g. JobDesc::id + // will use other filed. e.g. JobDesc::job_id 1: optional i32 job_id, // used in "show jobs" and "show job " @@ -1117,9 +1120,10 @@ struct KillQueryReq { struct ReportTaskReq { 1: common.ErrorCode code, - 2: i32 job_id, - 3: i32 task_id, - 4: optional StatsItem stats + 2: common.GraphSpaceID space_id, + 3: i32 job_id, + 4: i32 task_id, + 5: optional StatsItem stats } struct ListClusterInfoResp { diff --git a/src/meta/CMakeLists.txt b/src/meta/CMakeLists.txt index 80527f96bdb..1af91ac7a9e 100644 --- a/src/meta/CMakeLists.txt +++ b/src/meta/CMakeLists.txt @@ -64,7 +64,6 @@ nebula_add_library( processors/job/JobStatus.cpp processors/job/AdminJobProcessor.cpp processors/job/ReportTaskProcessor.cpp - processors/job/JobUtils.cpp processors/job/StorageJobExecutor.cpp processors/job/JobExecutor.cpp processors/job/MetaJobExecutor.cpp diff --git a/src/meta/MetaVersionMan.cpp b/src/meta/MetaVersionMan.cpp index 8e22c0d8c34..41acf1f001e 100644 --- a/src/meta/MetaVersionMan.cpp +++ b/src/meta/MetaVersionMan.cpp @@ -8,7 +8,6 @@ #include "common/fs/FileUtils.h" #include "meta/ActiveHostsMan.h" #include "meta/processors/job/JobDescription.h" -#include "meta/processors/job/JobUtils.h" #include "meta/upgrade/MetaDataUpgrade.h" #include "meta/upgrade/v2/MetaServiceUtilsV2.h" diff --git a/src/meta/processors/admin/CreateBackupProcessor.cpp b/src/meta/processors/admin/CreateBackupProcessor.cpp index b345a9f0e3a..2597113eda4 100644 --- a/src/meta/processors/admin/CreateBackupProcessor.cpp +++ b/src/meta/processors/admin/CreateBackupProcessor.cpp @@ -83,7 +83,9 @@ void CreateBackupProcessor::process(const cpp2::CreateBackupReq& req) { JobManager* jobMgr = JobManager::getInstance(); // make sure there is no index job - auto result = jobMgr->checkIndexJobRunning(); + std::unordered_set jobTypes{cpp2::JobType::REBUILD_TAG_INDEX, + cpp2::JobType::REBUILD_EDGE_INDEX}; + auto result = jobMgr->checkTypeJobRunning(jobTypes); if (!nebula::ok(result)) { LOG(INFO) << "Get Index status failed, not allowed to create backup."; handleErrorCode(nebula::error(result)); diff --git a/src/meta/processors/admin/CreateSnapshotProcessor.cpp b/src/meta/processors/admin/CreateSnapshotProcessor.cpp index b870c5dc336..0a1e437c926 100644 --- a/src/meta/processors/admin/CreateSnapshotProcessor.cpp +++ b/src/meta/processors/admin/CreateSnapshotProcessor.cpp @@ -16,7 +16,9 @@ void CreateSnapshotProcessor::process(const cpp2::CreateSnapshotReq&) { // check the index rebuild. not allowed to create snapshot when index // rebuilding. JobManager* jobMgr = JobManager::getInstance(); - auto result = jobMgr->checkIndexJobRunning(); + std::unordered_set jobTypes{cpp2::JobType::REBUILD_TAG_INDEX, + cpp2::JobType::REBUILD_EDGE_INDEX}; + auto result = jobMgr->checkTypeJobRunning(jobTypes); if (!nebula::ok(result)) { handleErrorCode(nebula::error(result)); onFinished(); diff --git a/src/meta/processors/job/AdminJobProcessor.cpp b/src/meta/processors/job/AdminJobProcessor.cpp index 9e1e4c41026..b073ffb4ecf 100644 --- a/src/meta/processors/job/AdminJobProcessor.cpp +++ b/src/meta/processors/job/AdminJobProcessor.cpp @@ -18,12 +18,18 @@ void AdminJobProcessor::process(const cpp2::AdminJobReq& req) { if (req.get_op() == nebula::meta::cpp2::JobOp::ADD) { oss << ", type = " << apache::thrift::util::enumNameSafe(req.get_type()); } - oss << ", paras.size()=" << req.get_paras().size(); - for (auto& p : req.get_paras()) { + + auto paras = req.get_paras(); + oss << ", paras.size()=" << paras.size(); + for (auto& p : paras) { oss << " " << p; } LOG(INFO) << __func__ << "() " << oss.str(); + // Check if space not exists + spaceId_ = req.get_space_id(); + CHECK_SPACE_ID_AND_RETURN(spaceId_); + cpp2::AdminJobResult result; auto errorCode = nebula::cpp2::ErrorCode::SUCCEEDED; jobMgr_ = JobManager::getInstance(); @@ -34,7 +40,7 @@ void AdminJobProcessor::process(const cpp2::AdminJobReq& req) { break; } case nebula::meta::cpp2::JobOp::SHOW_All: { - auto ret = jobMgr_->showJobs(req.get_paras().back()); + auto ret = jobMgr_->showJobs(spaceId_); if (nebula::ok(ret)) { result.job_desc_ref() = nebula::value(ret); } else { @@ -42,21 +48,22 @@ void AdminJobProcessor::process(const cpp2::AdminJobReq& req) { } break; } + case nebula::meta::cpp2::JobOp::SHOW: { - static const size_t kShowArgsNum = 2; - if (req.get_paras().size() != kShowArgsNum) { - LOG(INFO) << "Parameter number not matched"; + // show job jobId should have a parameter as jobId + if (paras.size() != 1) { + LOG(INFO) << "Show job jobId can only have one parameter."; errorCode = nebula::cpp2::ErrorCode::E_INVALID_PARM; break; } - int iJob = atoi(req.get_paras()[0].c_str()); - if (iJob == 0) { - LOG(INFO) << "Show job should have parameter as the job ID"; + int jobId = atoi(paras[0].c_str()); + if (jobId == 0) { + LOG(INFO) << "Show job jobId should have one parameter as the job ID"; errorCode = nebula::cpp2::ErrorCode::E_INVALID_PARM; break; } - auto ret = jobMgr_->showJob(iJob, req.get_paras().back()); + auto ret = jobMgr_->showJob(spaceId_, jobId); if (nebula::ok(ret)) { result.job_desc_ref() = std::vector{nebula::value(ret).first}; result.task_desc_ref() = nebula::value(ret).second; @@ -65,31 +72,31 @@ void AdminJobProcessor::process(const cpp2::AdminJobReq& req) { } break; } + case nebula::meta::cpp2::JobOp::STOP: { - static const size_t kStopJobArgsNum = 2; - if (req.get_paras().size() != kStopJobArgsNum) { - LOG(INFO) << "Parameter number not matched"; + // stop job should have a parameter as jobId + if (paras.size() != 1) { + LOG(INFO) << "Stop job jobId can only have one parameter"; errorCode = nebula::cpp2::ErrorCode::E_INVALID_PARM; break; } - int iJob = atoi(req.get_paras()[0].c_str()); - if (iJob == 0) { - LOG(INFO) << "Stop job should have parameter as the job ID"; + JobID jobId = atoi(paras[0].c_str()); + if (jobId == 0) { + LOG(INFO) << "Stop job should have one parameter as the job ID"; errorCode = nebula::cpp2::ErrorCode::E_INVALID_PARM; break; } - errorCode = jobMgr_->stopJob(iJob, req.get_paras().back()); + errorCode = jobMgr_->stopJob(spaceId_, jobId); break; } case nebula::meta::cpp2::JobOp::RECOVER: { - const std::vector& paras = req.get_paras(); - const std::string& spaceName = req.get_paras().back(); + // Note that the last parameter is no longer spaceId std::vector jobIds; - jobIds.reserve(paras.size() - 1); - for (size_t i = 0; i < paras.size() - 1; i++) { + jobIds.reserve(paras.size()); + for (size_t i = 0; i < paras.size(); i++) { jobIds.push_back(std::stoi(paras[i])); } - auto ret = jobMgr_->recoverJob(spaceName, adminClient_, jobIds); + auto ret = jobMgr_->recoverJob(spaceId_, adminClient_, jobIds); if (nebula::ok(ret)) { result.recovered_job_num_ref() = nebula::value(ret); } else { @@ -116,25 +123,9 @@ nebula::cpp2::ErrorCode AdminJobProcessor::addJobProcess(const cpp2::AdminJobReq auto type = req.get_type(); auto paras = req.get_paras(); - // All jobs here are the space level, so the last parameter is spaceName. - if (paras.empty()) { - LOG(INFO) << "Parameter should be not empty"; - return nebula::cpp2::ErrorCode::E_INVALID_PARM; - } - - // Check if space not exists - auto spaceName = paras.back(); - auto spaceRet = getSpaceId(spaceName); - if (!nebula::ok(spaceRet)) { - auto retCode = nebula::error(spaceRet); - LOG(INFO) << "Get space failed, space name: " << spaceName - << " error: " << apache::thrift::util::enumNameSafe(retCode); - return retCode; - } - // Check if job not exists JobID jId = 0; - auto jobExist = jobMgr_->checkJobExist(type, paras, jId); + auto jobExist = jobMgr_->checkJobExist(spaceId_, type, paras, jId); if (jobExist) { LOG(INFO) << "Job has already exists: " << jId; result.job_id_ref() = jId; @@ -147,7 +138,7 @@ nebula::cpp2::ErrorCode AdminJobProcessor::addJobProcess(const cpp2::AdminJobReq return nebula::error(jobId); } - JobDescription jobDesc(nebula::value(jobId), type, paras); + JobDescription jobDesc(spaceId_, nebula::value(jobId), type, paras); auto errorCode = jobMgr_->addJob(jobDesc, adminClient_); if (errorCode == nebula::cpp2::ErrorCode::SUCCEEDED) { result.job_id_ref() = nebula::value(jobId); diff --git a/src/meta/processors/job/AdminJobProcessor.h b/src/meta/processors/job/AdminJobProcessor.h index 09836e127ef..e5340b7bbcc 100644 --- a/src/meta/processors/job/AdminJobProcessor.h +++ b/src/meta/processors/job/AdminJobProcessor.h @@ -32,6 +32,7 @@ class AdminJobProcessor : public BaseProcessor { private: /** * @brief Check whether the parameters are legal, then construct the job and join the queue. + * All jobs here are the space level, the last parameter is no longer spaceName. * * @param req * @param result @@ -42,6 +43,7 @@ class AdminJobProcessor : public BaseProcessor { protected: AdminClient* adminClient_{nullptr}; JobManager* jobMgr_{nullptr}; + GraphSpaceID spaceId_; }; } // namespace meta diff --git a/src/meta/processors/job/BalanceJobExecutor.cpp b/src/meta/processors/job/BalanceJobExecutor.cpp index aab915d700d..8244c816bea 100644 --- a/src/meta/processors/job/BalanceJobExecutor.cpp +++ b/src/meta/processors/job/BalanceJobExecutor.cpp @@ -9,15 +9,15 @@ #include "common/utils/MetaKeyUtils.h" #include "kvstore/NebulaStore.h" -#include "meta/processors/job/JobUtils.h" namespace nebula { namespace meta { -BalanceJobExecutor::BalanceJobExecutor(JobID jobId, +BalanceJobExecutor::BalanceJobExecutor(GraphSpaceID space, + JobID jobId, kvstore::KVStore* kvstore, AdminClient* adminClient, const std::vector& paras) - : MetaJobExecutor(jobId, kvstore, adminClient, paras) {} + : MetaJobExecutor(space, jobId, kvstore, adminClient, paras) {} bool BalanceJobExecutor::check() { return !paras_.empty(); @@ -43,7 +43,8 @@ nebula::cpp2::ErrorCode BalanceJobExecutor::recovery() { // if not leader. return nebula::cpp2::ErrorCode::E_LEADER_CHANGED; } - auto jobKey = JobDescription::makeJobKey(jobId_); + + auto jobKey = MetaKeyUtils::jobKey(space_, jobId_); std::string value; auto retCode = kvstore_->get(kDefaultSpaceId, kDefaultPartId, jobKey, &value); if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { diff --git a/src/meta/processors/job/BalanceJobExecutor.h b/src/meta/processors/job/BalanceJobExecutor.h index 9757dc83b21..904d7cedac2 100644 --- a/src/meta/processors/job/BalanceJobExecutor.h +++ b/src/meta/processors/job/BalanceJobExecutor.h @@ -88,7 +88,8 @@ struct SpaceInfo { */ class BalanceJobExecutor : public MetaJobExecutor { public: - BalanceJobExecutor(JobID jobId, + BalanceJobExecutor(GraphSpaceID space, + JobID jobId, kvstore::KVStore* kvstore, AdminClient* adminClient, const std::vector& params); diff --git a/src/meta/processors/job/CompactJobExecutor.cpp b/src/meta/processors/job/CompactJobExecutor.cpp index ef689d0663c..7efbafaa4c6 100644 --- a/src/meta/processors/job/CompactJobExecutor.cpp +++ b/src/meta/processors/job/CompactJobExecutor.cpp @@ -8,11 +8,12 @@ namespace nebula { namespace meta { -CompactJobExecutor::CompactJobExecutor(JobID jobId, +CompactJobExecutor::CompactJobExecutor(GraphSpaceID space, + JobID jobId, kvstore::KVStore* kvstore, AdminClient* adminClient, const std::vector& paras) - : SimpleConcurrentJobExecutor(jobId, kvstore, adminClient, paras) {} + : SimpleConcurrentJobExecutor(space, jobId, kvstore, adminClient, paras) {} folly::Future CompactJobExecutor::executeInternal(HostAddr&& address, std::vector&& parts) { diff --git a/src/meta/processors/job/CompactJobExecutor.h b/src/meta/processors/job/CompactJobExecutor.h index 9f3969933fa..b9bd56d36a2 100644 --- a/src/meta/processors/job/CompactJobExecutor.h +++ b/src/meta/processors/job/CompactJobExecutor.h @@ -16,7 +16,8 @@ namespace meta { */ class CompactJobExecutor : public SimpleConcurrentJobExecutor { public: - CompactJobExecutor(JobID jobId, + CompactJobExecutor(GraphSpaceID space, + JobID jobId, kvstore::KVStore* kvstore, AdminClient* adminClient, const std::vector& params); diff --git a/src/meta/processors/job/DataBalanceJobExecutor.cpp b/src/meta/processors/job/DataBalanceJobExecutor.cpp index 4a54e9694e8..e89d9ce1dbe 100644 --- a/src/meta/processors/job/DataBalanceJobExecutor.cpp +++ b/src/meta/processors/job/DataBalanceJobExecutor.cpp @@ -11,7 +11,6 @@ #include "common/utils/MetaKeyUtils.h" #include "kvstore/NebulaStore.h" -#include "meta/processors/job/JobUtils.h" namespace nebula { namespace meta { @@ -201,18 +200,18 @@ nebula::cpp2::ErrorCode DataBalanceJobExecutor::stop() { } nebula::cpp2::ErrorCode DataBalanceJobExecutor::prepare() { - auto spaceRet = getSpaceIdFromName(paras_.back()); - if (!nebula::ok(spaceRet)) { - LOG(INFO) << "Can't find the space: " << paras_.back(); - return nebula::error(spaceRet); + auto spaceRet = spaceExist(); + if (spaceRet != nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(INFO) << "Can't find the space, spaceId " << space_; + return spaceRet; } - GraphSpaceID spaceId = nebula::value(spaceRet); - nebula::cpp2::ErrorCode rc = spaceInfo_.loadInfo(spaceId, kvstore_); + + nebula::cpp2::ErrorCode rc = spaceInfo_.loadInfo(space_, kvstore_); if (rc != nebula::cpp2::ErrorCode::SUCCEEDED) { return rc; } - lostHosts_.reserve(paras_.size() - 1); - for (size_t i = 0; i < paras_.size() - 1; i++) { + lostHosts_.reserve(paras_.size()); + for (size_t i = 0; i < paras_.size(); i++) { lostHosts_.emplace_back(HostAddr::fromString(paras_[i])); } return nebula::cpp2::ErrorCode::SUCCEEDED; diff --git a/src/meta/processors/job/DataBalanceJobExecutor.h b/src/meta/processors/job/DataBalanceJobExecutor.h index a6b27d789a0..0ba45a01728 100644 --- a/src/meta/processors/job/DataBalanceJobExecutor.h +++ b/src/meta/processors/job/DataBalanceJobExecutor.h @@ -25,7 +25,8 @@ class DataBalanceJobExecutor : public BalanceJobExecutor { kvstore::KVStore* kvstore, AdminClient* adminClient, const std::vector& params) - : BalanceJobExecutor(jobDescription.getJobId(), kvstore, adminClient, params), + : BalanceJobExecutor( + jobDescription.getSpace(), jobDescription.getJobId(), kvstore, adminClient, params), jobDescription_(jobDescription) {} /** diff --git a/src/meta/processors/job/FlushJobExecutor.cpp b/src/meta/processors/job/FlushJobExecutor.cpp index cbdfae4eb38..af264d25bab 100644 --- a/src/meta/processors/job/FlushJobExecutor.cpp +++ b/src/meta/processors/job/FlushJobExecutor.cpp @@ -8,11 +8,12 @@ namespace nebula { namespace meta { -FlushJobExecutor::FlushJobExecutor(JobID jobId, +FlushJobExecutor::FlushJobExecutor(GraphSpaceID space, + JobID jobId, kvstore::KVStore* kvstore, AdminClient* adminClient, const std::vector& paras) - : SimpleConcurrentJobExecutor(jobId, kvstore, adminClient, paras) {} + : SimpleConcurrentJobExecutor(space, jobId, kvstore, adminClient, paras) {} folly::Future FlushJobExecutor::executeInternal(HostAddr&& address, std::vector&& parts) { diff --git a/src/meta/processors/job/FlushJobExecutor.h b/src/meta/processors/job/FlushJobExecutor.h index a1ff6081ed1..f0b2dd0d953 100644 --- a/src/meta/processors/job/FlushJobExecutor.h +++ b/src/meta/processors/job/FlushJobExecutor.h @@ -16,7 +16,8 @@ namespace meta { */ class FlushJobExecutor : public SimpleConcurrentJobExecutor { public: - FlushJobExecutor(JobID jobId, + FlushJobExecutor(GraphSpaceID space, + JobID jobId, kvstore::KVStore* kvstore, AdminClient* adminClient, const std::vector& params); diff --git a/src/meta/processors/job/JobDescription.cpp b/src/meta/processors/job/JobDescription.cpp index c3c102b0b08..4e9d2cedd67 100644 --- a/src/meta/processors/job/JobDescription.cpp +++ b/src/meta/processors/job/JobDescription.cpp @@ -13,7 +13,6 @@ #include "common/utils/MetaKeyUtils.h" #include "kvstore/KVIterator.h" #include "meta/processors/Common.h" -#include "meta/processors/job/JobUtils.h" namespace nebula { namespace meta { @@ -21,16 +20,15 @@ namespace meta { using Status = cpp2::JobStatus; using JobType = cpp2::JobType; -int32_t JobDescription::minDataVer_ = 1; -int32_t JobDescription::currDataVer_ = 1; - -JobDescription::JobDescription(JobID id, +JobDescription::JobDescription(GraphSpaceID space, + JobID jobId, cpp2::JobType type, std::vector paras, Status status, int64_t startTime, int64_t stopTime) - : id_(id), + : space_(space), + jobId_(jobId), type_(type), paras_(std::move(paras)), status_(status), @@ -40,16 +38,11 @@ JobDescription::JobDescription(JobID id, ErrorOr JobDescription::makeJobDescription( folly::StringPiece rawkey, folly::StringPiece rawval) { try { - if (!isJobKey(rawkey)) { + if (!MetaKeyUtils::isJobKey(rawkey)) { return nebula::cpp2::ErrorCode::E_INVALID_JOB; } - auto key = parseKey(rawkey); - - if (!isSupportedValue(rawval)) { - LOG(INFO) << "not supported data ver of job " << key; - return nebula::cpp2::ErrorCode::E_INVALID_JOB; - } - auto tup = parseVal(rawval); + auto spaceIdAndJob = MetaKeyUtils::parseJobKey(rawkey); + auto tup = MetaKeyUtils::parseJobVal(rawval); auto type = std::get<0>(tup); auto paras = std::get<1>(tup); @@ -59,81 +52,18 @@ ErrorOr JobDescription::makeJobDescript auto status = std::get<2>(tup); auto startTime = std::get<3>(tup); auto stopTime = std::get<4>(tup); - return JobDescription(key, type, paras, status, startTime, stopTime); + return JobDescription( + spaceIdAndJob.first, spaceIdAndJob.second, type, paras, status, startTime, stopTime); } catch (std::exception& ex) { LOG(INFO) << ex.what(); } return nebula::cpp2::ErrorCode::E_INVALID_JOB; } -std::string JobDescription::jobKey() const { - return makeJobKey(id_); -} - -std::string JobDescription::makeJobKey(JobID iJob) { - std::string str; - str.reserve(32); - auto& jPrefix = JobUtil::jobPrefix(); - str.append(jPrefix.data(), jPrefix.size()) - .append(reinterpret_cast(&iJob), sizeof(JobID)); - return str; -} - -int32_t JobDescription::parseKey(const folly::StringPiece& rawKey) { - auto offset = JobUtil::jobPrefix().size(); - return *reinterpret_cast(rawKey.begin() + offset); -} - -std::string JobDescription::jobVal() const { - std::string str; - str.reserve(256); - // use a big num to avoid possible conflict - int32_t dataVersion = INT_MAX - currDataVer_; - str.append(reinterpret_cast(&dataVersion), sizeof(dataVersion)) - .append(reinterpret_cast(&type_), sizeof(type_)); - auto paraSize = paras_.size(); - str.append(reinterpret_cast(¶Size), sizeof(size_t)); - for (auto& para : paras_) { - auto len = para.length(); - str.append(reinterpret_cast(&len), sizeof(len)) - .append(reinterpret_cast(¶[0]), len); - } - str.append(reinterpret_cast(&status_), sizeof(Status)) - .append(reinterpret_cast(&startTime_), sizeof(int64_t)) - .append(reinterpret_cast(&stopTime_), sizeof(int64_t)); - return str; -} - -std::tuple, Status, int64_t, int64_t> JobDescription::parseVal( - const folly::StringPiece& rawVal) { - return decodeValV1(rawVal); -} - -// old saved data may have different format -// which means we have different decoder for each version -std::tuple, Status, int64_t, int64_t> JobDescription::decodeValV1( - const folly::StringPiece& rawVal) { - size_t offset = sizeof(int32_t); - - auto type = JobUtil::parseFixedVal(rawVal, offset); - offset += sizeof(type); - - std::vector paras = JobUtil::parseStrVector(rawVal, &offset); - - auto status = JobUtil::parseFixedVal(rawVal, offset); - offset += sizeof(Status); - - auto tStart = JobUtil::parseFixedVal(rawVal, offset); - offset += sizeof(int64_t); - - auto tStop = JobUtil::parseFixedVal(rawVal, offset); - - return std::make_tuple(type, paras, status, tStart, tStop); -} - cpp2::JobDesc JobDescription::toJobDesc() { cpp2::JobDesc ret; - ret.id_ref() = id_; + ret.space_id_ref() = space_; + ret.job_id_ref() = jobId_; ret.type_ref() = type_; ret.paras_ref() = paras_; ret.status_ref() = status_; @@ -142,15 +72,6 @@ cpp2::JobDesc JobDescription::toJobDesc() { return ret; } -std::string JobDescription::archiveKey() { - std::string str; - str.reserve(32); - auto& aPrefix = JobUtil::archivePrefix(); - str.append(aPrefix.data(), aPrefix.size()) - .append(reinterpret_cast(&id_), sizeof(id_)); - return str; -} - bool JobDescription::setStatus(Status newStatus, bool force) { if (JobStatus::laterThan(status_, newStatus) && !force) { return false; @@ -165,33 +86,20 @@ bool JobDescription::setStatus(Status newStatus, bool force) { return true; } -bool JobDescription::isJobKey(const folly::StringPiece& rawKey) { - if (!rawKey.startsWith(JobUtil::jobPrefix())) { - return false; - } - return rawKey.size() == JobUtil::jobPrefix().length() + sizeof(int32_t); -} - ErrorOr JobDescription::loadJobDescription( - JobID iJob, nebula::kvstore::KVStore* kv) { - auto key = makeJobKey(iJob); + GraphSpaceID space, JobID iJob, nebula::kvstore::KVStore* kv) { + auto key = MetaKeyUtils::jobKey(space, iJob); std::string val; auto retCode = kv->get(kDefaultSpaceId, kDefaultPartId, key, &val); if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { - LOG(INFO) << "Loading Job Description Failed" << apache::thrift::util::enumNameSafe(retCode); + if (retCode == nebula::cpp2::ErrorCode::E_KEY_NOT_FOUND) + retCode = nebula::cpp2::ErrorCode::E_JOB_NOT_IN_SPACE; + LOG(INFO) << "Loading job description failed, error: " + << apache::thrift::util::enumNameSafe(retCode); return retCode; } return makeJobDescription(key, val); } -bool JobDescription::isSupportedValue(const folly::StringPiece& val) { - if (val.size() < sizeof(int32_t)) { - return false; - } - - int32_t ver = INT_MAX - JobUtil::parseFixedVal(val, 0); - return ver >= minDataVer_ && ver <= currDataVer_; -} - } // namespace meta } // namespace nebula diff --git a/src/meta/processors/job/JobDescription.h b/src/meta/processors/job/JobDescription.h index ef6c0448fe1..80bccc76ea4 100644 --- a/src/meta/processors/job/JobDescription.h +++ b/src/meta/processors/job/JobDescription.h @@ -18,29 +18,15 @@ namespace nebula { namespace meta { class JobDescription { - FRIEND_TEST(JobDescriptionTest, ParseKey); - FRIEND_TEST(JobDescriptionTest, ParseVal); - FRIEND_TEST(JobManagerTest, BuildJobDescription); - FRIEND_TEST(JobManagerTest, AddJob); - FRIEND_TEST(JobManagerTest, StatsJob); - FRIEND_TEST(JobManagerTest, LoadJobDescription); - FRIEND_TEST(JobManagerTest, ShowJobs); - FRIEND_TEST(JobManagerTest, ShowJob); - FRIEND_TEST(JobManagerTest, ShowJobsFromMultiSpace); - FRIEND_TEST(JobManagerTest, ShowJobInOtherSpace); - FRIEND_TEST(JobManagerTest, BackupJob); - FRIEND_TEST(JobManagerTest, RecoverJob); - FRIEND_TEST(GetStatsTest, StatsJob); - FRIEND_TEST(GetStatsTest, MockSingleMachineTest); - FRIEND_TEST(GetStatsTest, MockMultiMachineTest); - using Status = cpp2::JobStatus; public: JobDescription() = default; - JobDescription(JobID id, + + JobDescription(GraphSpaceID space, + JobID id, cpp2::JobType type, - std::vector paras, + std::vector paras = {}, Status status = Status::QUEUE, int64_t startTime = 0, int64_t stopTime = 0); @@ -55,8 +41,22 @@ class JobDescription { static ErrorOr makeJobDescription( folly::StringPiece key, folly::StringPiece val); + /** + * @brief Get the SpaceId + * + * @return GraphSpaceID + */ + GraphSpaceID getSpace() const { + return space_; + } + + /** + * @brief Get the Job Id + * + * @return JobID + */ JobID getJobId() const { - return id_; + return jobId_; } /** @@ -86,27 +86,6 @@ class JobDescription { return status_; } - /** - * @brief Return the key write to kv store - * - * @return - */ - std::string jobKey() const; - - /** - * @brief Return the val write to kv store - * - * @return - */ - std::string jobVal() const; - - /** - * @brief Return the key write to kv store, while calling "backup job" - * - * @return - */ - std::string archiveKey(); - /** * @brief * Set the internal status @@ -123,24 +102,34 @@ class JobDescription { bool setStatus(Status newStatus, bool force = false); /** - * @brief - * Get a existed job from kvstore, reture std::nullopt if there isn't + * @brief Get the Start Time * - * @param iJob Id of the job we would load - * @param kv Where we load the job from - * @return + * @return int64_t */ - static ErrorOr loadJobDescription( - JobID iJob, nebula::kvstore::KVStore* kv); + int64_t getStartTime() { + return startTime_; + } + + /** + * @brief Get the Stop Time + * + * @return int64_t + */ + int64_t getStopTime() { + return stopTime_; + } /** * @brief - * Compose a key write to kvstore, according to the given job id + * Get a existed job from kvstore, return folly::none if there isn't * - * @param iJob + * @param space the spaceId of the job we would load + * @param iJob Id of the job we would load + * @param kv Where we load the job from * @return */ - static std::string makeJobKey(JobID iJob); + static ErrorOr loadJobDescription( + GraphSpaceID space, JobID iJob, nebula::kvstore::KVStore* kv); /** * @brief @@ -160,37 +149,9 @@ class JobDescription { */ cpp2::JobDesc toJobDesc(); - /** - * @brief Decode key from kvstore, return job id - * - * @param rawKey - * @return - */ - static int32_t parseKey(const folly::StringPiece& rawKey); - - /** - * @brief - * Decode val from kvstore, return - * {command, paras, status, start time, stop time} - * - * @param rawVal - * @return - */ - static std::tuple, Status, int64_t, int64_t> parseVal( - const folly::StringPiece& rawVal); - - /** - * @brief - * Check if the given rawKey is a valid JobKey - * - * @param rawKey - * @return - */ - static bool isJobKey(const folly::StringPiece& rawKey); - bool operator==(const JobDescription& that) const { - return this->type_ == that.type_ && this->paras_ == that.paras_ && - this->status_ == that.status_; + return space_ == that.space_ && type_ == that.type_ && paras_ == that.paras_ && + status_ == that.status_; } bool operator!=(const JobDescription& that) const { @@ -198,32 +159,14 @@ class JobDescription { } private: - static bool isSupportedValue(const folly::StringPiece& val); - - /** - * @brief - * Decode val if it stored in data ver.1, return - * {command, paras, status, start time, stop time} - * - * @param rawVal - * @return - */ - static std::tuple, Status, int64_t, int64_t> decodeValV1( - const folly::StringPiece& rawVal); - - private: - JobID id_; + // Because all jobs are space-level, spaceName is not in paras_. + GraphSpaceID space_; + JobID jobId_; cpp2::JobType type_; std::vector paras_; Status status_; int64_t startTime_; int64_t stopTime_; - - // old job may have different format, - // will ignore some job if it is too old - // use a hard coded int mark data ver - static int32_t minDataVer_; - static int32_t currDataVer_; }; } // namespace meta diff --git a/src/meta/processors/job/JobExecutor.cpp b/src/meta/processors/job/JobExecutor.cpp index 1dcde13e974..41c5cfca5c4 100644 --- a/src/meta/processors/job/JobExecutor.cpp +++ b/src/meta/processors/job/JobExecutor.cpp @@ -30,17 +30,14 @@ DECLARE_uint32(expired_time_factor); namespace nebula { namespace meta { -ErrorOr JobExecutor::getSpaceIdFromName( - const std::string& spaceName) { - auto indexKey = MetaKeyUtils::indexSpaceKey(spaceName); +nebula::cpp2::ErrorCode JobExecutor::spaceExist() { + auto spaceKey = MetaKeyUtils::spaceKey(space_); std::string val; - auto retCode = kvstore_->get(kDefaultSpaceId, kDefaultPartId, indexKey, &val); - if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { - LOG(INFO) << "Get space failed, space name: " << spaceName - << " error: " << apache::thrift::util::enumNameSafe(retCode); - return retCode; + auto retCode = kvstore_->get(kDefaultSpaceId, kDefaultPartId, spaceKey, &val); + if (retCode == nebula::cpp2::ErrorCode::E_KEY_NOT_FOUND) { + retCode = nebula::cpp2::ErrorCode::E_SPACE_NOT_FOUND; } - return *reinterpret_cast(val.c_str()); + return retCode; } std::unique_ptr JobExecutorFactory::createJobExecutor(const JobDescription& jd, @@ -49,7 +46,7 @@ std::unique_ptr JobExecutorFactory::createJobExecutor(const JobDesc std::unique_ptr ret; switch (jd.getJobType()) { case cpp2::JobType::COMPACT: - ret.reset(new CompactJobExecutor(jd.getJobId(), store, client, jd.getParas())); + ret.reset(new CompactJobExecutor(jd.getSpace(), jd.getJobId(), store, client, jd.getParas())); break; case cpp2::JobType::DATA_BALANCE: ret.reset(new DataBalanceJobExecutor(jd, store, client, jd.getParas())); @@ -58,22 +55,26 @@ std::unique_ptr JobExecutorFactory::createJobExecutor(const JobDesc ret.reset(new ZoneBalanceJobExecutor(jd, store, client, jd.getParas())); break; case cpp2::JobType::LEADER_BALANCE: - ret.reset(new LeaderBalanceJobExecutor(jd.getJobId(), store, client, jd.getParas())); + ret.reset( + new LeaderBalanceJobExecutor(jd.getSpace(), jd.getJobId(), store, client, jd.getParas())); break; case cpp2::JobType::FLUSH: - ret.reset(new FlushJobExecutor(jd.getJobId(), store, client, jd.getParas())); + ret.reset(new FlushJobExecutor(jd.getSpace(), jd.getJobId(), store, client, jd.getParas())); break; case cpp2::JobType::REBUILD_TAG_INDEX: - ret.reset(new RebuildTagJobExecutor(jd.getJobId(), store, client, jd.getParas())); + ret.reset( + new RebuildTagJobExecutor(jd.getSpace(), jd.getJobId(), store, client, jd.getParas())); break; case cpp2::JobType::REBUILD_EDGE_INDEX: - ret.reset(new RebuildEdgeJobExecutor(jd.getJobId(), store, client, jd.getParas())); + ret.reset( + new RebuildEdgeJobExecutor(jd.getSpace(), jd.getJobId(), store, client, jd.getParas())); break; case cpp2::JobType::REBUILD_FULLTEXT_INDEX: - ret.reset(new RebuildFTJobExecutor(jd.getJobId(), store, client, jd.getParas())); + ret.reset( + new RebuildFTJobExecutor(jd.getSpace(), jd.getJobId(), store, client, jd.getParas())); break; case cpp2::JobType::STATS: - ret.reset(new StatsJobExecutor(jd.getJobId(), store, client, jd.getParas())); + ret.reset(new StatsJobExecutor(jd.getSpace(), jd.getJobId(), store, client, jd.getParas())); break; default: break; diff --git a/src/meta/processors/job/JobExecutor.h b/src/meta/processors/job/JobExecutor.h index a5819a57e7f..3c5868a28ed 100644 --- a/src/meta/processors/job/JobExecutor.h +++ b/src/meta/processors/job/JobExecutor.h @@ -19,7 +19,7 @@ namespace meta { class JobExecutor { public: JobExecutor() = default; - explicit JobExecutor(kvstore::KVStore* kv) : kvstore_(kv) {} + explicit JobExecutor(kvstore::KVStore* kv, GraphSpaceID space) : kvstore_(kv), space_(space) {} virtual ~JobExecutor() = default; /** @@ -66,13 +66,6 @@ class JobExecutor { */ virtual nebula::cpp2::ErrorCode recovery() = 0; - /** - * @brief Set id of the space - * - * @param spaceId - */ - virtual void setSpaceId(GraphSpaceID spaceId) = 0; - virtual bool isMetaJob() = 0; /** @@ -93,10 +86,12 @@ class JobExecutor { virtual nebula::cpp2::ErrorCode saveSpecialTaskStatus(const cpp2::ReportTaskReq&) = 0; protected: - ErrorOr getSpaceIdFromName(const std::string& spaceName); + nebula::cpp2::ErrorCode spaceExist(); protected: kvstore::KVStore* kvstore_{nullptr}; + + GraphSpaceID space_; }; class JobExecutorFactory { diff --git a/src/meta/processors/job/JobManager.cpp b/src/meta/processors/job/JobManager.cpp index 81b79d030e4..3515e6db5ad 100644 --- a/src/meta/processors/job/JobManager.cpp +++ b/src/meta/processors/job/JobManager.cpp @@ -22,7 +22,6 @@ #include "meta/processors/admin/AdminClient.h" #include "meta/processors/job/BalancePlan.h" #include "meta/processors/job/JobStatus.h" -#include "meta/processors/job/JobUtils.h" #include "meta/processors/job/TaskDescription.h" #include "webservice/Common.h" @@ -49,9 +48,6 @@ bool JobManager::init(nebula::kvstore::KVStore* store) { } kvStore_ = store; - lowPriorityQueue_ = std::make_unique, true>>(); - highPriorityQueue_ = std::make_unique, true>>(); - status_.store(JbmgrStatus::IDLE, std::memory_order_release); if (handleRemainingJobs() != nebula::cpp2::ErrorCode::SUCCEEDED) { return false; @@ -67,7 +63,8 @@ JobManager::~JobManager() { nebula::cpp2::ErrorCode JobManager::handleRemainingJobs() { std::unique_ptr iter; - auto retCode = kvStore_->prefix(kDefaultSpaceId, kDefaultPartId, JobUtil::jobPrefix(), &iter); + auto retCode = + kvStore_->prefix(kDefaultSpaceId, kDefaultPartId, MetaKeyUtils::jobPrefix(), &iter); if (retCode == nebula::cpp2::ErrorCode::E_LEADER_CHANGED) { LOG(INFO) << "Not leader, skip reading remaining jobs"; return nebula::cpp2::ErrorCode::SUCCEEDED; @@ -78,7 +75,7 @@ nebula::cpp2::ErrorCode JobManager::handleRemainingJobs() { } std::vector jds; for (; iter->valid(); iter->next()) { - if (!JobDescription::isJobKey(iter->key())) { + if (!MetaKeyUtils::isJobKey(iter->key())) { continue; } auto optJobRet = JobDescription::makeJobDescription(iter->key(), iter->val()); @@ -94,15 +91,18 @@ nebula::cpp2::ErrorCode JobManager::handleRemainingJobs() { } for (auto& jd : jds) { jd.setStatus(cpp2::JobStatus::QUEUE, true); - save(jd.jobKey(), jd.jobVal()); + auto jobKey = MetaKeyUtils::jobKey(jd.getSpace(), jd.getJobId()); + auto jobVal = MetaKeyUtils::jobVal( + jd.getJobType(), jd.getParas(), jd.getStatus(), jd.getStartTime(), jd.getStopTime()); + save(jobKey, jobVal); } return nebula::cpp2::ErrorCode::SUCCEEDED; } void JobManager::shutDown() { LOG(INFO) << "JobManager::shutDown() begin"; - if (status_.load(std::memory_order_acquire) == - JbmgrStatus::STOPPED) { // in case of shutdown more than once + // In case of shutdown more than once + if (status_.load(std::memory_order_acquire) == JbmgrStatus::STOPPED) { LOG(INFO) << "JobManager not running, exit"; return; } @@ -112,10 +112,10 @@ void JobManager::shutDown() { } void JobManager::scheduleThread() { - LOG(INFO) << "JobManager::runJobBackground() enter"; + LOG(INFO) << "JobManager::scheduleThread enter"; while (status_.load(std::memory_order_acquire) != JbmgrStatus::STOPPED) { - std::pair opJobId; - while (status_.load(std::memory_order_acquire) == JbmgrStatus::BUSY || !try_dequeue(opJobId)) { + std::tuple opJobId; + while (!tryDequeue(opJobId)) { if (status_.load(std::memory_order_acquire) == JbmgrStatus::STOPPED) { LOG(INFO) << "[JobManager] detect shutdown called, exit"; break; @@ -123,29 +123,41 @@ void JobManager::scheduleThread() { usleep(FLAGS_job_check_intervals); } - auto jobDescRet = JobDescription::loadJobDescription(opJobId.second, kvStore_); + auto jobOp = std::get<0>(opJobId); + auto jodId = std::get<1>(opJobId); + auto spaceId = std::get<2>(opJobId); + auto jobDescRet = JobDescription::loadJobDescription(spaceId, jodId, kvStore_); if (!nebula::ok(jobDescRet)) { - LOG(INFO) << "[JobManager] load an invalid job from queue " << opJobId.second; + LOG(INFO) << "[JobManager] load an invalid job from space " << spaceId << " jodId " << jodId; continue; // leader change or archive happened } auto jobDesc = nebula::value(jobDescRet); - if (!jobDesc.setStatus(cpp2::JobStatus::RUNNING, opJobId.first == JbOp::RECOVER)) { - LOG(INFO) << "[JobManager] skip job " << opJobId.second; + if (!jobDesc.setStatus(cpp2::JobStatus::RUNNING, jobOp == JbOp::RECOVER)) { + LOG(INFO) << "[JobManager] skip job space " << spaceId << " jodId " << jodId; continue; } - save(jobDesc.jobKey(), jobDesc.jobVal()); - compareChangeStatus(JbmgrStatus::IDLE, JbmgrStatus::BUSY); - if (!runJobInternal(jobDesc, opJobId.first)) { - jobFinished(opJobId.second, cpp2::JobStatus::FAILED); + + auto jobKey = MetaKeyUtils::jobKey(jobDesc.getSpace(), jobDesc.getJobId()); + auto jobVal = MetaKeyUtils::jobVal(jobDesc.getJobType(), + jobDesc.getParas(), + jobDesc.getStatus(), + jobDesc.getStartTime(), + jobDesc.getStopTime()); + save(jobKey, jobVal); + spaceRunningJobs_.insert_or_assign(spaceId, true); + if (!runJobInternal(jobDesc, jobOp)) { + jobFinished(spaceId, jodId, cpp2::JobStatus::FAILED); } } } bool JobManager::runJobInternal(const JobDescription& jobDesc, JbOp op) { - std::lock_guard lk(muJobFinished_); + auto spaceId = jobDesc.getSpace(); + std::lock_guard lk(muJobFinished_[spaceId]); std::unique_ptr je = JobExecutorFactory::createJobExecutor(jobDesc, kvStore_, adminClient_); JobExecutor* jobExec = je.get(); + runningJobs_.emplace(jobDesc.getJobId(), std::move(je)); if (jobExec == nullptr) { LOG(INFO) << "unreconized job type " @@ -173,11 +185,12 @@ bool JobManager::runJobInternal(const JobDescription& jobDesc, JbOp op) { if (jobExec->isMetaJob()) { jobExec->setFinishCallBack([this, jobDesc](meta::cpp2::JobStatus status) { if (status == meta::cpp2::JobStatus::STOPPED) { - std::lock_guard lkg(muJobFinished_); + auto space = jobDesc.getSpace(); + std::lock_guard lkg(muJobFinished_[space]); cleanJob(jobDesc.getJobId()); return nebula::cpp2::ErrorCode::SUCCEEDED; } else { - return jobFinished(jobDesc.getJobId(), status); + return jobFinished(jobDesc.getSpace(), jobDesc.getJobId(), status); } }); } @@ -190,7 +203,7 @@ bool JobManager::runJobInternal(const JobDescription& jobDesc, JbOp op) { void JobManager::cleanJob(JobID jobId) { // Delete the job after job finished or failed - LOG(INFO) << "[task] cleanJob " << jobId; + LOG(INFO) << "cleanJob " << jobId; auto it = inFlightJobs_.find(jobId); if (it != inFlightJobs_.end()) { inFlightJobs_.erase(it); @@ -201,19 +214,24 @@ void JobManager::cleanJob(JobID jobId) { } } -nebula::cpp2::ErrorCode JobManager::jobFinished(JobID jobId, cpp2::JobStatus jobStatus) { - LOG(INFO) << folly::sformat( - "{}, jobId={}, result={}", __func__, jobId, apache::thrift::util::enumNameSafe(jobStatus)); +nebula::cpp2::ErrorCode JobManager::jobFinished(GraphSpaceID spaceId, + JobID jobId, + cpp2::JobStatus jobStatus) { + LOG(INFO) << folly::sformat("{}, spaceId={}, jobId={}, result={}", + __func__, + spaceId, + jobId, + apache::thrift::util::enumNameSafe(jobStatus)); // normal job finish may race to job stop - std::lock_guard lk(muJobFinished_); - auto optJobDescRet = JobDescription::loadJobDescription(jobId, kvStore_); + std::lock_guard lk(muJobFinished_[spaceId]); + auto optJobDescRet = JobDescription::loadJobDescription(spaceId, jobId, kvStore_); if (!nebula::ok(optJobDescRet)) { - LOG(INFO) << folly::sformat("can't load job, jobId={}", jobId); + LOG(INFO) << folly::sformat("Load job failed, spaceId={} jobId={}", spaceId, jobId); if (jobStatus != cpp2::JobStatus::STOPPED) { // there is a rare condition, that when job finished, // the job description is deleted(default more than a week) // but stop an invalid job should not set status to idle. - compareChangeStatus(JbmgrStatus::BUSY, JbmgrStatus::IDLE); + spaceRunningJobs_.insert_or_assign(spaceId, false); } return nebula::error(optJobDescRet); } @@ -224,34 +242,25 @@ nebula::cpp2::ErrorCode JobManager::jobFinished(JobID jobId, cpp2::JobStatus job // job already been set as finished, failed or stopped return nebula::cpp2::ErrorCode::E_SAVE_JOB_FAILURE; } - compareChangeStatus(JbmgrStatus::BUSY, JbmgrStatus::IDLE); - auto rc = save(optJobDesc.jobKey(), optJobDesc.jobVal()); + + spaceRunningJobs_.insert_or_assign(spaceId, false); + auto jobKey = MetaKeyUtils::jobKey(optJobDesc.getSpace(), optJobDesc.getJobId()); + auto jobVal = MetaKeyUtils::jobVal(optJobDesc.getJobType(), + optJobDesc.getParas(), + optJobDesc.getStatus(), + optJobDesc.getStartTime(), + optJobDesc.getStopTime()); + auto rc = save(jobKey, jobVal); if (rc != nebula::cpp2::ErrorCode::SUCCEEDED) { return rc; } auto it = runningJobs_.find(jobId); if (it == runningJobs_.end()) { - LOG(INFO) << folly::sformat("can't find jobExecutor, jobId={}", jobId); + LOG(INFO) << folly::sformat("Can't find jobExecutor, jobId={}", jobId); return nebula::cpp2::ErrorCode::E_UNKNOWN; } std::unique_ptr& jobExec = it->second; - if (!optJobDesc.getParas().empty()) { - auto spaceName = optJobDesc.getParas().back(); - auto spaceIdRet = getSpaceId(spaceName); - if (!nebula::ok(spaceIdRet)) { - auto retCode = nebula::error(spaceIdRet); - LOG(INFO) << "Get spaceName " << spaceName - << " failed, error: " << apache::thrift::util::enumNameSafe(retCode); - return retCode; - } - - auto spaceId = nebula::value(spaceIdRet); - if (spaceId == -1) { - return nebula::cpp2::ErrorCode::E_STORE_FAILURE; - } - jobExec->setSpaceId(spaceId); - } if (jobStatus == cpp2::JobStatus::STOPPED) { jobExec->stop(); if (!jobExec->isMetaJob()) { @@ -272,8 +281,9 @@ nebula::cpp2::ErrorCode JobManager::saveTaskStatus(TaskDescription& td, : cpp2::JobStatus::FAILED; td.setStatus(status); + auto spaceId = req.get_space_id(); auto jobId = req.get_job_id(); - auto optJobDescRet = JobDescription::loadJobDescription(jobId, kvStore_); + auto optJobDescRet = JobDescription::loadJobDescription(spaceId, jobId, kvStore_); if (!nebula::ok(optJobDescRet)) { auto retCode = nebula::error(optJobDescRet); LOG(INFO) << "LoadJobDesc failed, jobId " << jobId @@ -289,25 +299,14 @@ nebula::cpp2::ErrorCode JobManager::saveTaskStatus(TaskDescription& td, return nebula::cpp2::ErrorCode::E_TASK_REPORT_OUT_DATE; } - auto rcSave = save(td.taskKey(), td.taskVal()); + auto taskKey = MetaKeyUtils::taskKey(td.getSpace(), td.getJobId(), td.getTaskId()); + auto taskVal = + MetaKeyUtils::taskVal(td.getHost(), td.getStatus(), td.getStartTime(), td.getStopTime()); + auto rcSave = save(taskKey, taskVal); if (rcSave != nebula::cpp2::ErrorCode::SUCCEEDED) { return rcSave; } - if (!optJobDesc.getParas().empty()) { - GraphSpaceID spaceId = -1; - auto spaceName = optJobDesc.getParas().back(); - auto spaceIdRet = getSpaceId(spaceName); - if (!nebula::ok(spaceIdRet)) { - auto retCode = nebula::error(spaceIdRet); - LOG(INFO) << "Get spaceName " << spaceName - << " failed, error: " << apache::thrift::util::enumNameSafe(retCode); - } else { - spaceId = nebula::value(spaceIdRet); - jobExec->setSpaceId(spaceId); - } - } - return jobExec->saveSpecialTaskStatus(req); } @@ -316,27 +315,21 @@ void JobManager::compareChangeStatus(JbmgrStatus expected, JbmgrStatus desired) status_.compare_exchange_strong(ex, desired, std::memory_order_acq_rel); } -/** - * @brief - * client should retry if any persist attempt - * for example leader change / store failure. - * else, may log then ignore error - * @return cpp2::ErrorCode - */ nebula::cpp2::ErrorCode JobManager::reportTaskFinish(const cpp2::ReportTaskReq& req) { + auto spaceId = req.get_space_id(); auto jobId = req.get_job_id(); auto taskId = req.get_task_id(); // only an active job manager will accept task finish report if (status_.load(std::memory_order_acquire) == JbmgrStatus::STOPPED || status_.load(std::memory_order_acquire) == JbmgrStatus::NOT_START) { LOG(INFO) << folly::sformat( - "report to an in-active job manager, job={}, task={}", jobId, taskId); + "report to an in-active job manager, spaceId={}, job={}, task={}", spaceId, jobId, taskId); return nebula::cpp2::ErrorCode::E_UNKNOWN; } // because the last task will update the job's status // tasks should report once a time - std::lock_guard lk(muReportFinish_); - auto tasksRet = getAllTasks(jobId); + std::lock_guard lk(muReportFinish_[spaceId]); + auto tasksRet = getAllTasks(spaceId, jobId); if (!nebula::ok(tasksRet)) { return nebula::error(tasksRet); } @@ -368,21 +361,22 @@ nebula::cpp2::ErrorCode JobManager::reportTaskFinish(const cpp2::ReportTaskReq& [](auto& tsk) { return tsk.status_ == cpp2::JobStatus::FINISHED; }) ? cpp2::JobStatus::FINISHED : cpp2::JobStatus::FAILED; - return jobFinished(jobId, jobStatus); + return jobFinished(spaceId, jobId, jobStatus); } return nebula::cpp2::ErrorCode::SUCCEEDED; } -ErrorOr> JobManager::getAllTasks(JobID jobId) { +ErrorOr> JobManager::getAllTasks( + GraphSpaceID spaceId, JobID jobId) { std::list taskDescriptions; - auto jobKey = JobDescription::makeJobKey(jobId); + auto jobKey = MetaKeyUtils::jobKey(spaceId, jobId); std::unique_ptr iter; auto rc = kvStore_->prefix(kDefaultSpaceId, kDefaultPartId, jobKey, &iter); if (rc != nebula::cpp2::ErrorCode::SUCCEEDED) { return rc; } for (; iter->valid(); iter->next()) { - if (JobDescription::isJobKey(iter->key())) { + if (MetaKeyUtils::isJobKey(iter->key())) { continue; } taskDescriptions.emplace_back(TaskDescription(iter->key(), iter->val())); @@ -390,12 +384,18 @@ ErrorOr> JobManager::getAllT return taskDescriptions; } -nebula::cpp2::ErrorCode JobManager::addJob(const JobDescription& jobDesc, AdminClient* client) { - auto rc = save(jobDesc.jobKey(), jobDesc.jobVal()); +nebula::cpp2::ErrorCode JobManager::addJob(JobDescription& jobDesc, AdminClient* client) { + auto spaceId = jobDesc.getSpace(); + auto jobId = jobDesc.getJobId(); + auto jobKey = MetaKeyUtils::jobKey(spaceId, jobId); + auto jobVal = MetaKeyUtils::jobVal(jobDesc.getJobType(), + jobDesc.getParas(), + jobDesc.getStatus(), + jobDesc.getStartTime(), + jobDesc.getStopTime()); + auto rc = save(jobKey, jobVal); if (rc == nebula::cpp2::ErrorCode::SUCCEEDED) { - auto jobId = jobDesc.getJobId(); - enqueue(JbOp::ADD, jobId, jobDesc.getJobType()); - // Add job to jobMap + enqueue(spaceId, jobId, JbOp::ADD, jobDesc.getJobType()); inFlightJobs_.emplace(jobId, jobDesc); } else { LOG(INFO) << "Add Job Failed"; @@ -409,32 +409,63 @@ nebula::cpp2::ErrorCode JobManager::addJob(const JobDescription& jobDesc, AdminC } size_t JobManager::jobSize() const { - return highPriorityQueue_->size() + lowPriorityQueue_->size(); + size_t size = 0; + for (auto iter = priorityQueues_.begin(); iter != priorityQueues_.end(); ++iter) { + size += iter->second->size(); + } + return size; } -bool JobManager::try_dequeue(std::pair& opJobId) { - if (highPriorityQueue_->try_dequeue(opJobId)) { - return true; - } else if (lowPriorityQueue_->try_dequeue(opJobId)) { - return true; +// Execute jobs concurrently between spaces +// Execute jobs according to priority within the space +bool JobManager::tryDequeue(std::tuple& opJobId) { + for (auto queueIter = priorityQueues_.begin(); queueIter != priorityQueues_.end(); ++queueIter) { + auto spaceId = queueIter->first; + auto runningJobIter = spaceRunningJobs_.find(spaceId); + if (runningJobIter != spaceRunningJobs_.end() && runningJobIter->second) { + continue; + } + if (queueIter->second == nullptr) { + spaceRunningJobs_.insert_or_assign(spaceId, false); + continue; + } + auto ret = queueIter->second->try_dequeue(opJobId); + if (ret) { + return true; + } } return false; } -void JobManager::enqueue(const JbOp& op, const JobID& jobId, const cpp2::JobType& jobType) { - if (jobType == cpp2::JobType::STATS) { - highPriorityQueue_->enqueue(std::make_pair(op, jobId)); +void JobManager::enqueue(GraphSpaceID space, + JobID jobId, + const JbOp& op, + const cpp2::JobType& jobType) { + static const size_t priorityCount = 2; + auto iter = priorityQueues_.find(space); + if (iter == priorityQueues_.end()) { + std::unique_ptr priQueue = std::make_unique(priorityCount); + priorityQueues_.emplace(space, std::move(priQueue)); + } + iter = priorityQueues_.find(space); + CHECK(iter != priorityQueues_.end()); + if (jobType == cpp2::JobType::LEADER_BALANCE) { + iter->second->at_priority(static_cast(JbPriority::kHIGH)) + .enqueue(std::make_tuple(op, jobId, space)); + } else { - lowPriorityQueue_->enqueue(std::make_pair(op, jobId)); + iter->second->at_priority(static_cast(JbPriority::kLOW)) + .enqueue(std::make_tuple(op, jobId, space)); } } ErrorOr> JobManager::showJobs( - const std::string& spaceName) { + GraphSpaceID spaceId) { std::unique_ptr iter; - auto retCode = kvStore_->prefix(kDefaultSpaceId, kDefaultPartId, JobUtil::jobPrefix(), &iter); + auto jobPre = MetaKeyUtils::jobPrefix(spaceId); + auto retCode = kvStore_->prefix(kDefaultSpaceId, kDefaultPartId, jobPre, &iter); if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { - LOG(INFO) << "Fetch Jobs Failed, error: " << apache::thrift::util::enumNameSafe(retCode); + LOG(INFO) << "Fetch jobs failed, error: " << apache::thrift::util::enumNameSafe(retCode); return retCode; } @@ -444,7 +475,7 @@ ErrorOr> JobManager::showJob for (; iter->valid(); iter->next()) { auto jobKey = iter->key(); - if (JobDescription::isJobKey(jobKey)) { + if (MetaKeyUtils::isJobKey(jobKey)) { auto optJobRet = JobDescription::makeJobDescription(jobKey, iter->val()); if (!nebula::ok(optJobRet)) { expiredJobKeys.emplace_back(jobKey); @@ -452,16 +483,13 @@ ErrorOr> JobManager::showJob } auto optJob = nebula::value(optJobRet); // skip expired job, default 1 week - auto jobDesc = optJob.toJobDesc(); - if (isExpiredJob(jobDesc)) { - lastExpiredJobId = jobDesc.get_id(); + if (isExpiredJob(optJob)) { + lastExpiredJobId = optJob.getJobId(); LOG(INFO) << "remove expired job " << lastExpiredJobId; expiredJobKeys.emplace_back(jobKey); continue; } - if (jobDesc.get_paras().back() != spaceName) { - continue; - } + auto jobDesc = optJob.toJobDesc(); ret.emplace_back(jobDesc); } else { // iter-key() is a TaskKey TaskDescription task(jobKey, iter->val()); @@ -477,26 +505,22 @@ ErrorOr> JobManager::showJob return retCode; } - std::sort( - ret.begin(), ret.end(), [](const auto& a, const auto& b) { return a.get_id() > b.get_id(); }); + std::sort(ret.begin(), ret.end(), [](const auto& a, const auto& b) { + return a.get_job_id() > b.get_job_id(); + }); return ret; } -bool JobManager::isExpiredJob(const cpp2::JobDesc& jobDesc) { - if (*jobDesc.status_ref() == cpp2::JobStatus::QUEUE || - *jobDesc.status_ref() == cpp2::JobStatus::RUNNING) { +bool JobManager::isExpiredJob(JobDescription& jobDesc) { + auto status = jobDesc.getStatus(); + if (status == cpp2::JobStatus::QUEUE || status == cpp2::JobStatus::RUNNING) { return false; } - auto jobStart = jobDesc.get_start_time(); + auto jobStart = jobDesc.getStartTime(); auto duration = std::difftime(nebula::time::WallClock::fastNowInSec(), jobStart); return duration > FLAGS_job_expired_secs; } -bool JobManager::isRunningJob(const JobDescription& jobDesc) { - auto status = jobDesc.getStatus(); - return status == cpp2::JobStatus::QUEUE || status == cpp2::JobStatus::RUNNING; -} - nebula::cpp2::ErrorCode JobManager::removeExpiredJobs( std::vector&& expiredJobsAndTasks) { nebula::cpp2::ErrorCode ret; @@ -516,14 +540,15 @@ nebula::cpp2::ErrorCode JobManager::removeExpiredJobs( return ret; } -bool JobManager::checkJobExist(const cpp2::JobType& jobType, +bool JobManager::checkJobExist(GraphSpaceID spaceId, + const cpp2::JobType& jobType, const std::vector& paras, - JobID& iJob) { - JobDescription jobDesc(0, jobType, paras); + JobID& jobId) { + JobDescription jobDesc(spaceId, 0, jobType, paras); auto it = inFlightJobs_.begin(); while (it != inFlightJobs_.end()) { if (it->second == jobDesc) { - iJob = it->first; + jobId = it->first; return true; } ++it; @@ -532,8 +557,8 @@ bool JobManager::checkJobExist(const cpp2::JobType& jobType, } ErrorOr>> -JobManager::showJob(JobID iJob, const std::string& spaceName) { - auto jobKey = JobDescription::makeJobKey(iJob); +JobManager::showJob(GraphSpaceID spaceId, JobID jobId) { + auto jobKey = MetaKeyUtils::jobKey(spaceId, jobId); std::unique_ptr iter; auto rc = kvStore_->prefix(kDefaultSpaceId, kDefaultPartId, jobKey, &iter); if (rc != nebula::cpp2::ErrorCode::SUCCEEDED) { @@ -541,22 +566,18 @@ JobManager::showJob(JobID iJob, const std::string& spaceName) { } if (!iter->valid()) { - return nebula::cpp2::ErrorCode::E_KEY_NOT_FOUND; + return nebula::cpp2::ErrorCode::E_JOB_NOT_IN_SPACE; } std::pair> ret; for (; iter->valid(); iter->next()) { auto jKey = iter->key(); - if (JobDescription::isJobKey(jKey)) { + if (MetaKeyUtils::isJobKey(jKey)) { auto optJobRet = JobDescription::makeJobDescription(jKey, iter->val()); if (!nebula::ok(optJobRet)) { return nebula::error(optJobRet); } auto optJob = nebula::value(optJobRet); - if (optJob.getParas().back() != spaceName) { - LOG(INFO) << "Show job " << iJob << " not in current space " << spaceName; - return nebula::cpp2::ErrorCode::E_JOB_NOT_IN_SPACE; - } ret.first = optJob.toJobDesc(); } else { TaskDescription td(jKey, iter->val()); @@ -565,7 +586,7 @@ JobManager::showJob(JobID iJob, const std::string& spaceName) { } if (ret.first.get_type() == meta::cpp2::JobType::DATA_BALANCE || ret.first.get_type() == meta::cpp2::JobType::ZONE_BALANCE) { - auto res = BalancePlan::show(iJob, kvStore_, adminClient_); + auto res = BalancePlan::show(jobId, kvStore_, adminClient_); if (ok(res)) { std::vector thriftTasks = value(res); auto& vec = ret.first.paras_ref<>().value(); @@ -582,78 +603,60 @@ JobManager::showJob(JobID iJob, const std::string& spaceName) { return ret; } -nebula::cpp2::ErrorCode JobManager::stopJob(JobID iJob, const std::string& spaceName) { - LOG(INFO) << "try to stop job " << iJob; - auto optJobDescRet = JobDescription::loadJobDescription(iJob, kvStore_); - if (!nebula::ok(optJobDescRet)) { - auto retCode = nebula::error(optJobDescRet); - LOG(INFO) << "LoadJobDesc failed, jobId " << iJob - << " error: " << apache::thrift::util::enumNameSafe(retCode); - return retCode; - } - auto optJobDesc = nebula::value(optJobDescRet); - if (optJobDesc.getParas().back() != spaceName) { - LOG(INFO) << "Stop job " << iJob << " not in space " << spaceName; - return nebula::cpp2::ErrorCode::E_JOB_NOT_IN_SPACE; - } - return jobFinished(iJob, cpp2::JobStatus::STOPPED); +nebula::cpp2::ErrorCode JobManager::stopJob(GraphSpaceID spaceId, JobID jobId) { + LOG(INFO) << folly::sformat("Try to stop job {} in space {}", jobId, spaceId); + return jobFinished(spaceId, jobId, cpp2::JobStatus::STOPPED); } -/* - * Return: recovered job num. - * */ ErrorOr JobManager::recoverJob( - const std::string& spaceName, AdminClient* client, const std::vector& jobIds) { + GraphSpaceID spaceId, AdminClient* client, const std::vector& jobIds) { int32_t recoveredJobNum = 0; - std::vector> kvs; + std::vector> jobKVs; adminClient_ = client; if (jobIds.empty()) { std::unique_ptr iter; - auto retCode = kvStore_->prefix(kDefaultSpaceId, kDefaultPartId, JobUtil::jobPrefix(), &iter); + auto jobPre = MetaKeyUtils::jobPrefix(spaceId); + auto retCode = kvStore_->prefix(kDefaultSpaceId, kDefaultPartId, jobPre, &iter); if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { LOG(INFO) << "Can't find jobs, error: " << apache::thrift::util::enumNameSafe(retCode); return retCode; } for (; iter->valid(); iter->next()) { - if (!JobDescription::isJobKey(iter->key())) { + if (!MetaKeyUtils::isJobKey(iter->key())) { continue; } - kvs.emplace_back(std::make_pair(iter->key(), iter->val())); + jobKVs.emplace_back(std::make_pair(iter->key(), iter->val())); } } else { - std::vector keys; - keys.reserve(jobIds.size()); + std::vector jobKeys; + jobKeys.reserve(jobIds.size()); for (int jobId : jobIds) { - keys.emplace_back(JobDescription::makeJobKey(jobId)); + jobKeys.emplace_back(MetaKeyUtils::jobKey(spaceId, jobId)); } - std::vector values; - auto retCode = kvStore_->multiGet(kDefaultSpaceId, kDefaultPartId, keys, &values); + std::vector jobVals; + auto retCode = kvStore_->multiGet(kDefaultSpaceId, kDefaultPartId, jobKeys, &jobVals); if (retCode.first != nebula::cpp2::ErrorCode::SUCCEEDED) { LOG(INFO) << "Can't find jobs, error: " << apache::thrift::util::enumNameSafe(retCode.first); return retCode.first; } - for (size_t i = 0; i < keys.size(); i++) { - kvs.emplace_back(std::make_pair(keys[i], values[i])); + for (size_t i = 0; i < jobKeys.size(); i++) { + jobKVs.emplace_back(std::make_pair(jobKeys[i], jobVals[i])); } } - for (const std::pair& p : kvs) { - auto optJobRet = JobDescription::makeJobDescription(p.first, p.second); + for (auto& jobkv : jobKVs) { + auto optJobRet = JobDescription::makeJobDescription(jobkv.first, jobkv.second); if (nebula::ok(optJobRet)) { auto optJob = nebula::value(optJobRet); - if (optJob.getParas().back() != spaceName) { - continue; - } if (optJob.getStatus() == cpp2::JobStatus::QUEUE || (jobIds.size() && (optJob.getStatus() == cpp2::JobStatus::FAILED || optJob.getStatus() == cpp2::JobStatus::STOPPED))) { // Check if the job exists JobID jId = 0; - auto jobExist = checkJobExist(optJob.getJobType(), optJob.getParas(), jId); - + auto jobExist = checkJobExist(spaceId, optJob.getJobType(), optJob.getParas(), jId); if (!jobExist) { auto jobId = optJob.getJobId(); - enqueue(JbOp::RECOVER, jobId, optJob.getJobType()); + enqueue(spaceId, jobId, JbOp::RECOVER, optJob.getJobType()); inFlightJobs_.emplace(jobId, optJob); ++recoveredJobNum; } @@ -690,9 +693,11 @@ ErrorOr JobManager::getSpaceId(const std: return *reinterpret_cast(val.c_str()); } -ErrorOr JobManager::checkIndexJobRunning() { +ErrorOr JobManager::checkTypeJobRunning( + std::unordered_set& jobTypes) { std::unique_ptr iter; - auto retCode = kvStore_->prefix(kDefaultSpaceId, kDefaultPartId, JobUtil::jobPrefix(), &iter); + auto jobPrefix = MetaKeyUtils::jobPrefix(); + auto retCode = kvStore_->prefix(kDefaultSpaceId, kDefaultPartId, jobPrefix, &iter); if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { LOG(INFO) << "Fetch Jobs Failed, error: " << apache::thrift::util::enumNameSafe(retCode); return retCode; @@ -700,18 +705,19 @@ ErrorOr JobManager::checkIndexJobRunning() { for (; iter->valid(); iter->next()) { auto jobKey = iter->key(); - if (JobDescription::isJobKey(jobKey)) { + if (MetaKeyUtils::isJobKey(jobKey)) { auto optJobRet = JobDescription::makeJobDescription(jobKey, iter->val()); if (!nebula::ok(optJobRet)) { continue; } auto jobDesc = nebula::value(optJobRet); - if (!isRunningJob(jobDesc)) { + auto jType = jobDesc.getJobType(); + if (jobTypes.find(jType) == jobTypes.end()) { continue; } - auto jobType = jobDesc.getJobType(); - if (jobType == cpp2::JobType::REBUILD_TAG_INDEX || - jobType == cpp2::JobType::REBUILD_EDGE_INDEX) { + + auto status = jobDesc.getStatus(); + if (status == cpp2::JobStatus::QUEUE || status == cpp2::JobStatus::RUNNING) { return true; } } diff --git a/src/meta/processors/job/JobManager.h b/src/meta/processors/job/JobManager.h index 837d6dbc2e1..f33d18cf4b5 100644 --- a/src/meta/processors/job/JobManager.h +++ b/src/meta/processors/job/JobManager.h @@ -7,7 +7,7 @@ #define META_JOBMANAGER_H_ #include -#include +#include #include #include @@ -62,11 +62,16 @@ class JobManager : public boost::noncopyable, public nebula::cpp::NonMovable { RECOVER, }; + enum class JbPriority : size_t { + kHIGH = 0x00, + kLOW = 0x01, + }; + /** * @brief Init task queue, kvStore and schedule thread * * @param store - * @return + * @return true if the init is successful */ bool init(nebula::kvstore::KVStore* store); @@ -80,115 +85,121 @@ class JobManager : public boost::noncopyable, public nebula::cpp::NonMovable { * * @param jobDesc * @param client - * @return + * @return nebula::cpp2::ErrorCode */ - nebula::cpp2::ErrorCode addJob(const JobDescription& jobDesc, AdminClient* client); + nebula::cpp2::ErrorCode addJob(JobDescription& jobDesc, AdminClient* client); /** * @brief The same job is in jobMap * + * @param spaceId * @param type * @param paras - * @param iJob + * @param jobId If the job exists, jobId is the id of the existing job * @return */ - bool checkJobExist(const cpp2::JobType& type, const std::vector& paras, JobID& iJob); + bool checkJobExist(GraphSpaceID spaceId, + const cpp2::JobType& type, + const std::vector& paras, + JobID& jobId); /** * @brief Load all jobs of the space from kvStore and convert to cpp2::JobDesc * - * @param spaceName - * @return + * @param spaceId + * @return ErrorOr> */ - ErrorOr> showJobs( - const std::string& spaceName); + ErrorOr> showJobs(GraphSpaceID spaceId); /** * @brief Load one job and related tasks from kvStore and convert to cpp2::JobDesc * - * @param iJob - * @param spaceName - * @return + * @param spaceId + * @param jobId + * @return ErrorOr> */ ErrorOr>> showJob( - JobID iJob, const std::string& spaceName); + GraphSpaceID spaceId, JobID jobId); /** * @brief Stop a job when user cancel it * - * @param iJob - * @param spaceName - * @return + * @param spaceId + * @param jobId + * @return nebula::cpp2::ErrorCode */ - nebula::cpp2::ErrorCode stopJob(JobID iJob, const std::string& spaceName); + nebula::cpp2::ErrorCode stopJob(GraphSpaceID spaceId, JobID jobId); /** - * @brief + * @brief Number of recovered jobs * - * @param spaceName + * @param spaceId * @param client * @param jobIds * @return Return error/recovered job num */ - ErrorOr recoverJob(const std::string& spaceName, + ErrorOr recoverJob(GraphSpaceID spaceId, AdminClient* client, const std::vector& jobIds = {}); /** * @brief Persist job executed result, and do the cleanup * + * @param spaceId * @param jobId * @param jobStatus * @return cpp2::ErrorCode if error when write to kv store */ - nebula::cpp2::ErrorCode jobFinished(JobID jobId, cpp2::JobStatus jobStatus); + nebula::cpp2::ErrorCode jobFinished(GraphSpaceID spaceId, JobID jobId, cpp2::JobStatus jobStatus); /** * @brief Report task finished. * * @param req - * @return + * @return cpp2::ErrorCode */ nebula::cpp2::ErrorCode reportTaskFinish(const cpp2::ReportTaskReq& req); /** * @brief Only used for Test - * The number of jobs in lowPriorityQueue_ a and highPriorityQueue_ + * The number of jobs in all spaces * * @return */ size_t jobSize() const; /** - * @brief Tries to extract an element from the front of the highPriorityQueue_, - * If failed, then extract an element from lowPriorityQueue_. - * If the element is obtained, return true, otherwise return false. + * @brief Traverse from priorityQueues_, and find the priorityQueue of the space + * that is not executing the job. Then take a job from the queue according to the priority. * * @param opJobId - * @return + * @return return true if the element is obtained, otherwise return false. */ - bool try_dequeue(std::pair& opJobId); + bool tryDequeue(std::tuple& opJobId); /** - * @brief Enter different priority queues according to the command type + * @brief Enter different priority queues according to the command type and space * - * @param op Recover a job or add a new one + * @param spaceId SpaceId of the job * @param jobId Id of the job + * @param op Recover a job or add a new one * @param jobType Type of the job */ - void enqueue(const JbOp& op, const JobID& jobId, const cpp2::JobType& jobType); + void enqueue(GraphSpaceID spaceId, JobID jobId, const JbOp& op, const cpp2::JobType& jobType); /** - * @brief Check if there is a rebuild_tag_index or rebuild_edge_index running + * @brief Check whether the job of the specified type in all spaces is running * - * @return + * @param jobTypes Cmd types of the job + * @return ErrorOr */ - ErrorOr checkIndexJobRunning(); + ErrorOr checkTypeJobRunning( + std::unordered_set& jobTypes); /** - * @brief Load jobs that are running before crashed and add them into queue - * - * @return + * @brief Load jobs that are running before crashed, set status to QUEUE + * Notice: Only the meta leader can save successfully. + * Set the QUEUE state for later recover this job. */ nebula::cpp2::ErrorCode handleRemainingJobs(); @@ -210,9 +221,7 @@ class JobManager : public boost::noncopyable, public nebula::cpp::NonMovable { nebula::cpp2::ErrorCode save(const std::string& k, const std::string& v); - static bool isExpiredJob(const cpp2::JobDesc& jobDesc); - - static bool isRunningJob(const JobDescription& jobDesc); + static bool isExpiredJob(JobDescription& jobDesc); /** * @brief Remove jobs of the given keys @@ -228,7 +237,8 @@ class JobManager : public boost::noncopyable, public nebula::cpp::NonMovable { * @param jobId * @return */ - ErrorOr> getAllTasks(JobID jobId); + ErrorOr> getAllTasks(GraphSpaceID spaceId, + JobID jobId); /** * @brief Remove a job from the queue and running map @@ -255,23 +265,25 @@ class JobManager : public boost::noncopyable, public nebula::cpp::NonMovable { void compareChangeStatus(JbmgrStatus expected, JbmgrStatus desired); private: - // Todo(pandasheep) - // When folly is upgraded, PriorityUMPSCQueueSet can be used - // Use two queues to simulate priority queue, Divide by job type - std::unique_ptr, true>> lowPriorityQueue_; - std::unique_ptr, true>> highPriorityQueue_; - std::map> runningJobs_; + using PriorityQueue = folly::PriorityUMPSCQueueSet, true>; + // Each PriorityQueue contains high and low priority queues. + // The lower the value, the higher the priority. + folly::ConcurrentHashMap> priorityQueues_; + // Identify whether the current space is running a job + folly::ConcurrentHashMap> spaceRunningJobs_; + + std::map> runningJobs_; // The job in running or queue folly::ConcurrentHashMap inFlightJobs_; std::thread bgThread_; nebula::kvstore::KVStore* kvStore_{nullptr}; AdminClient* adminClient_{nullptr}; - std::mutex muReportFinish_; + std::map muReportFinish_; // The reason of using recursive_mutex is that, it's possible for a meta job try to get this lock // in finish-callback in the same thread with runJobInternal - std::recursive_mutex muJobFinished_; + std::map muJobFinished_; std::atomic status_ = JbmgrStatus::NOT_START; }; diff --git a/src/meta/processors/job/JobUtils.cpp b/src/meta/processors/job/JobUtils.cpp deleted file mode 100644 index 1cab6e0c4f7..00000000000 --- a/src/meta/processors/job/JobUtils.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright (c) 2019 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#include "meta/processors/job/JobUtils.h" - -#include -#include -#include - -#include "common/base/Base.h" - -namespace nebula { -namespace meta { - -/* - * It it the key to describe the current job id. - * each time a job added, this value will +1 - * *important* *important* *important* - * this key is carefully designed to be the length of jobKey + size(int32_t) + 1 - * */ -const std::string kCurrJob = "__job_mgr____id"; // NOLINT - -/* - * this is the prefix for a regular job - * there will be one job, and a bunch of tasks use this prefix - * if there are 1 job(let say 65536) which has 4 sub tasks, there will 5 records - * in kvstore which is - * __job_mgr_<65536> - * __job_mgr_<65536><0> - * __job_mgr_<65536><1> - * __job_mgr_<65536><2> - * __job_mgr_<65536><3> - * */ -const std::string kJob = "__job_mgr_"; // NOLINT - -/* - * DBA may call "backup jobs " - * then all the jobs(and sub tasks) in the range will be moved from kJob to this - * */ -const std::string kJobArchive = "__job_mgr_archive_"; // NOLINT - -const std::string& JobUtil::jobPrefix() { - return kJob; -} - -const std::string& JobUtil::currJobKey() { - return kCurrJob; -} - -const std::string& JobUtil::archivePrefix() { - return kJobArchive; -} - -std::string JobUtil::parseString(folly::StringPiece rawVal, size_t offset) { - if (rawVal.size() < offset + sizeof(size_t)) { - LOG(INFO) << "Error: rawVal: " << toHexStr(rawVal) << ", offset: " << offset; - throw std::runtime_error( - folly::stringPrintf("%s: offset=%zu, rawVal.size()=%zu", __func__, offset, rawVal.size())); - } - auto len = *reinterpret_cast(rawVal.data() + offset); - offset += sizeof(size_t); - if (rawVal.size() < offset + len) { - LOG(INFO) << "Error: rawVal: " << toHexStr(rawVal) << ", len: " << len - << ", offset: " << offset; - throw std::runtime_error( - folly::stringPrintf("%s: offset=%zu, rawVal.size()=%zu", __func__, offset, rawVal.size())); - } - return std::string(rawVal.data() + offset, len); -} - -std::vector JobUtil::parseStrVector(folly::StringPiece rawVal, size_t* offset) { - std::vector ret; - if (rawVal.size() < *offset + sizeof(size_t)) { - LOG(INFO) << "Error: rawVal: " << toHexStr(rawVal) << ", offset: " << offset; - throw std::runtime_error( - folly::stringPrintf("%s: offset=%zu, rawVal.size()=%zu", __func__, *offset, rawVal.size())); - } - auto vec_size = *reinterpret_cast(rawVal.data() + *offset); - *offset += sizeof(size_t); - for (size_t i = 0; i < vec_size; ++i) { - ret.emplace_back(parseString(rawVal, *offset)); - *offset += sizeof(size_t); - *offset += ret.back().length(); - } - return ret; -} - -} // namespace meta -} // namespace nebula diff --git a/src/meta/processors/job/JobUtils.h b/src/meta/processors/job/JobUtils.h deleted file mode 100644 index abbb3ce306a..00000000000 --- a/src/meta/processors/job/JobUtils.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (c) 2019 vesoft inc. All rights reserved. - * - * This source code is licensed under Apache 2.0 License. - */ - -#ifndef META_JOBUTIL_H_ -#define META_JOBUTIL_H_ - -#include -#include - -#include -#include -#include -#include -#include - -namespace nebula { -namespace meta { - -class JobUtil { - public: - static const std::string& jobPrefix(); - static const std::string& currJobKey(); - static const std::string& archivePrefix(); - - template - static T parseFixedVal(folly::StringPiece rawVal, size_t offset) { - if (rawVal.size() < offset + sizeof(T)) { - throw std::runtime_error(folly::stringPrintf( - "%s: offset=%zu, rawVal.size()=%zu", __func__, offset, rawVal.size())); - } - return *reinterpret_cast(rawVal.data() + offset); - } - - /** - * @brief Get a string from a serialized value - * - * @param rawVal string to read - * @param offset from where to read the string - * @return - */ - static std::string parseString(folly::StringPiece rawVal, size_t offset); - - /** - * @brief Get vector of string from a serialized value - * - * @param rawVal - * @param offset - * @return - */ - static std::vector parseStrVector(folly::StringPiece rawVal, size_t* offset); -}; - -} // namespace meta -} // namespace nebula - -#endif // META_JOBUTIL_H_ diff --git a/src/meta/processors/job/LeaderBalanceJobExecutor.cpp b/src/meta/processors/job/LeaderBalanceJobExecutor.cpp index 30eb187a579..c42b65e94f8 100644 --- a/src/meta/processors/job/LeaderBalanceJobExecutor.cpp +++ b/src/meta/processors/job/LeaderBalanceJobExecutor.cpp @@ -9,7 +9,6 @@ #include "common/utils/MetaKeyUtils.h" #include "kvstore/NebulaStore.h" -#include "meta/processors/job/JobUtils.h" DEFINE_double(leader_balance_deviation, 0.05, @@ -213,11 +212,12 @@ void LeaderBalanceJobExecutor::calDiff(const HostParts& hostParts, } } -LeaderBalanceJobExecutor::LeaderBalanceJobExecutor(JobID jobId, +LeaderBalanceJobExecutor::LeaderBalanceJobExecutor(GraphSpaceID space, + JobID jobId, kvstore::KVStore* kvstore, AdminClient* adminClient, const std::vector& params) - : MetaJobExecutor(jobId, kvstore, adminClient, params), + : MetaJobExecutor(space, jobId, kvstore, adminClient, params), inLeaderBalance_(false), hostLeaderMap_(nullptr) { executor_.reset(new folly::CPUThreadPoolExecutor(1)); diff --git a/src/meta/processors/job/LeaderBalanceJobExecutor.h b/src/meta/processors/job/LeaderBalanceJobExecutor.h index 2c07ff4d581..3bd42b2ee65 100644 --- a/src/meta/processors/job/LeaderBalanceJobExecutor.h +++ b/src/meta/processors/job/LeaderBalanceJobExecutor.h @@ -28,7 +28,8 @@ class LeaderBalanceJobExecutor : public MetaJobExecutor { FRIEND_TEST(BalanceTest, LeaderBalanceWithComplexZoneTest); public: - LeaderBalanceJobExecutor(JobID jobId, + LeaderBalanceJobExecutor(GraphSpaceID space, + JobID jobId, kvstore::KVStore* kvstore, AdminClient* adminClient, const std::vector& params); diff --git a/src/meta/processors/job/ListEdgeIndexStatusProcessor.cpp b/src/meta/processors/job/ListEdgeIndexStatusProcessor.cpp index 4a5a35eac0d..b2440d31c4e 100644 --- a/src/meta/processors/job/ListEdgeIndexStatusProcessor.cpp +++ b/src/meta/processors/job/ListEdgeIndexStatusProcessor.cpp @@ -5,14 +5,17 @@ #include "meta/processors/job/ListEdgeIndexStatusProcessor.h" +#include "meta/processors/job/JobDescription.h" + namespace nebula { namespace meta { void ListEdgeIndexStatusProcessor::process(const cpp2::ListIndexStatusReq& req) { - auto curSpaceId = req.get_space_id(); - CHECK_SPACE_ID_AND_RETURN(curSpaceId); + auto spaceId = req.get_space_id(); + CHECK_SPACE_ID_AND_RETURN(spaceId); std::unique_ptr iter; - auto retCode = kvstore_->prefix(kDefaultSpaceId, kDefaultPartId, JobUtil::jobPrefix(), &iter); + auto jobPrefix = MetaKeyUtils::jobPrefix(spaceId); + auto retCode = kvstore_->prefix(kDefaultSpaceId, kDefaultPartId, jobPrefix, &iter); if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { LOG(INFO) << "Loading Job Failed" << apache::thrift::util::enumNameSafe(retCode); handleErrorCode(retCode); @@ -21,55 +24,35 @@ void ListEdgeIndexStatusProcessor::process(const cpp2::ListIndexStatusReq& req) } std::vector jobs; - std::vector statuses; for (; iter->valid(); iter->next()) { - if (JobDescription::isJobKey(iter->key())) { + if (MetaKeyUtils::isJobKey(iter->key())) { auto optJobRet = JobDescription::makeJobDescription(iter->key(), iter->val()); if (!nebula::ok(optJobRet)) { continue; } auto optJob = nebula::value(optJobRet); - auto jobDesc = optJob.toJobDesc(); - if (jobDesc.get_type() == meta::cpp2::JobType::REBUILD_EDGE_INDEX) { - auto paras = jobDesc.get_paras(); - DCHECK_GE(paras.size(), 1); - auto spaceName = paras.back(); - auto ret = getSpaceId(spaceName); - if (!nebula::ok(ret)) { - retCode = nebula::error(ret); - if (retCode == nebula::cpp2::ErrorCode::E_LEADER_CHANGED) { - handleErrorCode(retCode); - onFinished(); - return; - } - continue; - } - auto spaceId = nebula::value(ret); - if (spaceId != curSpaceId) { - continue; - } - + if (optJob.getJobType() == cpp2::JobType::REBUILD_EDGE_INDEX) { + auto jobDesc = optJob.toJobDesc(); jobs.emplace_back(jobDesc); } } } std::sort(jobs.begin(), jobs.end(), [](const auto& a, const auto& b) { - return a.get_id() > b.get_id(); + return a.get_job_id() > b.get_job_id(); }); - std::unordered_map tmp; + + std::vector statuses; for (auto& jobDesc : jobs) { + cpp2::IndexStatus status; auto paras = jobDesc.get_paras(); - if (paras.size() == 1) { - tmp.emplace(paras[0] + "_all_edge_indexes", jobDesc.get_status()); - continue; + std::string edgeIndexJobName; + if (paras.empty()) { + edgeIndexJobName = "all_edge_indexes"; + } else { + edgeIndexJobName = folly::join(",", paras); } - paras.pop_back(); - tmp.emplace(folly::join(",", paras), jobDesc.get_status()); - } - for (auto& kv : tmp) { - cpp2::IndexStatus status; - status.name_ref() = std::move(kv.first); - status.status_ref() = apache::thrift::util::enumNameSafe(kv.second); + status.name_ref() = edgeIndexJobName; + status.status_ref() = apache::thrift::util::enumNameSafe(jobDesc.get_status()); statuses.emplace_back(std::move(status)); } resp_.statuses_ref() = std::move(statuses); diff --git a/src/meta/processors/job/ListEdgeIndexStatusProcessor.h b/src/meta/processors/job/ListEdgeIndexStatusProcessor.h index ba6257b07b1..2197bc67330 100644 --- a/src/meta/processors/job/ListEdgeIndexStatusProcessor.h +++ b/src/meta/processors/job/ListEdgeIndexStatusProcessor.h @@ -7,8 +7,6 @@ #define META_LISTEDGEINDEXSTATUSPROCESSOR_H #include "meta/processors/BaseProcessor.h" -#include "meta/processors/job/JobDescription.h" -#include "meta/processors/job/JobUtils.h" namespace nebula { namespace meta { diff --git a/src/meta/processors/job/ListTagIndexStatusProcessor.cpp b/src/meta/processors/job/ListTagIndexStatusProcessor.cpp index ea003fd1bb1..caeca3fc1f9 100644 --- a/src/meta/processors/job/ListTagIndexStatusProcessor.cpp +++ b/src/meta/processors/job/ListTagIndexStatusProcessor.cpp @@ -5,14 +5,17 @@ #include "meta/processors/job/ListTagIndexStatusProcessor.h" +#include "meta/processors/job/JobDescription.h" + namespace nebula { namespace meta { void ListTagIndexStatusProcessor::process(const cpp2::ListIndexStatusReq& req) { - auto curSpaceId = req.get_space_id(); - CHECK_SPACE_ID_AND_RETURN(curSpaceId); + auto spaceId = req.get_space_id(); + CHECK_SPACE_ID_AND_RETURN(spaceId); std::unique_ptr iter; - auto retCode = kvstore_->prefix(kDefaultSpaceId, kDefaultPartId, JobUtil::jobPrefix(), &iter); + auto jobPrefix = MetaKeyUtils::jobPrefix(spaceId); + auto retCode = kvstore_->prefix(kDefaultSpaceId, kDefaultPartId, jobPrefix, &iter); if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { LOG(INFO) << "Loading Job Failed" << apache::thrift::util::enumNameSafe(retCode); handleErrorCode(retCode); @@ -21,56 +24,36 @@ void ListTagIndexStatusProcessor::process(const cpp2::ListIndexStatusReq& req) { } std::vector jobs; - std::vector statuses; for (; iter->valid(); iter->next()) { - if (JobDescription::isJobKey(iter->key())) { + if (MetaKeyUtils::isJobKey(iter->key())) { auto optJobRet = JobDescription::makeJobDescription(iter->key(), iter->val()); if (!nebula::ok(optJobRet)) { continue; } auto optJob = nebula::value(optJobRet); - auto jobDesc = optJob.toJobDesc(); - if (jobDesc.get_type() == cpp2::JobType::REBUILD_TAG_INDEX) { - auto paras = jobDesc.get_paras(); - DCHECK_GE(paras.size(), 1); - auto spaceName = paras.back(); - auto ret = getSpaceId(spaceName); - if (!nebula::ok(ret)) { - retCode = nebula::error(ret); - if (retCode == nebula::cpp2::ErrorCode::E_LEADER_CHANGED) { - handleErrorCode(retCode); - onFinished(); - return; - } - continue; - } - auto spaceId = nebula::value(ret); - if (spaceId != curSpaceId) { - continue; - } - + if (optJob.getJobType() == cpp2::JobType::REBUILD_TAG_INDEX) { + auto jobDesc = optJob.toJobDesc(); jobs.emplace_back(jobDesc); } } } std::sort(jobs.begin(), jobs.end(), [](const auto& a, const auto& b) { - return a.get_id() > b.get_id(); + return a.get_job_id() > b.get_job_id(); }); - std::unordered_map tmp; + + std::vector statuses; for (auto& jobDesc : jobs) { + cpp2::IndexStatus status; auto paras = jobDesc.get_paras(); - if (paras.size() == 1) { - tmp.emplace(paras[0] + "_all_tag_indexes", jobDesc.get_status()); - continue; + std::string tagIndexJobName; + if (paras.empty()) { + tagIndexJobName = "all_tag_indexes"; + } else { + tagIndexJobName = folly::join(",", paras); } - paras.pop_back(); - tmp.emplace(folly::join(",", paras), jobDesc.get_status()); - } - for (auto& kv : tmp) { - cpp2::IndexStatus status; - status.name_ref() = std::move(kv.first); - status.status_ref() = apache::thrift::util::enumNameSafe(kv.second); + status.name_ref() = tagIndexJobName; + status.status_ref() = apache::thrift::util::enumNameSafe(jobDesc.get_status()); statuses.emplace_back(std::move(status)); } resp_.statuses_ref() = std::move(statuses); diff --git a/src/meta/processors/job/ListTagIndexStatusProcessor.h b/src/meta/processors/job/ListTagIndexStatusProcessor.h index 14513f33a55..bc3f022eefe 100644 --- a/src/meta/processors/job/ListTagIndexStatusProcessor.h +++ b/src/meta/processors/job/ListTagIndexStatusProcessor.h @@ -7,8 +7,6 @@ #define META_LISTTAGINDEXSTATUSPROCESSOR_H_ #include "meta/processors/BaseProcessor.h" -#include "meta/processors/job/JobDescription.h" -#include "meta/processors/job/JobUtils.h" namespace nebula { namespace meta { diff --git a/src/meta/processors/job/MetaJobExecutor.cpp b/src/meta/processors/job/MetaJobExecutor.cpp index 57056a700a1..bdba83d3b5f 100644 --- a/src/meta/processors/job/MetaJobExecutor.cpp +++ b/src/meta/processors/job/MetaJobExecutor.cpp @@ -43,10 +43,6 @@ nebula::cpp2::ErrorCode MetaJobExecutor::finish(bool) { return nebula::cpp2::ErrorCode::SUCCEEDED; } -void MetaJobExecutor::setSpaceId(GraphSpaceID spaceId) { - space_ = spaceId; -} - bool MetaJobExecutor::isMetaJob() { return true; } diff --git a/src/meta/processors/job/MetaJobExecutor.h b/src/meta/processors/job/MetaJobExecutor.h index be0b5fa37fe..519f755a4b1 100644 --- a/src/meta/processors/job/MetaJobExecutor.h +++ b/src/meta/processors/job/MetaJobExecutor.h @@ -19,11 +19,12 @@ namespace meta { class MetaJobExecutor : public JobExecutor { public: - MetaJobExecutor(JobID jobId, + MetaJobExecutor(GraphSpaceID space, + JobID jobId, kvstore::KVStore* kvstore, AdminClient* adminClient, const std::vector& paras) - : JobExecutor(kvstore), jobId_(jobId), adminClient_(adminClient), paras_(paras) { + : JobExecutor(kvstore, space), jobId_(jobId), adminClient_(adminClient), paras_(paras) { executorOnFinished_ = [](meta::cpp2::JobStatus) { return nebula::cpp2::ErrorCode::SUCCEEDED; }; } @@ -60,8 +61,6 @@ class MetaJobExecutor : public JobExecutor { nebula::cpp2::ErrorCode finish(bool) override; - void setSpaceId(GraphSpaceID spaceId) override; - bool isMetaJob() override; nebula::cpp2::ErrorCode recovery() override; @@ -78,7 +77,6 @@ class MetaJobExecutor : public JobExecutor { JobID jobId_{INT_MIN}; TaskID taskId_{0}; AdminClient* adminClient_{nullptr}; - GraphSpaceID space_; std::vector paras_; volatile bool stopped_{false}; std::mutex muInterrupt_; diff --git a/src/meta/processors/job/RebuildEdgeJobExecutor.h b/src/meta/processors/job/RebuildEdgeJobExecutor.h index cc688b4ecb8..a4486246388 100644 --- a/src/meta/processors/job/RebuildEdgeJobExecutor.h +++ b/src/meta/processors/job/RebuildEdgeJobExecutor.h @@ -13,11 +13,12 @@ namespace meta { class RebuildEdgeJobExecutor : public RebuildJobExecutor { public: - RebuildEdgeJobExecutor(JobID jobId, + RebuildEdgeJobExecutor(GraphSpaceID space, + JobID jobId, kvstore::KVStore* kvstore, AdminClient* adminClient, const std::vector& paras) - : RebuildJobExecutor(jobId, kvstore, adminClient, std::move(paras)) {} + : RebuildJobExecutor(space, jobId, kvstore, adminClient, std::move(paras)) {} protected: folly::Future executeInternal(HostAddr&& address, diff --git a/src/meta/processors/job/RebuildFTJobExecutor.h b/src/meta/processors/job/RebuildFTJobExecutor.h index 0ea039c0f62..b23990a0805 100644 --- a/src/meta/processors/job/RebuildFTJobExecutor.h +++ b/src/meta/processors/job/RebuildFTJobExecutor.h @@ -13,11 +13,12 @@ namespace meta { class RebuildFTJobExecutor : public RebuildJobExecutor { public: - RebuildFTJobExecutor(JobID jobId, + RebuildFTJobExecutor(GraphSpaceID space, + JobID jobId, kvstore::KVStore* kvstore, AdminClient* adminClient, const std::vector& paras) - : RebuildJobExecutor(jobId, kvstore, adminClient, std::move(paras)) { + : RebuildJobExecutor(space, jobId, kvstore, adminClient, std::move(paras)) { toHost_ = TargetHosts::LISTENER; } diff --git a/src/meta/processors/job/RebuildJobExecutor.cpp b/src/meta/processors/job/RebuildJobExecutor.cpp index e8377a21488..2fa380af7b0 100644 --- a/src/meta/processors/job/RebuildJobExecutor.cpp +++ b/src/meta/processors/job/RebuildJobExecutor.cpp @@ -16,22 +16,17 @@ DECLARE_int32(heartbeat_interval_secs); namespace nebula { namespace meta { -bool RebuildJobExecutor::check() { - return paras_.size() >= 1; -} - nebula::cpp2::ErrorCode RebuildJobExecutor::prepare() { - // the last value of paras_ is the space name, others are index name - auto spaceRet = getSpaceIdFromName(paras_.back()); - if (!nebula::ok(spaceRet)) { - LOG(INFO) << "Can't find the space: " << paras_.back(); - return nebula::error(spaceRet); + // The last value of paras_ are index name + auto spaceRet = spaceExist(); + if (spaceRet != nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(INFO) << "Can't find the space, spaceId " << space_; + return spaceRet; } - space_ = nebula::value(spaceRet); std::string indexValue; IndexID indexId = -1; - for (auto i = 0u; i < paras_.size() - 1; i++) { + for (auto i = 0u; i < paras_.size(); i++) { auto indexKey = MetaKeyUtils::indexIndexKey(space_, paras_[i]); auto retCode = kvstore_->get(kDefaultSpaceId, kDefaultPartId, indexKey, &indexValue); if (retCode != nebula::cpp2::ErrorCode::SUCCEEDED) { diff --git a/src/meta/processors/job/RebuildJobExecutor.h b/src/meta/processors/job/RebuildJobExecutor.h index 4832b724c67..2d1820cbd71 100644 --- a/src/meta/processors/job/RebuildJobExecutor.h +++ b/src/meta/processors/job/RebuildJobExecutor.h @@ -15,16 +15,15 @@ namespace meta { class RebuildJobExecutor : public StorageJobExecutor { public: - RebuildJobExecutor(JobID jobId, + RebuildJobExecutor(GraphSpaceID space, + JobID jobId, kvstore::KVStore* kvstore, AdminClient* adminClient, const std::vector& paras) - : StorageJobExecutor(jobId, kvstore, adminClient, paras) { + : StorageJobExecutor(space, jobId, kvstore, adminClient, paras) { toHost_ = TargetHosts::LEADER; } - bool check() override; - nebula::cpp2::ErrorCode prepare() override; nebula::cpp2::ErrorCode stop() override; diff --git a/src/meta/processors/job/RebuildTagJobExecutor.h b/src/meta/processors/job/RebuildTagJobExecutor.h index 8cb7a763b4f..ff6d11b1db6 100644 --- a/src/meta/processors/job/RebuildTagJobExecutor.h +++ b/src/meta/processors/job/RebuildTagJobExecutor.h @@ -13,11 +13,12 @@ namespace meta { class RebuildTagJobExecutor : public RebuildJobExecutor { public: - RebuildTagJobExecutor(JobID jobId, + RebuildTagJobExecutor(GraphSpaceID space, + JobID jobId, kvstore::KVStore* kvstore, AdminClient* adminClient, const std::vector& paras) - : RebuildJobExecutor(jobId, kvstore, adminClient, std::move(paras)) {} + : RebuildJobExecutor(space, jobId, kvstore, adminClient, std::move(paras)) {} protected: folly::Future executeInternal(HostAddr&& address, diff --git a/src/meta/processors/job/SimpleConcurrentJobExecutor.cpp b/src/meta/processors/job/SimpleConcurrentJobExecutor.cpp index 991c44ff66e..6edd2b417bf 100644 --- a/src/meta/processors/job/SimpleConcurrentJobExecutor.cpp +++ b/src/meta/processors/job/SimpleConcurrentJobExecutor.cpp @@ -11,26 +11,24 @@ namespace nebula { namespace meta { -SimpleConcurrentJobExecutor::SimpleConcurrentJobExecutor(JobID jobId, +SimpleConcurrentJobExecutor::SimpleConcurrentJobExecutor(GraphSpaceID space, + JobID jobId, kvstore::KVStore* kvstore, AdminClient* adminClient, const std::vector& paras) - : StorageJobExecutor(jobId, kvstore, adminClient, paras) {} + : StorageJobExecutor(space, jobId, kvstore, adminClient, paras) {} bool SimpleConcurrentJobExecutor::check() { - auto parasNum = paras_.size(); - return parasNum == 1; + return paras_.empty(); } nebula::cpp2::ErrorCode SimpleConcurrentJobExecutor::prepare() { - std::string spaceName = paras_.back(); - auto errOrSpaceId = getSpaceIdFromName(spaceName); - if (!nebula::ok(errOrSpaceId)) { - LOG(INFO) << "Can't find the space: " << spaceName; - return nebula::error(errOrSpaceId); + auto spaceRet = spaceExist(); + if (spaceRet != nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(INFO) << "Can't find the space, spaceId " << space_; + return spaceRet; } - space_ = nebula::value(errOrSpaceId); ErrOrHosts errOrHost = getTargetHost(space_); if (!nebula::ok(errOrHost)) { LOG(INFO) << "Can't get any host according to space"; diff --git a/src/meta/processors/job/SimpleConcurrentJobExecutor.h b/src/meta/processors/job/SimpleConcurrentJobExecutor.h index 6400379bb01..7df1b8f8036 100644 --- a/src/meta/processors/job/SimpleConcurrentJobExecutor.h +++ b/src/meta/processors/job/SimpleConcurrentJobExecutor.h @@ -14,7 +14,8 @@ namespace meta { class SimpleConcurrentJobExecutor : public StorageJobExecutor { public: - SimpleConcurrentJobExecutor(JobID jobId, + SimpleConcurrentJobExecutor(GraphSpaceID space, + JobID jobId, kvstore::KVStore* kvstore, AdminClient* adminClient, const std::vector& params); diff --git a/src/meta/processors/job/StatsJobExecutor.cpp b/src/meta/processors/job/StatsJobExecutor.cpp index ee72d283c41..0a36546d05d 100644 --- a/src/meta/processors/job/StatsJobExecutor.cpp +++ b/src/meta/processors/job/StatsJobExecutor.cpp @@ -13,8 +13,7 @@ namespace nebula { namespace meta { bool StatsJobExecutor::check() { - // Only one parameter, the current space name - return paras_.size() == 1; + return paras_.empty(); } nebula::cpp2::ErrorCode StatsJobExecutor::save(const std::string& key, const std::string& val) { @@ -42,13 +41,11 @@ nebula::cpp2::ErrorCode StatsJobExecutor::doRemove(const std::string& key) { } nebula::cpp2::ErrorCode StatsJobExecutor::prepare() { - std::string spaceName = paras_.back(); - auto spaceRet = getSpaceIdFromName(spaceName); - if (!nebula::ok(spaceRet)) { - LOG(INFO) << "Can't find the space: " << spaceName; - return nebula::error(spaceRet); + auto spaceRet = spaceExist(); + if (spaceRet != nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(INFO) << "Can't find the space, spaceId " << space_; + return spaceRet; } - space_ = nebula::value(spaceRet); // Set the status of the stats job to running cpp2::StatsItem statsItem; @@ -144,11 +141,9 @@ nebula::cpp2::ErrorCode StatsJobExecutor::saveSpecialTaskStatus(const cpp2::Repo } /** - * @brief - * if two stats job run at the same time. - * (this may happens if leader changed) - * they will write to the same kv data - * so separate the partial result by job + * @brief If two stats job run at the same time. + * This may happens if leader changed. They will write to the same kv data, + * so separate the partial result by job. * @return std::string */ std::string StatsJobExecutor::toTempKey(int32_t jobId) { diff --git a/src/meta/processors/job/StatsJobExecutor.h b/src/meta/processors/job/StatsJobExecutor.h index ace89e0aa43..ba0c9666b3d 100644 --- a/src/meta/processors/job/StatsJobExecutor.h +++ b/src/meta/processors/job/StatsJobExecutor.h @@ -15,11 +15,12 @@ namespace meta { class StatsJobExecutor : public StorageJobExecutor { public: - StatsJobExecutor(JobID jobId, + StatsJobExecutor(GraphSpaceID space, + JobID jobId, kvstore::KVStore* kvstore, AdminClient* adminClient, const std::vector& paras) - : StorageJobExecutor(jobId, kvstore, adminClient, paras) { + : StorageJobExecutor(space, jobId, kvstore, adminClient, paras) { toHost_ = TargetHosts::LEADER; } diff --git a/src/meta/processors/job/StorageJobExecutor.cpp b/src/meta/processors/job/StorageJobExecutor.cpp index 6933a0e6c3f..013a555c3f2 100644 --- a/src/meta/processors/job/StorageJobExecutor.cpp +++ b/src/meta/processors/job/StorageJobExecutor.cpp @@ -153,21 +153,26 @@ nebula::cpp2::ErrorCode StorageJobExecutor::execute() { auto addresses = nebula::value(addressesRet); // write all tasks first. + std::vector data; for (auto i = 0U; i != addresses.size(); ++i) { - TaskDescription task(jobId_, i, addresses[i].first); - std::vector data{{task.taskKey(), task.taskVal()}}; - folly::Baton baton; - auto rc = nebula::cpp2::ErrorCode::SUCCEEDED; - kvstore_->asyncMultiPut( - kDefaultSpaceId, kDefaultPartId, std::move(data), [&](nebula::cpp2::ErrorCode code) { - rc = code; - baton.post(); - }); - baton.wait(); - if (rc != nebula::cpp2::ErrorCode::SUCCEEDED) { - LOG(INFO) << "write to kv store failed, error: " << apache::thrift::util::enumNameSafe(rc); - return rc; - } + TaskDescription task(space_, jobId_, i, addresses[i].first); + auto taskKey = MetaKeyUtils::taskKey(task.getSpace(), task.getJobId(), task.getTaskId()); + auto taskVal = MetaKeyUtils::taskVal( + task.getHost(), task.getStatus(), task.getStartTime(), task.getStopTime()); + data.emplace_back(std::move(taskKey), std::move(taskVal)); + } + + folly::Baton baton; + auto rc = nebula::cpp2::ErrorCode::SUCCEEDED; + kvstore_->asyncMultiPut( + kDefaultSpaceId, kDefaultPartId, std::move(data), [&](nebula::cpp2::ErrorCode code) { + rc = code; + baton.post(); + }); + baton.wait(); + if (rc != nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(INFO) << "write to kv store failed, error: " << apache::thrift::util::enumNameSafe(rc); + return rc; } std::vector> futures; @@ -176,7 +181,6 @@ nebula::cpp2::ErrorCode StorageJobExecutor::execute() { futures.emplace_back(executeInternal(std::move(address.first), std::move(address.second))); } - auto rc = nebula::cpp2::ErrorCode::SUCCEEDED; auto tries = folly::collectAll(std::move(futures)).get(); for (auto& t : tries) { if (t.hasException()) { diff --git a/src/meta/processors/job/StorageJobExecutor.h b/src/meta/processors/job/StorageJobExecutor.h index ea47614c6a8..0f0eb6eb5a1 100644 --- a/src/meta/processors/job/StorageJobExecutor.h +++ b/src/meta/processors/job/StorageJobExecutor.h @@ -24,11 +24,12 @@ class StorageJobExecutor : public JobExecutor { public: enum class TargetHosts { LEADER = 0, LISTENER, DEFAULT }; - StorageJobExecutor(JobID jobId, + StorageJobExecutor(GraphSpaceID space, + JobID jobId, kvstore::KVStore* kvstore, AdminClient* adminClient, const std::vector& paras) - : JobExecutor(kvstore), jobId_(jobId), adminClient_(adminClient), paras_(paras) {} + : JobExecutor(kvstore, space), jobId_(jobId), adminClient_(adminClient), paras_(paras) {} virtual ~StorageJobExecutor() = default; @@ -73,10 +74,6 @@ class StorageJobExecutor : public JobExecutor { return nebula::cpp2::ErrorCode::SUCCEEDED; } - void setSpaceId(GraphSpaceID spaceId) override { - space_ = spaceId; - } - nebula::cpp2::ErrorCode saveSpecialTaskStatus(const cpp2::ReportTaskReq&) override { return nebula::cpp2::ErrorCode::SUCCEEDED; } @@ -103,7 +100,6 @@ class StorageJobExecutor : public JobExecutor { JobID jobId_{INT_MIN}; TaskID taskId_{0}; AdminClient* adminClient_{nullptr}; - GraphSpaceID space_; std::vector paras_; TargetHosts toHost_{TargetHosts::DEFAULT}; volatile bool stopped_{false}; diff --git a/src/meta/processors/job/TaskDescription.cpp b/src/meta/processors/job/TaskDescription.cpp index 66fde77a510..c7600bb4e31 100644 --- a/src/meta/processors/job/TaskDescription.cpp +++ b/src/meta/processors/job/TaskDescription.cpp @@ -10,7 +10,6 @@ #include "common/time/WallClock.h" #include "common/utils/MetaKeyUtils.h" #include "meta/processors/job/JobStatus.h" -#include "meta/processors/job/JobUtils.h" namespace nebula { namespace meta { @@ -18,11 +17,13 @@ namespace meta { using Status = cpp2::JobStatus; using Host = std::pair; -TaskDescription::TaskDescription(JobID iJob, TaskID iTask, const HostAddr& dst) - : TaskDescription(iJob, iTask, dst.host, dst.port) {} +TaskDescription::TaskDescription(GraphSpaceID space, JobID iJob, TaskID iTask, const HostAddr& dst) + : TaskDescription(space, iJob, iTask, dst.host, dst.port) {} -TaskDescription::TaskDescription(JobID iJob, TaskID iTask, std::string addr, int32_t port) - : iJob_(iJob), +TaskDescription::TaskDescription( + GraphSpaceID space, JobID iJob, TaskID iTask, std::string addr, int32_t port) + : space_(space), + iJob_(iJob), iTask_(iTask), dest_(addr, port), status_(cpp2::JobStatus::RUNNING), @@ -30,91 +31,30 @@ TaskDescription::TaskDescription(JobID iJob, TaskID iTask, std::string addr, int stopTime_(0) {} /* + * task key: + * GraphSpaceID space_; * JobID iJob_; * TaskID iTask_; + * + * task val: * HostAddr dest_; * cpp2::JobStatus status_; * int64_t startTime_; * int64_t stopTime_; * */ TaskDescription::TaskDescription(const folly::StringPiece& key, const folly::StringPiece& val) { - auto tupKey = parseKey(key); - iJob_ = std::get<0>(tupKey); - iTask_ = std::get<1>(tupKey); + auto tupKey = MetaKeyUtils::parseTaskKey(key); + space_ = std::get<0>(tupKey); + iJob_ = std::get<1>(tupKey); + iTask_ = std::get<2>(tupKey); - auto tupVal = parseVal(val); + auto tupVal = MetaKeyUtils::parseTaskVal(val); dest_ = std::get<0>(tupVal); status_ = std::get<1>(tupVal); startTime_ = std::get<2>(tupVal); stopTime_ = std::get<3>(tupVal); } -std::string TaskDescription::taskKey() { - std::string str; - str.reserve(32); - str.append(reinterpret_cast(JobUtil::jobPrefix().data()), - JobUtil::jobPrefix().size()) - .append(reinterpret_cast(&iJob_), sizeof(JobID)) - .append(reinterpret_cast(&iTask_), sizeof(TaskID)); - return str; -} - -std::pair TaskDescription::parseKey(const folly::StringPiece& rawKey) { - auto offset = JobUtil::jobPrefix().size(); - JobID iJob = *reinterpret_cast(rawKey.begin() + offset); - offset += sizeof(JobID); - TaskID iTask = *reinterpret_cast(rawKey.begin() + offset); - return std::make_pair(iJob, iTask); -} - -std::string TaskDescription::archiveKey() { - std::string str; - str.reserve(32); - str.append(reinterpret_cast(JobUtil::archivePrefix().data()), - JobUtil::archivePrefix().size()) - .append(reinterpret_cast(&iJob_), sizeof(JobID)) - .append(reinterpret_cast(&iTask_), sizeof(TaskID)); - return str; -} - -std::string TaskDescription::taskVal() { - std::string str; - str.reserve(128); - str.append(MetaKeyUtils::serializeHostAddr(dest_)) - .append(reinterpret_cast(&status_), sizeof(Status)) - .append(reinterpret_cast(&startTime_), sizeof(startTime_)) - .append(reinterpret_cast(&stopTime_), sizeof(stopTime_)); - return str; -} - -/* - * HostAddr dest_; - * cpp2::JobStatus status_; - * int64_t startTime_; - * int64_t stopTime_; - * */ -// std::tuple -std::tuple TaskDescription::parseVal( - const folly::StringPiece& rawVal) { - size_t offset = 0; - - folly::StringPiece raw = rawVal; - HostAddr host = MetaKeyUtils::deserializeHostAddr(raw); - offset += sizeof(size_t); - offset += host.host.size(); - offset += sizeof(uint32_t); - - auto status = JobUtil::parseFixedVal(rawVal, offset); - offset += sizeof(Status); - - auto tStart = JobUtil::parseFixedVal(rawVal, offset); - offset += sizeof(int64_t); - - auto tStop = JobUtil::parseFixedVal(rawVal, offset); - - return std::make_tuple(host, status, tStart, tStop); -} - /* * ===================================================================================== * | Job Id(TaskId) | Command(Dest) | Status | Start Time | Stop Time | @@ -125,6 +65,7 @@ std::tuple TaskDescription::parseVal( * */ cpp2::TaskDesc TaskDescription::toTaskDesc() { cpp2::TaskDesc ret; + ret.space_id_ref() = space_; ret.job_id_ref() = iJob_; ret.task_id_ref() = iTask_; ret.host_ref() = dest_; diff --git a/src/meta/processors/job/TaskDescription.h b/src/meta/processors/job/TaskDescription.h index afdde9f03c6..9e2bd555d8a 100644 --- a/src/meta/processors/job/TaskDescription.h +++ b/src/meta/processors/job/TaskDescription.h @@ -16,7 +16,11 @@ #include "interface/gen-cpp2/meta_types.h" #include "meta/processors/job/JobStatus.h" +namespace nebula { +namespace meta { + /* + * Task is described as follows: * ===================================================================================== * | Job Id(TaskId) | Command(Dest) | Status | Start Time | Stop Time | * ===================================================================================== @@ -27,65 +31,18 @@ * 11:09:40 | * ------------------------------------------------------------------------------------- * */ - -namespace nebula { -namespace meta { - class TaskDescription { FRIEND_TEST(TaskDescriptionTest, Ctor); - FRIEND_TEST(TaskDescriptionTest, ParseKey); - FRIEND_TEST(TaskDescriptionTest, ParseVal); FRIEND_TEST(TaskDescriptionTest, Dump); FRIEND_TEST(TaskDescriptionTest, Ctor2); FRIEND_TEST(JobManagerTest, ShowJob); friend class JobManager; public: - TaskDescription(JobID iJob, TaskID iTask, const HostAddr& dst); - TaskDescription(JobID iJob, TaskID iTask, std::string addr, int32_t port); + TaskDescription(GraphSpaceID space, JobID iJob, TaskID iTask, const HostAddr& dst); + TaskDescription(GraphSpaceID space, JobID iJob, TaskID iTask, std::string addr, int32_t port); TaskDescription(const folly::StringPiece& key, const folly::StringPiece& val); - /** - * @brief Encoded key going to write to kvstore - * kJobKey+jobid+taskid - * - * @return - */ - std::string taskKey(); - - /** - * @brief Decode jobid and taskid from kv store - * - * @param rawKey - * @return - */ - static std::pair parseKey(const folly::StringPiece& rawKey); - - /** - * @brief Encode task val to write to kvstore - * - * @return - */ - std::string taskVal(); - - /** - * @brief Decode task val from kvstore - * should be - * {host, status, start time, stop time} - * - * @param rawVal - * @return - */ - static std::tuple parseVal( - const folly::StringPiece& rawVal); - - /** - * @brief Encoded key when dba called "backup jobs" - * - * @return - */ - std::string archiveKey(); - /** * @brief * Write out task details in human readable strings @@ -118,6 +75,14 @@ class TaskDescription { */ bool setStatus(cpp2::JobStatus newStatus); + cpp2::JobStatus getStatus() { + return status_; + } + + GraphSpaceID getSpace() { + return space_; + } + JobID getJobId() { return iJob_; } @@ -126,7 +91,20 @@ class TaskDescription { return iTask_; } + HostAddr getHost() { + return dest_; + } + + int64_t getStartTime() { + return startTime_; + } + + int64_t getStopTime() { + return stopTime_; + } + private: + GraphSpaceID space_; JobID iJob_; TaskID iTask_; HostAddr dest_; diff --git a/src/meta/processors/job/ZoneBalanceJobExecutor.cpp b/src/meta/processors/job/ZoneBalanceJobExecutor.cpp index 277a3a662d7..7d628f6a188 100644 --- a/src/meta/processors/job/ZoneBalanceJobExecutor.cpp +++ b/src/meta/processors/job/ZoneBalanceJobExecutor.cpp @@ -11,24 +11,23 @@ #include "common/utils/MetaKeyUtils.h" #include "kvstore/NebulaStore.h" -#include "meta/processors/job/JobUtils.h" namespace nebula { namespace meta { nebula::cpp2::ErrorCode ZoneBalanceJobExecutor::prepare() { - auto spaceRet = getSpaceIdFromName(paras_.back()); - if (!nebula::ok(spaceRet)) { - LOG(INFO) << "Can't find the space: " << paras_.back(); - return nebula::error(spaceRet); + auto spaceRet = spaceExist(); + if (spaceRet != nebula::cpp2::ErrorCode::SUCCEEDED) { + LOG(INFO) << "Can't find the space, spaceId " << space_; + return spaceRet; } - GraphSpaceID spaceId = nebula::value(spaceRet); - nebula::cpp2::ErrorCode rc = spaceInfo_.loadInfo(spaceId, kvstore_); + + nebula::cpp2::ErrorCode rc = spaceInfo_.loadInfo(space_, kvstore_); if (rc != nebula::cpp2::ErrorCode::SUCCEEDED) { return rc; } - lostZones_.reserve(paras_.size() - 1); - for (size_t i = 0; i < paras_.size() - 1; i++) { + lostZones_.reserve(paras_.size()); + for (size_t i = 0; i < paras_.size(); i++) { lostZones_.emplace_back(paras_[i]); } return nebula::cpp2::ErrorCode::SUCCEEDED; diff --git a/src/meta/processors/job/ZoneBalanceJobExecutor.h b/src/meta/processors/job/ZoneBalanceJobExecutor.h index 52207b08987..20658ea98d7 100644 --- a/src/meta/processors/job/ZoneBalanceJobExecutor.h +++ b/src/meta/processors/job/ZoneBalanceJobExecutor.h @@ -25,7 +25,8 @@ class ZoneBalanceJobExecutor : public BalanceJobExecutor { kvstore::KVStore* kvstore, AdminClient* adminClient, const std::vector& params) - : BalanceJobExecutor(jobDescription.getJobId(), kvstore, adminClient, params), + : BalanceJobExecutor( + jobDescription.getSpace(), jobDescription.getJobId(), kvstore, adminClient, params), jobDescription_(jobDescription) {} nebula::cpp2::ErrorCode prepare() override; diff --git a/src/meta/test/BalancerTest.cpp b/src/meta/test/BalancerTest.cpp index 2e3434ab0f7..d84ef1fbd9f 100644 --- a/src/meta/test/BalancerTest.cpp +++ b/src/meta/test/BalancerTest.cpp @@ -46,21 +46,22 @@ TEST(BalanceTest, BalanceTaskTest) { DefaultValue>::SetFactory( [] { return folly::Future(Status::OK()); }); + GraphSpaceID space = 0; { StrictMock client; - EXPECT_CALL(client, checkPeers(0, 0)).Times(2); - EXPECT_CALL(client, transLeader(0, 0, src, _)).Times(1); - EXPECT_CALL(client, addPart(0, 0, dst, true)).Times(1); - EXPECT_CALL(client, addLearner(0, 0, dst)).Times(1); - EXPECT_CALL(client, waitingForCatchUpData(0, 0, dst)).Times(1); - EXPECT_CALL(client, memberChange(0, 0, dst, true)).Times(1); - EXPECT_CALL(client, memberChange(0, 0, src, false)).Times(1); - EXPECT_CALL(client, updateMeta(0, 0, src, dst)).Times(1); - EXPECT_CALL(client, removePart(0, 0, src)).Times(1); + EXPECT_CALL(client, checkPeers(space, 0)).Times(2); + EXPECT_CALL(client, transLeader(space, 0, src, _)).Times(1); + EXPECT_CALL(client, addPart(space, 0, dst, true)).Times(1); + EXPECT_CALL(client, addLearner(space, 0, dst)).Times(1); + EXPECT_CALL(client, waitingForCatchUpData(space, 0, dst)).Times(1); + EXPECT_CALL(client, memberChange(space, 0, dst, true)).Times(1); + EXPECT_CALL(client, memberChange(space, 0, src, false)).Times(1); + EXPECT_CALL(client, updateMeta(space, 0, src, dst)).Times(1); + EXPECT_CALL(client, removePart(space, 0, src)).Times(1); folly::Baton b; BalanceTask task( - testJobId.fetch_add(1, std::memory_order_relaxed), 0, 0, src, dst, kv, &client); + testJobId.fetch_add(1, std::memory_order_relaxed), space, 0, src, dst, kv, &client); task.onFinished_ = [&]() { LOG(INFO) << "Task finished!"; EXPECT_EQ(BalanceTaskResult::SUCCEEDED, task.ret_); @@ -79,7 +80,7 @@ TEST(BalanceTest, BalanceTaskTest) { folly::Baton b; BalanceTask task( - testJobId.fetch_add(1, std::memory_order_relaxed), 0, 0, src, dst, kv, &client); + testJobId.fetch_add(1, std::memory_order_relaxed), space, 0, src, dst, kv, &client); task.onFinished_ = []() { LOG(FATAL) << "We should not reach here!"; }; task.onError_ = [&]() { LOG(INFO) << "Error happens!"; @@ -463,14 +464,15 @@ void showHostLoading(kvstore::KVStore* kv, GraphSpaceID spaceId) { } TEST(BalanceTest, DispatchTasksTest) { + GraphSpaceID space = 0; { FLAGS_task_concurrency = 10; JobDescription jd( - testJobId.fetch_add(1, std::memory_order_relaxed), cpp2::JobType::DATA_BALANCE, {}); + space, testJobId.fetch_add(1, std::memory_order_relaxed), cpp2::JobType::DATA_BALANCE, {}); BalancePlan plan(jd, nullptr, nullptr); for (int i = 0; i < 20; i++) { BalanceTask task(0, - 0, + space, 0, HostAddr(std::to_string(i), 0), HostAddr(std::to_string(i), 1), @@ -479,7 +481,7 @@ TEST(BalanceTest, DispatchTasksTest) { plan.addTask(std::move(task)); } plan.dispatchTasks(); - // All tasks is about space 0, part 0. + // All tasks is about space 1, part 0. // So they will be dispatched into the same bucket. ASSERT_EQ(1, plan.buckets_.size()); ASSERT_EQ(20, plan.buckets_[0].size()); @@ -487,11 +489,11 @@ TEST(BalanceTest, DispatchTasksTest) { { FLAGS_task_concurrency = 10; JobDescription jd( - testJobId.fetch_add(1, std::memory_order_relaxed), cpp2::JobType::DATA_BALANCE, {}); + space, testJobId.fetch_add(1, std::memory_order_relaxed), cpp2::JobType::DATA_BALANCE, {}); BalancePlan plan(jd, nullptr, nullptr); for (int i = 0; i < 5; i++) { BalanceTask task(0, - 0, + space, i, HostAddr(std::to_string(i), 0), HostAddr(std::to_string(i), 1), @@ -508,11 +510,11 @@ TEST(BalanceTest, DispatchTasksTest) { { FLAGS_task_concurrency = 20; JobDescription jd( - testJobId.fetch_add(1, std::memory_order_relaxed), cpp2::JobType::DATA_BALANCE, {}); + space, testJobId.fetch_add(1, std::memory_order_relaxed), cpp2::JobType::DATA_BALANCE, {}); BalancePlan plan(jd, nullptr, nullptr); for (int i = 0; i < 5; i++) { BalanceTask task(0, - 0, + space, i, HostAddr(std::to_string(i), 0), HostAddr(std::to_string(i), 1), @@ -522,7 +524,7 @@ TEST(BalanceTest, DispatchTasksTest) { } for (int i = 0; i < 10; i++) { BalanceTask task(0, - 0, + space, i, HostAddr(std::to_string(i), 2), HostAddr(std::to_string(i), 3), @@ -551,6 +553,7 @@ TEST(BalanceTest, BalancePlanTest) { hosts.emplace_back(std::to_string(i), 0); hosts.emplace_back(std::to_string(i), 1); } + GraphSpaceID space = 0; DefaultValue>::SetFactory( [] { return folly::Future(Status::OK()); }); @@ -558,14 +561,14 @@ TEST(BalanceTest, BalancePlanTest) { LOG(INFO) << "Test with all tasks succeeded, only one bucket!"; NiceMock client; JobDescription jd( - testJobId.fetch_add(1, std::memory_order_relaxed), cpp2::JobType::DATA_BALANCE, {}); + space, testJobId.fetch_add(1, std::memory_order_relaxed), cpp2::JobType::DATA_BALANCE, {}); BalancePlan plan(jd, kv, &client); TestUtils::createSomeHosts(kv, hosts); TestUtils::registerHB(kv, hosts); for (int i = 0; i < 10; i++) { BalanceTask task(plan.id(), - 0, + space, 0, HostAddr(std::to_string(i), 0), HostAddr(std::to_string(i), 1), @@ -590,13 +593,13 @@ TEST(BalanceTest, BalancePlanTest) { LOG(INFO) << "Test with all tasks succeeded, 10 buckets!"; NiceMock client; JobDescription jd( - testJobId.fetch_add(1, std::memory_order_relaxed), cpp2::JobType::DATA_BALANCE, {}); + space, testJobId.fetch_add(1, std::memory_order_relaxed), cpp2::JobType::DATA_BALANCE, {}); BalancePlan plan(jd, kv, &client); TestUtils::registerHB(kv, hosts); for (int i = 0; i < 10; i++) { BalanceTask task(plan.id(), - 0, + space, i, HostAddr(std::to_string(i), 0), HostAddr(std::to_string(i), 1), @@ -622,13 +625,13 @@ TEST(BalanceTest, BalancePlanTest) { { LOG(INFO) << "Test with one task failed, 10 buckets"; JobDescription jd( - testJobId.fetch_add(1, std::memory_order_relaxed), cpp2::JobType::DATA_BALANCE, {}); + space, testJobId.fetch_add(1, std::memory_order_relaxed), cpp2::JobType::DATA_BALANCE, {}); BalancePlan plan(jd, kv, nullptr); NiceMock client1, client2; { for (int i = 0; i < 9; i++) { BalanceTask task(plan.id(), - 0, + space, i, HostAddr(std::to_string(i), 0), HostAddr(std::to_string(i), 1), @@ -641,7 +644,7 @@ TEST(BalanceTest, BalancePlanTest) { EXPECT_CALL(client2, transLeader(_, _, _, _)) .Times(1) .WillOnce(Return(ByMove(folly::Future(Status::Error("Transfer failed"))))); - BalanceTask task(plan.id(), 0, 9, HostAddr("9", 0), HostAddr("9", 1), kv, &client2); + BalanceTask task(plan.id(), space, 9, HostAddr("9", 0), HostAddr("9", 1), kv, &client2); plan.addTask(std::move(task)); } TestUtils::registerHB(kv, hosts); @@ -735,10 +738,13 @@ void verifyZonePartNum(kvstore::KVStore* kv, EXPECT_EQ(zoneNum, zones); } -JobDescription makeJobDescription(kvstore::KVStore* kv, cpp2::JobType jobType) { - JobDescription jd(testJobId.fetch_add(1, std::memory_order_relaxed), jobType, {}); +JobDescription makeJobDescription(GraphSpaceID space, kvstore::KVStore* kv, cpp2::JobType jobType) { + JobDescription jd(space, testJobId.fetch_add(1, std::memory_order_relaxed), jobType, {}); std::vector data; - data.emplace_back(jd.jobKey(), jd.jobVal()); + auto jobKey = MetaKeyUtils::jobKey(jd.getSpace(), jd.getJobId()); + auto jobVal = MetaKeyUtils::jobVal( + jd.getJobType(), jd.getParas(), jd.getStatus(), jd.getStartTime(), jd.getStopTime()); + data.emplace_back(jobKey, jobVal); folly::Baton baton; kv->asyncMultiPut(0, 0, std::move(data), [&](nebula::cpp2::ErrorCode code) { ASSERT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, code); @@ -752,6 +758,7 @@ TEST(BalanceTest, NormalZoneTest) { fs::TempDir rootPath("/tmp/NormalZoneTest.XXXXXX"); auto store = MockCluster::initMetaKV(rootPath.path()); auto* kv = dynamic_cast(store.get()); + GraphSpaceID space = 1; FLAGS_heartbeat_interval_secs = 1; TestUtils::assembleSpaceWithZone(kv, 1, 8, 3, 8, 24); std::unordered_map partCount; @@ -759,9 +766,9 @@ TEST(BalanceTest, NormalZoneTest) { DefaultValue>::SetFactory( [] { return folly::Future(Status::OK()); }); NiceMock client; - JobDescription jd = makeJobDescription(kv, cpp2::JobType::ZONE_BALANCE); + JobDescription jd = makeJobDescription(space, kv, cpp2::JobType::ZONE_BALANCE); ZoneBalanceJobExecutor balancer(jd, kv, &client, {}); - balancer.spaceInfo_.loadInfo(1, kv); + balancer.spaceInfo_.loadInfo(space, kv); folly::Baton baton; balancer.setFinishCallBack([&](meta::cpp2::JobStatus) { baton.post(); @@ -789,15 +796,17 @@ TEST(BalanceTest, NormalDataTest) { auto store = MockCluster::initMetaKV(rootPath.path()); auto* kv = dynamic_cast(store.get()); FLAGS_heartbeat_interval_secs = 1; - TestUtils::assembleSpaceWithZone(kv, 1, 8, 3, 1, 8); + GraphSpaceID space = 1; + + TestUtils::assembleSpaceWithZone(kv, space, 8, 3, 1, 8); std::unordered_map partCount; DefaultValue>::SetFactory( [] { return folly::Future(Status::OK()); }); NiceMock client; - JobDescription jd = makeJobDescription(kv, cpp2::JobType::DATA_BALANCE); + JobDescription jd = makeJobDescription(space, kv, cpp2::JobType::DATA_BALANCE); DataBalanceJobExecutor balancer(jd, kv, &client, {}); - balancer.spaceInfo_.loadInfo(1, kv); + balancer.spaceInfo_.loadInfo(space, kv); auto ret = balancer.executeInternal(); EXPECT_EQ(Status::OK(), ret.value()); balancer.finish(); @@ -818,11 +827,13 @@ TEST(BalanceTest, RecoveryTest) { fs::TempDir rootPath("/tmp/TryToRecoveryTest.XXXXXX"); auto store = MockCluster::initMetaKV(rootPath.path()); auto* kv = dynamic_cast(store.get()); - TestUtils::assembleSpaceWithZone(kv, 1, 24, 1, 1, 8); + GraphSpaceID space = 1; + + TestUtils::assembleSpaceWithZone(kv, space, 24, 1, 1, 8); DefaultValue>::SetFactory( [] { return folly::Future(Status::OK()); }); NiceMock client; - EXPECT_CALL(client, waitingForCatchUpData(_, _, _)) + EXPECT_CALL(client, waitingForCatchUpData(space, _, _)) .Times(12) .WillOnce(Return(ByMove(folly::Future(Status::Error("catch up failed"))))) .WillOnce(Return(ByMove(folly::Future(Status::Error("catch up failed"))))) @@ -831,9 +842,9 @@ TEST(BalanceTest, RecoveryTest) { .WillOnce(Return(ByMove(folly::Future(Status::Error("catch up failed"))))) .WillOnce(Return(ByMove(folly::Future(Status::Error("catch up failed"))))); - JobDescription jd = makeJobDescription(kv, cpp2::JobType::DATA_BALANCE); + JobDescription jd = makeJobDescription(space, kv, cpp2::JobType::DATA_BALANCE); DataBalanceJobExecutor balancer(jd, kv, &client, {}); - balancer.spaceInfo_.loadInfo(1, kv); + balancer.spaceInfo_.loadInfo(space, kv); balancer.lostHosts_ = {{"127.0.0.1", 1}, {"127.0.0.1", 8}}; folly::Baton baton; balancer.setFinishCallBack([&](meta::cpp2::JobStatus) { @@ -873,8 +884,10 @@ TEST(BalanceTest, StopPlanTest) { auto store = MockCluster::initMetaKV(rootPath.path()); auto* kv = dynamic_cast(store.get()); FLAGS_heartbeat_interval_secs = 1; + GraphSpaceID space = 1; + TestUtils::createSomeHosts(kv); - TestUtils::assembleSpaceWithZone(kv, 1, 24, 3, 5, 5); + TestUtils::assembleSpaceWithZone(kv, space, 24, 3, 5, 5); DefaultValue>::SetFactory( [] { return folly::Future(Status::OK()); }); NiceMock delayClient; @@ -897,9 +910,9 @@ TEST(BalanceTest, StopPlanTest) { .WillOnce( Return(ByMove(folly::makeFuture(Status::OK()).delayed(std::chrono::seconds(3))))); FLAGS_task_concurrency = 8; - JobDescription jd = makeJobDescription(kv, cpp2::JobType::DATA_BALANCE); + JobDescription jd = makeJobDescription(space, kv, cpp2::JobType::DATA_BALANCE); ZoneBalanceJobExecutor balancer(jd, kv, &delayClient, {}); - balancer.spaceInfo_.loadInfo(1, kv); + balancer.spaceInfo_.loadInfo(space, kv); balancer.lostZones_ = {"4", "5"}; folly::Baton baton; balancer.setFinishCallBack([&](meta::cpp2::JobStatus) { @@ -983,14 +996,16 @@ TEST(BalanceTest, SimpleLeaderBalancePlanTest) { auto* kv = dynamic_cast(store.get()); std::vector hosts = {{"0", 0}, {"1", 1}, {"2", 2}}; TestUtils::createSomeHosts(kv, hosts); + GraphSpaceID space = 1; + // 9 partition in space 1, 3 replica, 3 hosts - TestUtils::assembleSpace(kv, 1, 9, 3, 3); + TestUtils::assembleSpace(kv, space, 9, 3, 3); DefaultValue>::SetFactory( [] { return folly::Future(Status::OK()); }); NiceMock client; LeaderBalanceJobExecutor balancer( - testJobId.fetch_add(1, std::memory_order_relaxed), kv, &client, {}); + space, testJobId.fetch_add(1, std::memory_order_relaxed), kv, &client, {}); { HostLeaderMap hostLeaderMap; hostLeaderMap[HostAddr("0", 0)][1] = {1, 2, 3, 4, 5}; @@ -1000,14 +1015,14 @@ TEST(BalanceTest, SimpleLeaderBalancePlanTest) { LeaderBalancePlan plan; auto leaderBalanceResult = - balancer.buildLeaderBalancePlan(&hostLeaderMap, 1, 3, false, plan, false); + balancer.buildLeaderBalancePlan(&hostLeaderMap, space, 3, false, plan, false); ASSERT_TRUE(nebula::ok(leaderBalanceResult) && nebula::value(leaderBalanceResult)); verifyLeaderBalancePlan(hostLeaderMap, plan, 3, 3); // check two plan build are same LeaderBalancePlan tempPlan; auto tempLeaderBalanceResult = - balancer.buildLeaderBalancePlan(&tempMap, 1, 3, false, tempPlan, false); + balancer.buildLeaderBalancePlan(&tempMap, space, 3, false, tempPlan, false); ASSERT_TRUE(nebula::ok(tempLeaderBalanceResult) && nebula::value(tempLeaderBalanceResult)); verifyLeaderBalancePlan(tempMap, tempPlan, 3, 3); @@ -1024,7 +1039,7 @@ TEST(BalanceTest, SimpleLeaderBalancePlanTest) { LeaderBalancePlan plan; auto leaderBalanceResult = - balancer.buildLeaderBalancePlan(&hostLeaderMap, 1, 3, false, plan, false); + balancer.buildLeaderBalancePlan(&hostLeaderMap, space, 3, false, plan, false); ASSERT_TRUE(nebula::ok(leaderBalanceResult) && nebula::value(leaderBalanceResult)); verifyLeaderBalancePlan(hostLeaderMap, plan, 3, 3); } @@ -1036,7 +1051,7 @@ TEST(BalanceTest, SimpleLeaderBalancePlanTest) { LeaderBalancePlan plan; auto leaderBalanceResult = - balancer.buildLeaderBalancePlan(&hostLeaderMap, 1, 3, false, plan, false); + balancer.buildLeaderBalancePlan(&hostLeaderMap, space, 3, false, plan, false); ASSERT_TRUE(nebula::ok(leaderBalanceResult) && nebula::value(leaderBalanceResult)); verifyLeaderBalancePlan(hostLeaderMap, plan, 3, 3); } @@ -1048,7 +1063,7 @@ TEST(BalanceTest, SimpleLeaderBalancePlanTest) { LeaderBalancePlan plan; auto leaderBalanceResult = - balancer.buildLeaderBalancePlan(&hostLeaderMap, 1, 3, false, plan, false); + balancer.buildLeaderBalancePlan(&hostLeaderMap, space, 3, false, plan, false); ASSERT_TRUE(nebula::ok(leaderBalanceResult) && nebula::value(leaderBalanceResult)); verifyLeaderBalancePlan(hostLeaderMap, plan, 3, 3); } @@ -1060,15 +1075,17 @@ TEST(BalanceTest, IntersectHostsLeaderBalancePlanTest) { auto* kv = dynamic_cast(store.get()); std::vector hosts = {{"0", 0}, {"1", 1}, {"2", 2}, {"3", 3}, {"4", 4}, {"5", 5}}; TestUtils::createSomeHosts(kv, hosts); + GraphSpaceID space = 1; + // 7 partition in space 1, 3 replica, 6 hosts, so not all hosts have // intersection parts - TestUtils::assembleSpace(kv, 1, 7, 3, 6); + TestUtils::assembleSpace(kv, space, 7, 3, 6); DefaultValue>::SetFactory( [] { return folly::Future(Status::OK()); }); NiceMock client; LeaderBalanceJobExecutor balancer( - testJobId.fetch_add(1, std::memory_order_relaxed), kv, &client, {}); + space, testJobId.fetch_add(1, std::memory_order_relaxed), kv, &client, {}); { HostLeaderMap hostLeaderMap; @@ -1078,11 +1095,11 @@ TEST(BalanceTest, IntersectHostsLeaderBalancePlanTest) { hostLeaderMap[HostAddr("3", 3)][1] = {1, 2, 3, 7}; hostLeaderMap[HostAddr("4", 4)][1] = {}; hostLeaderMap[HostAddr("5", 5)][1] = {}; - showHostLoading(kv, 1); + showHostLoading(kv, space); LeaderBalancePlan plan; auto leaderBalanceResult = - balancer.buildLeaderBalancePlan(&hostLeaderMap, 1, 3, false, plan, false); + balancer.buildLeaderBalancePlan(&hostLeaderMap, space, 3, false, plan, false); ASSERT_TRUE(nebula::ok(leaderBalanceResult) && nebula::value(leaderBalanceResult)); verifyLeaderBalancePlan(hostLeaderMap, plan, 1, 2); } @@ -1097,7 +1114,7 @@ TEST(BalanceTest, IntersectHostsLeaderBalancePlanTest) { LeaderBalancePlan plan; auto leaderBalanceResult = - balancer.buildLeaderBalancePlan(&hostLeaderMap, 1, 3, false, plan, false); + balancer.buildLeaderBalancePlan(&hostLeaderMap, space, 3, false, plan, false); ASSERT_TRUE(nebula::ok(leaderBalanceResult) && nebula::value(leaderBalanceResult)); verifyLeaderBalancePlan(hostLeaderMap, plan, 1, 2); } @@ -1112,7 +1129,7 @@ TEST(BalanceTest, IntersectHostsLeaderBalancePlanTest) { LeaderBalancePlan plan; auto leaderBalanceResult = - balancer.buildLeaderBalancePlan(&hostLeaderMap, 1, 3, false, plan, false); + balancer.buildLeaderBalancePlan(&hostLeaderMap, space, 3, false, plan, false); ASSERT_TRUE(nebula::ok(leaderBalanceResult) && nebula::value(leaderBalanceResult)); verifyLeaderBalancePlan(hostLeaderMap, plan, 1, 2); } @@ -1127,7 +1144,7 @@ TEST(BalanceTest, IntersectHostsLeaderBalancePlanTest) { LeaderBalancePlan plan; auto leaderBalanceResult = - balancer.buildLeaderBalancePlan(&hostLeaderMap, 1, 3, false, plan, false); + balancer.buildLeaderBalancePlan(&hostLeaderMap, space, 3, false, plan, false); ASSERT_TRUE(nebula::ok(leaderBalanceResult) && nebula::value(leaderBalanceResult)); verifyLeaderBalancePlan(hostLeaderMap, plan, 1, 2); } @@ -1142,7 +1159,7 @@ TEST(BalanceTest, IntersectHostsLeaderBalancePlanTest) { LeaderBalancePlan plan; auto leaderBalanceResult = - balancer.buildLeaderBalancePlan(&hostLeaderMap, 1, 3, false, plan, false); + balancer.buildLeaderBalancePlan(&hostLeaderMap, space, 3, false, plan, false); ASSERT_TRUE(nebula::ok(leaderBalanceResult) && nebula::value(leaderBalanceResult)); verifyLeaderBalancePlan(hostLeaderMap, plan, 1, 2); } @@ -1153,6 +1170,7 @@ TEST(BalanceTest, ManyHostsLeaderBalancePlanTest) { auto store = MockCluster::initMetaKV(rootPath.path()); auto* kv = dynamic_cast(store.get()); FLAGS_heartbeat_interval_secs = 1; + GraphSpaceID space = 1; int partCount = 99999; int replica = 3; @@ -1162,7 +1180,7 @@ TEST(BalanceTest, ManyHostsLeaderBalancePlanTest) { hosts.emplace_back(std::to_string(i), i); } TestUtils::createSomeHosts(kv, hosts); - TestUtils::assembleSpace(kv, 1, partCount, replica, hostCount); + TestUtils::assembleSpace(kv, space, partCount, replica, hostCount); float avgLoad = static_cast(partCount) / hostCount; int32_t minLoad = std::floor(avgLoad * (1 - FLAGS_leader_balance_deviation)); @@ -1172,7 +1190,7 @@ TEST(BalanceTest, ManyHostsLeaderBalancePlanTest) { [] { return folly::Future(Status::OK()); }); NiceMock client; LeaderBalanceJobExecutor balancer( - testJobId.fetch_add(1, std::memory_order_relaxed), kv, &client, {}); + space, testJobId.fetch_add(1, std::memory_order_relaxed), kv, &client, {}); // check several times if they are balanced for (int count = 0; count < 1; count++) { @@ -1190,7 +1208,8 @@ TEST(BalanceTest, ManyHostsLeaderBalancePlanTest) { } LeaderBalancePlan plan; - auto leaderBalanceResult = balancer.buildLeaderBalancePlan(&hostLeaderMap, 1, 3, false, plan); + auto leaderBalanceResult = + balancer.buildLeaderBalancePlan(&hostLeaderMap, space, 3, false, plan); ASSERT_TRUE(nebula::ok(leaderBalanceResult) && nebula::value(leaderBalanceResult)); verifyLeaderBalancePlan(hostLeaderMap, plan, minLoad, maxLoad); } @@ -1202,7 +1221,8 @@ TEST(BalanceTest, LeaderBalanceTest) { auto* kv = dynamic_cast(store.get()); std::vector hosts = {{"0", 0}, {"1", 1}, {"2", 2}}; TestUtils::createSomeHosts(kv, hosts); - TestUtils::assembleSpace(kv, 1, 9, 3, 3); + GraphSpaceID space = 1; + TestUtils::assembleSpace(kv, space, 9, 3, 3); DefaultValue>::SetFactory( [] { return folly::Future(Status::OK()); }); @@ -1216,7 +1236,7 @@ TEST(BalanceTest, LeaderBalanceTest) { Return(ByMove(folly::Future(Status::OK()))))); LeaderBalanceJobExecutor balancer( - testJobId.fetch_add(1, std::memory_order_relaxed), kv, &client, {}); + space, testJobId.fetch_add(1, std::memory_order_relaxed), kv, &client, {}); auto ret = balancer.executeInternal(); ASSERT_EQ(Status::OK(), ret.value()); } @@ -1226,6 +1246,8 @@ TEST(BalanceTest, LeaderBalanceWithZoneTest) { auto store = MockCluster::initMetaKV(rootPath.path()); auto* kv = dynamic_cast(store.get()); FLAGS_heartbeat_interval_secs = 1; + GraphSpaceID space = 0; + std::vector hosts; for (int i = 0; i < 9; i++) { hosts.emplace_back(std::to_string(i), i); @@ -1254,7 +1276,8 @@ TEST(BalanceTest, LeaderBalanceWithZoneTest) { processor->process(req); auto resp = std::move(f).get(); ASSERT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, resp.get_code()); - ASSERT_EQ(1, resp.get_id().get_space_id()); + space = resp.get_id().get_space_id(); + ASSERT_EQ(1, space); } sleep(1); @@ -1262,7 +1285,7 @@ TEST(BalanceTest, LeaderBalanceWithZoneTest) { [] { return folly::Future(Status::OK()); }); NiceMock client; LeaderBalanceJobExecutor balancer( - testJobId.fetch_add(1, std::memory_order_relaxed), kv, &client, {}); + space, testJobId.fetch_add(1, std::memory_order_relaxed), kv, &client, {}); { HostLeaderMap hostLeaderMap; hostLeaderMap[HostAddr("0", 0)][1] = {1, 3, 5, 7}; @@ -1274,7 +1297,7 @@ TEST(BalanceTest, LeaderBalanceWithZoneTest) { LeaderBalancePlan plan; auto leaderBalanceResult = - balancer.buildLeaderBalancePlan(&hostLeaderMap, 1, 3, true, plan, true); + balancer.buildLeaderBalancePlan(&hostLeaderMap, space, 3, true, plan, true); ASSERT_TRUE(nebula::ok(leaderBalanceResult) && nebula::value(leaderBalanceResult)); verifyLeaderBalancePlan(hostLeaderMap, plan, 1, 2); } @@ -1289,7 +1312,7 @@ TEST(BalanceTest, LeaderBalanceWithZoneTest) { LeaderBalancePlan plan; auto leaderBalanceResult = - balancer.buildLeaderBalancePlan(&hostLeaderMap, 1, 3, true, plan, true); + balancer.buildLeaderBalancePlan(&hostLeaderMap, space, 3, true, plan, true); ASSERT_TRUE(nebula::ok(leaderBalanceResult) && nebula::value(leaderBalanceResult)); verifyLeaderBalancePlan(hostLeaderMap, plan, 1, 2); } @@ -1300,6 +1323,7 @@ TEST(BalanceTest, LeaderBalanceWithLargerZoneTest) { auto store = MockCluster::initMetaKV(rootPath.path()); auto* kv = dynamic_cast(store.get()); FLAGS_heartbeat_interval_secs = 1; + GraphSpaceID space = 0; std::vector hosts; for (int i = 0; i < 15; i++) { hosts.emplace_back(std::to_string(i), i); @@ -1332,6 +1356,7 @@ TEST(BalanceTest, LeaderBalanceWithLargerZoneTest) { processor->process(req); auto resp = std::move(f).get(); ASSERT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, resp.get_code()); + space = resp.get_id().get_space_id(); ASSERT_EQ(1, resp.get_id().get_space_id()); } @@ -1340,7 +1365,7 @@ TEST(BalanceTest, LeaderBalanceWithLargerZoneTest) { [] { return folly::Future(Status::OK()); }); NiceMock client; LeaderBalanceJobExecutor balancer( - testJobId.fetch_add(1, std::memory_order_relaxed), kv, &client, {}); + space, testJobId.fetch_add(1, std::memory_order_relaxed), kv, &client, {}); { HostLeaderMap hostLeaderMap; hostLeaderMap[HostAddr("0", 0)][1] = {1, 5, 8}; @@ -1355,7 +1380,7 @@ TEST(BalanceTest, LeaderBalanceWithLargerZoneTest) { LeaderBalancePlan plan; auto leaderBalanceResult = - balancer.buildLeaderBalancePlan(&hostLeaderMap, 1, 3, true, plan, true); + balancer.buildLeaderBalancePlan(&hostLeaderMap, space, 3, true, plan, true); ASSERT_TRUE(nebula::ok(leaderBalanceResult) && nebula::value(leaderBalanceResult)); verifyLeaderBalancePlan(hostLeaderMap, plan, 0, 1); } @@ -1366,6 +1391,8 @@ TEST(BalanceTest, LeaderBalanceWithComplexZoneTest) { auto store = MockCluster::initMetaKV(rootPath.path()); auto* kv = dynamic_cast(store.get()); FLAGS_heartbeat_interval_secs = 1; + GraphSpaceID space = 3; + std::vector hosts; for (int i = 0; i < 18; i++) { hosts.emplace_back(std::to_string(i), i); @@ -1445,7 +1472,7 @@ TEST(BalanceTest, LeaderBalanceWithComplexZoneTest) { [] { return folly::Future(Status::OK()); }); NiceMock client; LeaderBalanceJobExecutor balancer( - testJobId.fetch_add(1, std::memory_order_relaxed), kv, &client, {}); + space, testJobId.fetch_add(1, std::memory_order_relaxed), kv, &client, {}); { HostLeaderMap hostLeaderMap; diff --git a/src/meta/test/GetStatsTest.cpp b/src/meta/test/GetStatsTest.cpp index 36a6c8a2d69..c8978be803f 100644 --- a/src/meta/test/GetStatsTest.cpp +++ b/src/meta/test/GetStatsTest.cpp @@ -12,7 +12,6 @@ #include "kvstore/Common.h" #include "meta/processors/job/GetStatsProcessor.h" #include "meta/processors/job/JobManager.h" -#include "meta/processors/job/JobUtils.h" #include "meta/test/MockAdminClient.h" #include "meta/test/TestUtils.h" @@ -26,14 +25,14 @@ using ::testing::NiceMock; using ::testing::Return; using ::testing::SetArgPointee; -std::string toTempKey(int32_t space, int32_t jobId) { +std::string toTempKey(GraphSpaceID space, JobID jobId) { std::string key = MetaKeyUtils::statsKey(space); - return key.append(reinterpret_cast(&jobId), sizeof(int32_t)); + return key.append(reinterpret_cast(&jobId), sizeof(JobID)); } void copyData(kvstore::KVStore* kv, - int32_t space, - int32_t part, + GraphSpaceID space, + PartitionID part, const std::string& keySrc, const std::string& keyDst) { std::string val; @@ -45,19 +44,20 @@ void copyData(kvstore::KVStore* kv, b.wait(); } -void genTempData(int32_t spaceId, int jobId, kvstore::KVStore* kv) { +void genTempData(GraphSpaceID spaceId, JobID jobId, kvstore::KVStore* kv) { auto statsKey = MetaKeyUtils::statsKey(spaceId); auto tempKey = toTempKey(spaceId, jobId); copyData(kv, 0, 0, statsKey, tempKey); } struct JobCallBack { - JobCallBack(JobManager* jobMgr, int job, int task, int n) - : jobMgr_(jobMgr), jobId_(job), taskId_(task), n_(n) {} + JobCallBack(JobManager* jobMgr, GraphSpaceID space, JobID job, TaskID task, int n) + : jobMgr_(jobMgr), spaceId_(space), jobId_(job), taskId_(task), n_(n) {} folly::Future operator()() { cpp2::ReportTaskReq req; req.code_ref() = nebula::cpp2::ErrorCode::SUCCEEDED; + req.space_id_ref() = spaceId_; req.job_id_ref() = jobId_; req.task_id_ref() = taskId_; @@ -67,14 +67,15 @@ struct JobCallBack { item.space_vertices_ref() = 2 * n_; item.space_edges_ref() = 2 * n_; req.stats_ref() = item; - jobMgr_->muJobFinished_.unlock(); + jobMgr_->muJobFinished_[spaceId_].unlock(); jobMgr_->reportTaskFinish(req); return folly::Future(Status::OK()); } JobManager* jobMgr_{nullptr}; - int32_t jobId_{-1}; - int32_t taskId_{-1}; + GraphSpaceID spaceId_{-1}; + JobID jobId_{-1}; + TaskID taskId_{-1}; int32_t n_{-1}; }; @@ -101,10 +102,9 @@ class GetStatsTest : public ::testing::Test { rootPath_.reset(); } - // using AllLeaders = std::unordered_map>; + // using AllLeaders = std::unordered_map> using FakeHost = std::pair; - FakeHost fakeHost(std::string ip, int port, int space, std::vector parts) { + FakeHost fakeHost(std::string ip, int port, GraphSpaceID space, std::vector parts) { HostAddr host(ip, port); ActiveHostsMan::AllLeaders leaders; for (auto i = 0U; i != parts.size(); ++i) { @@ -122,23 +122,32 @@ class GetStatsTest : public ::testing::Test { TEST_F(GetStatsTest, StatsJob) { ASSERT_TRUE(TestUtils::createSomeHosts(kv_.get())); - TestUtils::assembleSpace(kv_.get(), 1, 1); GraphSpaceID spaceId = 1; - std::vector paras{"test_space"}; - JobDescription statsJob(12, cpp2::JobType::STATS, paras); + int32_t partNum = 1; + JobID jobId1 = 12; + TestUtils::assembleSpace(kv_.get(), spaceId, partNum); + + JobDescription statsJob(spaceId, jobId1, cpp2::JobType::STATS); NiceMock adminClient; jobMgr->adminClient_ = &adminClient; - auto rc = jobMgr->save(statsJob.jobKey(), statsJob.jobVal()); + auto jobKey1 = MetaKeyUtils::jobKey(statsJob.getSpace(), statsJob.getJobId()); + auto jobVal1 = MetaKeyUtils::jobVal(statsJob.getJobType(), + statsJob.getParas(), + statsJob.getStatus(), + statsJob.getStartTime(), + statsJob.getStopTime()); + auto rc = jobMgr->save(std::move(jobKey1), std::move(jobVal1)); ASSERT_EQ(rc, nebula::cpp2::ErrorCode::SUCCEEDED); { // Job is not executed, job status is QUEUE. // Stats data does not exist. - auto job1Ret = JobDescription::loadJobDescription(statsJob.id_, kv_.get()); + auto job1Ret = + JobDescription::loadJobDescription(statsJob.getSpace(), statsJob.getJobId(), kv_.get()); ASSERT_TRUE(nebula::ok(job1Ret)); - auto job1 = nebula::value(job1Ret); - ASSERT_EQ(statsJob.id_, job1.id_); - ASSERT_EQ(cpp2::JobStatus::QUEUE, job1.status_); + auto job11 = nebula::value(job1Ret); + ASSERT_EQ(statsJob.getJobId(), job11.getJobId()); + ASSERT_EQ(cpp2::JobStatus::QUEUE, job11.getStatus()); cpp2::GetStatsReq req; req.space_id_ref() = spaceId; @@ -154,9 +163,15 @@ TEST_F(GetStatsTest, StatsJob) { auto ret = kv_->get(kDefaultSpaceId, kDefaultPartId, key, &val); ASSERT_NE(nebula::cpp2::ErrorCode::SUCCEEDED, ret); - auto res = job1.setStatus(cpp2::JobStatus::RUNNING); + auto res = job11.setStatus(cpp2::JobStatus::RUNNING); ASSERT_TRUE(res); - auto retsav = jobMgr->save(job1.jobKey(), job1.jobVal()); + auto jobKey2 = MetaKeyUtils::jobKey(job11.getSpace(), job11.getJobId()); + auto jobVal2 = MetaKeyUtils::jobVal(job11.getJobType(), + job11.getParas(), + job11.getStatus(), + job11.getStartTime(), + job11.getStopTime()); + auto retsav = jobMgr->save(std::move(jobKey2), std::move(jobVal2)); ASSERT_EQ(retsav, nebula::cpp2::ErrorCode::SUCCEEDED); } @@ -169,19 +184,26 @@ TEST_F(GetStatsTest, StatsJob) { // JobManager does not set the job finished status in RunJobInternal function. // But set stats data. statsJob.setStatus(cpp2::JobStatus::FINISHED); - jobMgr->save(statsJob.jobKey(), statsJob.jobVal()); - auto jobId = statsJob.getJobId(); + auto jobKey3 = MetaKeyUtils::jobKey(statsJob.getSpace(), statsJob.getJobId()); + auto jobVal3 = MetaKeyUtils::jobVal(statsJob.getJobType(), + statsJob.getParas(), + statsJob.getStatus(), + statsJob.getStartTime(), + statsJob.getStopTime()); + jobMgr->save(std::move(jobKey3), std::move(jobVal3)); + auto statsKey = MetaKeyUtils::statsKey(spaceId); - auto tempKey = toTempKey(spaceId, jobId); + auto tempKey = toTempKey(spaceId, jobId1); copyData(kv_.get(), 0, 0, statsKey, tempKey); - jobMgr->jobFinished(jobId, cpp2::JobStatus::FINISHED); + jobMgr->jobFinished(spaceId, statsJob.getJobId(), cpp2::JobStatus::FINISHED); { - auto job2Ret = JobDescription::loadJobDescription(statsJob.id_, kv_.get()); + auto job2Ret = + JobDescription::loadJobDescription(statsJob.getSpace(), statsJob.getJobId(), kv_.get()); ASSERT_TRUE(nebula::ok(job2Ret)); - auto job2 = nebula::value(job2Ret); - ASSERT_EQ(statsJob.id_, job2.id_); - ASSERT_EQ(cpp2::JobStatus::FINISHED, job2.status_); + auto job12 = nebula::value(job2Ret); + ASSERT_EQ(statsJob.getJobId(), job12.getJobId()); + ASSERT_EQ(cpp2::JobStatus::FINISHED, job12.getStatus()); cpp2::GetStatsReq req; req.space_id_ref() = spaceId; @@ -216,19 +238,26 @@ TEST_F(GetStatsTest, StatsJob) { } // Execute new stats job in same space. - std::vector paras1{"test_space"}; - JobDescription statsJob2(13, cpp2::JobType::STATS, paras1); - auto rc2 = jobMgr->save(statsJob2.jobKey(), statsJob2.jobVal()); + JobID jobId2 = 13; + JobDescription statsJob2(spaceId, jobId2, cpp2::JobType::STATS); + auto jobKey4 = MetaKeyUtils::jobKey(statsJob2.getSpace(), statsJob2.getJobId()); + auto jobVal4 = MetaKeyUtils::jobVal(statsJob2.getJobType(), + statsJob2.getParas(), + statsJob2.getStatus(), + statsJob2.getStartTime(), + statsJob2.getStopTime()); + auto rc2 = jobMgr->save(std::move(jobKey4), std::move(jobVal4)); ASSERT_EQ(rc2, nebula::cpp2::ErrorCode::SUCCEEDED); { // Job is not executed, job status is QUEUE. // Stats data exists, but it is the result of the last stats job // execution. - auto job1Ret = JobDescription::loadJobDescription(statsJob2.id_, kv_.get()); - ASSERT_TRUE(nebula::ok(job1Ret)); - auto job1 = nebula::value(job1Ret); - ASSERT_EQ(statsJob2.id_, job1.id_); - ASSERT_EQ(cpp2::JobStatus::QUEUE, job1.status_); + auto job2Ret = + JobDescription::loadJobDescription(statsJob2.getSpace(), statsJob2.getJobId(), kv_.get()); + ASSERT_TRUE(nebula::ok(job2Ret)); + auto job21 = nebula::value(job2Ret); + ASSERT_EQ(statsJob2.getJobId(), job21.getJobId()); + ASSERT_EQ(cpp2::JobStatus::QUEUE, job21.getStatus()); // Success, but stats data is the result of the last stats job. cpp2::GetStatsReq req; @@ -259,9 +288,15 @@ TEST_F(GetStatsTest, StatsJob) { ASSERT_EQ(0, statsItem1.get_space_vertices()); ASSERT_EQ(0, statsItem1.get_space_edges()); - auto res = job1.setStatus(cpp2::JobStatus::RUNNING); + auto res = job21.setStatus(cpp2::JobStatus::RUNNING); ASSERT_TRUE(res); - auto retsav = jobMgr->save(job1.jobKey(), job1.jobVal()); + auto jobKey5 = MetaKeyUtils::jobKey(job21.getSpace(), job21.getJobId()); + auto jobVal5 = MetaKeyUtils::jobVal(job21.getJobType(), + job21.getParas(), + job21.getStatus(), + job21.getStartTime(), + job21.getStopTime()); + auto retsav = jobMgr->save(std::move(jobKey5), std::move(jobVal5)); ASSERT_EQ(retsav, nebula::cpp2::ErrorCode::SUCCEEDED); } @@ -300,25 +335,31 @@ TEST_F(GetStatsTest, StatsJob) { // runJobInternal. auto result2 = jobMgr->runJobInternal(statsJob2, JobManager::JbOp::ADD); - auto jobId2 = statsJob2.getJobId(); auto statsKey2 = MetaKeyUtils::statsKey(spaceId); auto tempKey2 = toTempKey(spaceId, jobId2); copyData(kv_.get(), 0, 0, statsKey2, tempKey2); - jobMgr->jobFinished(jobId2, cpp2::JobStatus::FINISHED); + jobMgr->jobFinished(spaceId, statsJob2.getJobId(), cpp2::JobStatus::FINISHED); ASSERT_TRUE(result2); // JobManager does not set the job finished status in RunJobInternal function. // But set stats data. statsJob2.setStatus(cpp2::JobStatus::FINISHED); - jobMgr->save(statsJob2.jobKey(), statsJob2.jobVal()); + auto jobKey6 = MetaKeyUtils::jobKey(statsJob2.getSpace(), statsJob2.getJobId()); + auto jobVal6 = MetaKeyUtils::jobVal(statsJob2.getJobType(), + statsJob2.getParas(), + statsJob2.getStatus(), + statsJob2.getStartTime(), + statsJob2.getStopTime()); + jobMgr->save(std::move(jobKey6), std::move(jobVal6)); { - auto job2Ret = JobDescription::loadJobDescription(statsJob2.id_, kv_.get()); + auto job2Ret = + JobDescription::loadJobDescription(statsJob2.getSpace(), statsJob2.getJobId(), kv_.get()); ASSERT_TRUE(nebula::ok(job2Ret)); - auto job2 = nebula::value(job2Ret); - ASSERT_EQ(statsJob2.id_, job2.id_); - ASSERT_EQ(cpp2::JobStatus::FINISHED, job2.status_); + auto job22 = nebula::value(job2Ret); + ASSERT_EQ(statsJob2.getJobId(), job22.getJobId()); + ASSERT_EQ(cpp2::JobStatus::FINISHED, job22.getStatus()); cpp2::GetStatsReq req; req.space_id_ref() = spaceId; @@ -352,13 +393,14 @@ TEST_F(GetStatsTest, StatsJob) { TEST_F(GetStatsTest, MockSingleMachineTest) { GraphSpaceID spaceId = 1; - // // Because only send to leader, need to mock leader distribution + int32_t partNum = 1; + // Because only send to leader, need to mock leader distribution std::map allStorage; - auto storage = fakeHost("0", 0, 1, {1}); + auto storage = fakeHost("0", 0, spaceId, {1}); allStorage[storage.first] = storage.second; ASSERT_TRUE(TestUtils::createSomeHosts(kv_.get())); - TestUtils::assembleSpace(kv_.get(), 1, 1, 1, 1); + TestUtils::assembleSpace(kv_.get(), spaceId, partNum); std::vector data; for (const auto& entry : allStorage) { auto now = time::WallClock::fastNowInMilliSec(); @@ -376,12 +418,11 @@ TEST_F(GetStatsTest, MockSingleMachineTest) { // add stats job1 JobID jobId1 = 1; - std::vector paras{"test_space"}; - JobDescription job1(jobId1, cpp2::JobType::STATS, paras); + JobDescription job1(spaceId, jobId1, cpp2::JobType::STATS); jobMgr->addJob(job1, &adminClient); - JobCallBack cb1(jobMgr, jobId1, 0, 100); - JobCallBack cb2(jobMgr, 2, 0, 200); + JobCallBack cb1(jobMgr, spaceId, jobId1, 0, 100); + JobCallBack cb2(jobMgr, spaceId, 2, 0, 200); EXPECT_CALL(adminClient, addTask(_, _, _, _, _, _, _)) .Times(2) @@ -391,11 +432,11 @@ TEST_F(GetStatsTest, MockSingleMachineTest) { // check job result { sleep(1); - auto descRet = JobDescription::loadJobDescription(job1.id_, kv_.get()); + auto descRet = JobDescription::loadJobDescription(job1.getSpace(), job1.getJobId(), kv_.get()); ASSERT_TRUE(nebula::ok(descRet)); auto desc = nebula::value(descRet); - ASSERT_EQ(job1.id_, desc.id_); - ASSERT_EQ(cpp2::JobStatus::FINISHED, desc.status_); + ASSERT_EQ(job1.getJobId(), desc.getJobId()); + ASSERT_EQ(cpp2::JobStatus::FINISHED, desc.getStatus()); cpp2::GetStatsReq req; req.space_id_ref() = spaceId; @@ -425,17 +466,17 @@ TEST_F(GetStatsTest, MockSingleMachineTest) { // add stats job2 of same space JobID jobId2 = 2; - JobDescription job2(jobId2, cpp2::JobType::STATS, paras); + JobDescription job2(spaceId, jobId2, cpp2::JobType::STATS); jobMgr->addJob(job2, &adminClient); // check job result { sleep(1); - auto descRet = JobDescription::loadJobDescription(job2.id_, kv_.get()); + auto descRet = JobDescription::loadJobDescription(job2.getSpace(), job2.getJobId(), kv_.get()); ASSERT_TRUE(nebula::ok(descRet)); auto desc = nebula::value(descRet); - ASSERT_EQ(job2.id_, desc.id_); - ASSERT_EQ(cpp2::JobStatus::FINISHED, desc.status_); + ASSERT_EQ(job2.getJobId(), desc.getJobId()); + ASSERT_EQ(cpp2::JobStatus::FINISHED, desc.getStatus()); cpp2::GetStatsReq req; req.space_id_ref() = spaceId; @@ -468,15 +509,15 @@ TEST_F(GetStatsTest, MockMultiMachineTest) { GraphSpaceID spaceId = 1; // Because only send to leader, need to mock leader distribution std::map allStorage; - auto s1 = fakeHost("0", 0, 1, {1, 2}); - auto s2 = fakeHost("1", 1, 1, {3, 4}); - auto s3 = fakeHost("2", 2, 1, {5, 6}); + auto s1 = fakeHost("0", 0, spaceId, {1, 2}); + auto s2 = fakeHost("1", 1, spaceId, {3, 4}); + auto s3 = fakeHost("2", 2, spaceId, {5, 6}); allStorage[s1.first] = s1.second; allStorage[s2.first] = s2.second; allStorage[s3.first] = s3.second; ASSERT_TRUE(TestUtils::createSomeHosts(kv_.get())); - TestUtils::assembleSpace(kv_.get(), 1, 6, 3, 3); + TestUtils::assembleSpace(kv_.get(), spaceId, 6, 3, 3); std::vector data; for (const auto& entry : allStorage) { auto now = time::WallClock::fastNowInMilliSec(); @@ -494,13 +535,12 @@ TEST_F(GetStatsTest, MockMultiMachineTest) { // add stats job JobID jobId = 1; - std::vector paras{"test_space"}; - JobDescription job(jobId, cpp2::JobType::STATS, paras); + JobDescription job(spaceId, jobId, cpp2::JobType::STATS); jobMgr->addJob(job, &adminClient); - JobCallBack cb1(jobMgr, jobId, 0, 100); - JobCallBack cb2(jobMgr, jobId, 1, 200); - JobCallBack cb3(jobMgr, jobId, 2, 300); + JobCallBack cb1(jobMgr, spaceId, jobId, 0, 100); + JobCallBack cb2(jobMgr, spaceId, jobId, 1, 200); + JobCallBack cb3(jobMgr, spaceId, jobId, 2, 300); EXPECT_CALL(adminClient, addTask(_, _, _, _, _, _, _)) .Times(3) @@ -511,11 +551,11 @@ TEST_F(GetStatsTest, MockMultiMachineTest) { // check job result { sleep(1); - auto descRet = JobDescription::loadJobDescription(job.id_, kv_.get()); + auto descRet = JobDescription::loadJobDescription(job.getSpace(), job.getJobId(), kv_.get()); ASSERT_TRUE(nebula::ok(descRet)); auto desc = nebula::value(descRet); - ASSERT_EQ(job.id_, desc.id_); - ASSERT_EQ(cpp2::JobStatus::FINISHED, desc.status_); + ASSERT_EQ(job.getJobId(), desc.getJobId()); + ASSERT_EQ(cpp2::JobStatus::FINISHED, desc.getStatus()); cpp2::GetStatsReq req; req.space_id_ref() = spaceId; diff --git a/src/meta/test/JobManagerTest.cpp b/src/meta/test/JobManagerTest.cpp index 1429a9c67ce..ca40cba48b8 100644 --- a/src/meta/test/JobManagerTest.cpp +++ b/src/meta/test/JobManagerTest.cpp @@ -11,7 +11,6 @@ #include "kvstore/Common.h" #include "meta/ActiveHostsMan.h" #include "meta/processors/job/JobManager.h" -#include "meta/processors/job/JobUtils.h" #include "meta/processors/job/TaskDescription.h" #include "meta/test/MockAdminClient.h" #include "meta/test/TestUtils.h" @@ -31,9 +30,11 @@ class JobManagerTest : public ::testing::Test { rootPath_ = std::make_unique("/tmp/JobManager.XXXXXX"); mock::MockCluster cluster; kv_ = cluster.initMetaKV(rootPath_->path()); - + GraphSpaceID spaceId = 1; + int32_t partitionNum = 1; ASSERT_TRUE(TestUtils::createSomeHosts(kv_.get())); - TestUtils::assembleSpace(kv_.get(), 1, 1); + + TestUtils::assembleSpace(kv_.get(), spaceId, partitionNum); // Make sure the rebuild job could find the index name. std::vector columns; @@ -48,12 +49,9 @@ class JobManagerTest : public ::testing::Test { std::unique_ptr> getJobManager() { std::unique_ptr> jobMgr( new JobManager(), [](JobManager* p) { - std::pair pair; - while (!p->lowPriorityQueue_->empty()) { - p->lowPriorityQueue_->dequeue(pair); - } - while (!p->highPriorityQueue_->empty()) { - p->highPriorityQueue_->dequeue(pair); + std::tuple opJobId; + while (p->jobSize() != 0) { + p->tryDequeue(opJobId); } delete p; }); @@ -75,9 +73,13 @@ class JobManagerTest : public ::testing::Test { TEST_F(JobManagerTest, AddJob) { std::unique_ptr> jobMgr = getJobManager(); - std::vector paras{"test"}; - JobDescription job(1, cpp2::JobType::COMPACT, paras); - auto rc = jobMgr->addJob(job, adminClient_.get()); + // For preventing job schedule in JobManager + jobMgr->status_ = JobManager::JbmgrStatus::STOPPED; + jobMgr->bgThread_.join(); + GraphSpaceID spaceId = 1; + JobID jobId = 2; + JobDescription jobDesc(spaceId, jobId, cpp2::JobType::COMPACT); + auto rc = jobMgr->addJob(jobDesc, adminClient_.get()); ASSERT_EQ(rc, nebula::cpp2::ErrorCode::SUCCEEDED); } @@ -86,11 +88,13 @@ TEST_F(JobManagerTest, AddRebuildTagIndexJob) { // For preventing job schedule in JobManager jobMgr->status_ = JobManager::JbmgrStatus::STOPPED; jobMgr->bgThread_.join(); - std::vector paras{"tag_index_name", "test_space"}; - JobDescription job(11, cpp2::JobType::REBUILD_TAG_INDEX, paras); - auto rc = jobMgr->addJob(job, adminClient_.get()); + std::vector paras{"tag_index_name"}; + GraphSpaceID spaceId = 1; + JobID jobId = 11; + JobDescription jobDesc(spaceId, jobId, cpp2::JobType::REBUILD_TAG_INDEX, paras); + auto rc = jobMgr->addJob(jobDesc, adminClient_.get()); ASSERT_EQ(rc, nebula::cpp2::ErrorCode::SUCCEEDED); - auto result = jobMgr->runJobInternal(job, JobManager::JbOp::ADD); + auto result = jobMgr->runJobInternal(jobDesc, JobManager::JbOp::ADD); ASSERT_TRUE(result); } @@ -99,11 +103,13 @@ TEST_F(JobManagerTest, AddRebuildEdgeIndexJob) { // For preventing job schedule in JobManager jobMgr->status_ = JobManager::JbmgrStatus::STOPPED; jobMgr->bgThread_.join(); - std::vector paras{"edge_index_name", "test_space"}; - JobDescription job(11, cpp2::JobType::REBUILD_EDGE_INDEX, paras); - auto rc = jobMgr->addJob(job, adminClient_.get()); + std::vector paras{"edge_index_name"}; + GraphSpaceID spaceId = 1; + JobID jobId = 11; + JobDescription jobDesc(spaceId, jobId, cpp2::JobType::REBUILD_EDGE_INDEX, paras); + auto rc = jobMgr->addJob(jobDesc, adminClient_.get()); ASSERT_EQ(rc, nebula::cpp2::ErrorCode::SUCCEEDED); - auto result = jobMgr->runJobInternal(job, JobManager::JbOp::ADD); + auto result = jobMgr->runJobInternal(jobDesc, JobManager::JbOp::ADD); ASSERT_TRUE(result); } @@ -112,23 +118,32 @@ TEST_F(JobManagerTest, StatsJob) { // For preventing job schedule in JobManager jobMgr->status_ = JobManager::JbmgrStatus::STOPPED; jobMgr->bgThread_.join(); - std::vector paras{"test_space"}; - JobDescription job(12, cpp2::JobType::STATS, paras); - auto rc = jobMgr->addJob(job, adminClient_.get()); + GraphSpaceID spaceId = 1; + JobID jobId = 12; + JobDescription jobDesc(spaceId, jobId, cpp2::JobType::STATS); + auto rc = jobMgr->addJob(jobDesc, adminClient_.get()); ASSERT_EQ(rc, nebula::cpp2::ErrorCode::SUCCEEDED); - auto result = jobMgr->runJobInternal(job, JobManager::JbOp::ADD); + auto result = jobMgr->runJobInternal(jobDesc, JobManager::JbOp::ADD); ASSERT_TRUE(result); // Function runJobInternal does not set the finished status of the job - job.setStatus(cpp2::JobStatus::FINISHED); - jobMgr->save(job.jobKey(), job.jobVal()); - - auto job1Ret = JobDescription::loadJobDescription(job.id_, kv_.get()); + jobDesc.setStatus(cpp2::JobStatus::FINISHED); + auto jobKey = MetaKeyUtils::jobKey(jobDesc.getSpace(), jobDesc.getJobId()); + auto jobVal = MetaKeyUtils::jobVal(jobDesc.getJobType(), + jobDesc.getParas(), + jobDesc.getStatus(), + jobDesc.getStartTime(), + jobDesc.getStopTime()); + jobMgr->save(std::move(jobKey), std::move(jobVal)); + + auto job1Ret = + JobDescription::loadJobDescription(jobDesc.getSpace(), jobDesc.getJobId(), kv_.get()); ASSERT_TRUE(nebula::ok(job1Ret)); - auto job1 = nebula::value(job1Ret); - ASSERT_EQ(job.id_, job1.id_); - ASSERT_EQ(cpp2::JobStatus::FINISHED, job1.status_); + auto job = nebula::value(job1Ret); + ASSERT_EQ(job.getJobId(), jobDesc.getJobId()); + ASSERT_EQ(cpp2::JobStatus::FINISHED, job.getStatus()); } +// Jobs are parallelized between spaces, and serialized by priority within spaces TEST_F(JobManagerTest, JobPriority) { std::unique_ptr> jobMgr = getJobManager(); // For preventing job schedule in JobManager @@ -136,31 +151,57 @@ TEST_F(JobManagerTest, JobPriority) { jobMgr->bgThread_.join(); ASSERT_EQ(0, jobMgr->jobSize()); - std::vector paras{"test"}; - JobDescription job1(13, cpp2::JobType::COMPACT, paras); - auto rc1 = jobMgr->addJob(job1, adminClient_.get()); + GraphSpaceID spaceId = 1; + JobID jobId1 = 13; + JobDescription jobDesc1(spaceId, jobId1, cpp2::JobType::COMPACT); + auto rc1 = jobMgr->addJob(jobDesc1, adminClient_.get()); ASSERT_EQ(rc1, nebula::cpp2::ErrorCode::SUCCEEDED); - std::vector paras1{"test_space"}; - JobDescription job2(14, cpp2::JobType::STATS, paras1); - auto rc2 = jobMgr->addJob(job2, adminClient_.get()); + JobID jobId2 = 14; + JobDescription jobDesc2(spaceId, jobId2, cpp2::JobType::LEADER_BALANCE); + auto rc2 = jobMgr->addJob(jobDesc2, adminClient_.get()); ASSERT_EQ(rc2, nebula::cpp2::ErrorCode::SUCCEEDED); + GraphSpaceID spaceId2 = 2; + JobID jobId3 = 15; + JobDescription jobDesc3(spaceId2, jobId3, cpp2::JobType::STATS); + auto rc3 = jobMgr->addJob(jobDesc3, adminClient_.get()); + ASSERT_EQ(rc3, nebula::cpp2::ErrorCode::SUCCEEDED); + + ASSERT_EQ(3, jobMgr->jobSize()); + + std::tuple opJobId; + auto result = jobMgr->tryDequeue(opJobId); + ASSERT_TRUE(result); + ASSERT_EQ(14, std::get<1>(opJobId)); + ASSERT_EQ(spaceId, std::get<2>(opJobId)); + // Suppose job starts executing + jobMgr->spaceRunningJobs_.insert_or_assign(spaceId, true); + ASSERT_EQ(2, jobMgr->jobSize()); - std::pair opJobId; - auto result = jobMgr->try_dequeue(opJobId); + result = jobMgr->tryDequeue(opJobId); ASSERT_TRUE(result); - ASSERT_EQ(14, opJobId.second); + ASSERT_EQ(15, std::get<1>(opJobId)); + ASSERT_EQ(spaceId2, std::get<2>(opJobId)); + // Suppose job starts executing + jobMgr->spaceRunningJobs_.insert_or_assign(spaceId2, true); + ASSERT_EQ(1, jobMgr->jobSize()); - result = jobMgr->try_dequeue(opJobId); + result = jobMgr->tryDequeue(opJobId); + // Because all spaces are running jobs + ASSERT_FALSE(result); + + // Suppose the job execution is complete + jobMgr->spaceRunningJobs_.insert_or_assign(spaceId, false); + jobMgr->spaceRunningJobs_.insert_or_assign(spaceId2, false); + ASSERT_EQ(1, jobMgr->jobSize()); + result = jobMgr->tryDequeue(opJobId); ASSERT_TRUE(result); - ASSERT_EQ(13, opJobId.second); + ASSERT_EQ(13, std::get<1>(opJobId)); + ASSERT_EQ(spaceId, std::get<2>(opJobId)); ASSERT_EQ(0, jobMgr->jobSize()); - - result = jobMgr->try_dequeue(opJobId); - ASSERT_FALSE(result); } TEST_F(JobManagerTest, JobDeduplication) { @@ -170,139 +211,147 @@ TEST_F(JobManagerTest, JobDeduplication) { jobMgr->bgThread_.join(); ASSERT_EQ(0, jobMgr->jobSize()); - std::vector paras{"test"}; - JobDescription job1(15, cpp2::JobType::COMPACT, paras); - auto rc1 = jobMgr->addJob(job1, adminClient_.get()); + GraphSpaceID spaceId = 1; + JobID jobId1 = 15; + JobDescription jobDesc1(spaceId, jobId1, cpp2::JobType::COMPACT); + auto rc1 = jobMgr->addJob(jobDesc1, adminClient_.get()); ASSERT_EQ(rc1, nebula::cpp2::ErrorCode::SUCCEEDED); - std::vector paras1{"test_space"}; - JobDescription job2(16, cpp2::JobType::STATS, paras1); - auto rc2 = jobMgr->addJob(job2, adminClient_.get()); + JobID jobId2 = 16; + JobDescription jobDesc2(spaceId, jobId2, cpp2::JobType::LEADER_BALANCE); + auto rc2 = jobMgr->addJob(jobDesc2, adminClient_.get()); ASSERT_EQ(rc2, nebula::cpp2::ErrorCode::SUCCEEDED); ASSERT_EQ(2, jobMgr->jobSize()); - JobDescription job3(17, cpp2::JobType::STATS, paras1); + JobID jobId3 = 17; + JobDescription jobDesc3(spaceId, jobId3, cpp2::JobType::LEADER_BALANCE); JobID jId3 = 0; - auto jobExist = jobMgr->checkJobExist(job3.getJobType(), job3.getParas(), jId3); + auto jobExist = jobMgr->checkJobExist(spaceId, jobDesc3.getJobType(), jobDesc3.getParas(), jId3); if (!jobExist) { - auto rc3 = jobMgr->addJob(job3, adminClient_.get()); + auto rc3 = jobMgr->addJob(jobDesc3, adminClient_.get()); ASSERT_EQ(rc3, nebula::cpp2::ErrorCode::SUCCEEDED); } - JobDescription job4(18, cpp2::JobType::COMPACT, paras); + JobID jobId4 = 18; + JobDescription jobDesc4(spaceId, jobId4, cpp2::JobType::COMPACT); JobID jId4 = 0; - jobExist = jobMgr->checkJobExist(job4.getJobType(), job4.getParas(), jId4); + jobExist = jobMgr->checkJobExist(spaceId, jobDesc4.getJobType(), jobDesc4.getParas(), jId4); if (!jobExist) { - auto rc4 = jobMgr->addJob(job4, adminClient_.get()); + auto rc4 = jobMgr->addJob(jobDesc4, adminClient_.get()); ASSERT_NE(rc4, nebula::cpp2::ErrorCode::SUCCEEDED); } ASSERT_EQ(2, jobMgr->jobSize()); - std::pair opJobId; - auto result = jobMgr->try_dequeue(opJobId); + std::tuple opJobId; + auto result = jobMgr->tryDequeue(opJobId); ASSERT_TRUE(result); - ASSERT_EQ(16, opJobId.second); + ASSERT_EQ(16, std::get<1>(opJobId)); ASSERT_EQ(1, jobMgr->jobSize()); - result = jobMgr->try_dequeue(opJobId); + result = jobMgr->tryDequeue(opJobId); ASSERT_TRUE(result); - ASSERT_EQ(15, opJobId.second); + ASSERT_EQ(15, std::get<1>(opJobId)); ASSERT_EQ(0, jobMgr->jobSize()); - result = jobMgr->try_dequeue(opJobId); + result = jobMgr->tryDequeue(opJobId); ASSERT_FALSE(result); } TEST_F(JobManagerTest, LoadJobDescription) { std::unique_ptr> jobMgr = getJobManager(); - std::vector paras{"test_space"}; - JobDescription job1(1, cpp2::JobType::COMPACT, paras); - job1.setStatus(cpp2::JobStatus ::RUNNING); - job1.setStatus(cpp2::JobStatus::FINISHED); - auto rc = jobMgr->addJob(job1, adminClient_.get()); + GraphSpaceID spaceId = 1; + JobID jobId1 = 1; + JobDescription jobDesc1(spaceId, jobId1, cpp2::JobType::COMPACT); + jobDesc1.setStatus(cpp2::JobStatus::RUNNING); + jobDesc1.setStatus(cpp2::JobStatus::FINISHED); + auto rc = jobMgr->addJob(jobDesc1, adminClient_.get()); ASSERT_EQ(rc, nebula::cpp2::ErrorCode::SUCCEEDED); - ASSERT_EQ(job1.id_, 1); - ASSERT_EQ(job1.type_, cpp2::JobType::COMPACT); - ASSERT_EQ(job1.paras_[0], "test_space"); + ASSERT_EQ(jobDesc1.getSpace(), 1); + ASSERT_EQ(jobDesc1.getJobId(), 1); + ASSERT_EQ(jobDesc1.getJobType(), cpp2::JobType::COMPACT); + ASSERT_TRUE(jobDesc1.getParas().empty()); - auto optJd2Ret = JobDescription::loadJobDescription(job1.id_, kv_.get()); + auto optJd2Ret = + JobDescription::loadJobDescription(jobDesc1.getSpace(), jobDesc1.getJobId(), kv_.get()); ASSERT_TRUE(nebula::ok(optJd2Ret)); auto optJd2 = nebula::value(optJd2Ret); - ASSERT_EQ(job1.id_, optJd2.id_); - LOG(INFO) << "job1.id_ = " << job1.id_; - ASSERT_EQ(job1.type_, optJd2.type_); - ASSERT_EQ(job1.paras_, optJd2.paras_); - ASSERT_EQ(job1.status_, optJd2.status_); - ASSERT_EQ(job1.startTime_, optJd2.startTime_); - ASSERT_EQ(job1.stopTime_, optJd2.stopTime_); -} - -TEST(JobUtilTest, Dummy) { - ASSERT_TRUE(JobUtil::jobPrefix().length() + sizeof(size_t) != JobUtil::currJobKey().length()); + ASSERT_EQ(jobDesc1.getJobId(), optJd2.getJobId()); + ASSERT_EQ(jobDesc1.getSpace(), optJd2.getSpace()); + ASSERT_EQ(jobDesc1.getJobType(), optJd2.getJobType()); + ASSERT_EQ(jobDesc1.getParas(), optJd2.getParas()); + ASSERT_EQ(jobDesc1.getStatus(), optJd2.getStatus()); + ASSERT_EQ(jobDesc1.getStartTime(), optJd2.getStartTime()); + ASSERT_EQ(jobDesc1.getStopTime(), optJd2.getStopTime()); } TEST_F(JobManagerTest, ShowJobs) { std::unique_ptr> jobMgr = getJobManager(); - std::vector paras1{"test_space"}; - JobDescription jd1(1, cpp2::JobType::COMPACT, paras1); - jd1.setStatus(cpp2::JobStatus::RUNNING); - jd1.setStatus(cpp2::JobStatus::FINISHED); - jobMgr->addJob(jd1, adminClient_.get()); - - std::vector paras2{"test_space"}; - JobDescription jd2(2, cpp2::JobType::FLUSH, paras2); - jd2.setStatus(cpp2::JobStatus::RUNNING); - jd2.setStatus(cpp2::JobStatus::FAILED); - jobMgr->addJob(jd2, adminClient_.get()); - - auto statusOrShowResult = jobMgr->showJobs(paras1.back()); + GraphSpaceID spaceId = 1; + JobID jobId1 = 1; + JobDescription jobDesc1(spaceId, jobId1, cpp2::JobType::COMPACT); + jobDesc1.setStatus(cpp2::JobStatus::RUNNING); + jobDesc1.setStatus(cpp2::JobStatus::FINISHED); + jobMgr->addJob(jobDesc1, adminClient_.get()); + + JobID jobId2 = 2; + JobDescription jobDesc2(spaceId, jobId2, cpp2::JobType::FLUSH); + jobDesc2.setStatus(cpp2::JobStatus::RUNNING); + jobDesc2.setStatus(cpp2::JobStatus::FAILED); + jobMgr->addJob(jobDesc2, adminClient_.get()); + + auto statusOrShowResult = jobMgr->showJobs(spaceId); LOG(INFO) << "after show jobs"; ASSERT_TRUE(nebula::ok(statusOrShowResult)); auto& jobs = nebula::value(statusOrShowResult); - ASSERT_EQ(jobs[1].get_id(), jd1.id_); - ASSERT_EQ(jobs[1].get_type(), cpp2::JobType::COMPACT); - ASSERT_EQ(jobs[1].get_paras()[0], "test_space"); - ASSERT_EQ(jobs[1].get_status(), cpp2::JobStatus::FINISHED); - ASSERT_EQ(jobs[1].get_start_time(), jd1.startTime_); - ASSERT_EQ(jobs[1].get_stop_time(), jd1.stopTime_); - - ASSERT_EQ(jobs[0].get_id(), jd2.id_); + ASSERT_EQ(jobs[0].get_space_id(), jobDesc2.getSpace()); + ASSERT_EQ(jobs[0].get_job_id(), jobDesc2.getJobId()); ASSERT_EQ(jobs[0].get_type(), cpp2::JobType::FLUSH); - ASSERT_EQ(jobs[0].get_paras()[0], "test_space"); ASSERT_EQ(jobs[0].get_status(), cpp2::JobStatus::FAILED); - ASSERT_EQ(jobs[0].get_start_time(), jd2.startTime_); - ASSERT_EQ(jobs[0].get_stop_time(), jd2.stopTime_); + ASSERT_EQ(jobs[0].get_start_time(), jobDesc2.getStartTime()); + ASSERT_EQ(jobs[0].get_stop_time(), jobDesc2.getStopTime()); + ASSERT_EQ(jobs[0].get_paras(), jobDesc2.getParas()); + + ASSERT_EQ(jobs[1].get_space_id(), jobDesc1.getSpace()); + ASSERT_EQ(jobs[1].get_job_id(), jobDesc1.getJobId()); + ASSERT_EQ(jobs[1].get_type(), cpp2::JobType::COMPACT); + ASSERT_EQ(jobs[1].get_status(), cpp2::JobStatus::FINISHED); + ASSERT_EQ(jobs[1].get_start_time(), jobDesc1.getStartTime()); + ASSERT_EQ(jobs[1].get_stop_time(), jobDesc1.getStopTime()); + ASSERT_EQ(jobs[1].get_paras(), jobDesc1.getParas()); } TEST_F(JobManagerTest, ShowJobsFromMultiSpace) { std::unique_ptr> jobMgr = getJobManager(); - std::vector paras1{"test_space"}; - JobDescription jd1(1, cpp2::JobType::COMPACT, paras1); + GraphSpaceID spaceId1 = 1; + JobID jobId1 = 1; + JobDescription jd1(spaceId1, jobId1, cpp2::JobType::COMPACT); jd1.setStatus(cpp2::JobStatus::RUNNING); jd1.setStatus(cpp2::JobStatus::FINISHED); jobMgr->addJob(jd1, adminClient_.get()); - std::vector paras2{"test_space2"}; - JobDescription jd2(2, cpp2::JobType::FLUSH, paras2); + GraphSpaceID spaceId2 = 2; + JobID jobId2 = 2; + JobDescription jd2(spaceId2, jobId2, cpp2::JobType::FLUSH); jd2.setStatus(cpp2::JobStatus::RUNNING); jd2.setStatus(cpp2::JobStatus::FAILED); jobMgr->addJob(jd2, adminClient_.get()); - auto statusOrShowResult = jobMgr->showJobs(paras2.back()); + auto statusOrShowResult = jobMgr->showJobs(spaceId2); LOG(INFO) << "after show jobs"; ASSERT_TRUE(nebula::ok(statusOrShowResult)); auto& jobs = nebula::value(statusOrShowResult); ASSERT_EQ(jobs.size(), 1); - ASSERT_EQ(jobs[0].get_id(), jd2.id_); + ASSERT_EQ(jobs[0].get_space_id(), jd2.getSpace()); + ASSERT_EQ(jobs[0].get_job_id(), jd2.getJobId()); ASSERT_EQ(jobs[0].get_type(), cpp2::JobType::FLUSH); - ASSERT_EQ(jobs[0].get_paras()[0], "test_space2"); ASSERT_EQ(jobs[0].get_status(), cpp2::JobStatus::FAILED); - ASSERT_EQ(jobs[0].get_start_time(), jd2.startTime_); - ASSERT_EQ(jobs[0].get_stop_time(), jd2.stopTime_); + ASSERT_EQ(jobs[0].get_start_time(), jd2.getStartTime()); + ASSERT_EQ(jobs[0].get_stop_time(), jd2.getStopTime()); + ASSERT_EQ(jobs[0].get_paras(), jd2.getParas()); } HostAddr toHost(std::string strIp) { @@ -311,86 +360,101 @@ HostAddr toHost(std::string strIp) { TEST_F(JobManagerTest, ShowJob) { std::unique_ptr> jobMgr = getJobManager(); - std::vector paras{"test_space"}; - - JobDescription jd(1, cpp2::JobType::COMPACT, paras); + GraphSpaceID spaceId = 1; + JobID jobId1 = 1; + JobDescription jd(spaceId, jobId1, cpp2::JobType::COMPACT); jd.setStatus(cpp2::JobStatus::RUNNING); jd.setStatus(cpp2::JobStatus::FINISHED); jobMgr->addJob(jd, adminClient_.get()); - int32_t iJob = jd.id_; + int32_t jobId2 = jd.getJobId(); int32_t task1 = 0; auto host1 = toHost("127.0.0.1"); - TaskDescription td1(iJob, task1, host1); + TaskDescription td1(spaceId, jobId2, task1, host1); td1.setStatus(cpp2::JobStatus::RUNNING); td1.setStatus(cpp2::JobStatus::FINISHED); - jobMgr->save(td1.taskKey(), td1.taskVal()); + auto taskKey1 = MetaKeyUtils::taskKey(td1.getSpace(), td1.getJobId(), td1.getTaskId()); + auto taskVal1 = + MetaKeyUtils::taskVal(td1.getHost(), td1.getStatus(), td1.getStartTime(), td1.getStopTime()); + jobMgr->save(taskKey1, taskVal1); int32_t task2 = 1; auto host2 = toHost("127.0.0.1"); - TaskDescription td2(iJob, task2, host2); + TaskDescription td2(spaceId, jobId2, task2, host2); td2.setStatus(cpp2::JobStatus::RUNNING); td2.setStatus(cpp2::JobStatus::FAILED); - jobMgr->save(td2.taskKey(), td2.taskVal()); + auto taskKey2 = MetaKeyUtils::taskKey(td2.getSpace(), td2.getJobId(), td2.getTaskId()); + auto taskVal2 = + MetaKeyUtils::taskVal(td2.getHost(), td2.getStatus(), td2.getStartTime(), td2.getStopTime()); + jobMgr->save(taskKey2, taskVal2); LOG(INFO) << "before jobMgr->showJob"; - auto showResult = jobMgr->showJob(iJob, paras.back()); + auto showResult = jobMgr->showJob(spaceId, jobId1); LOG(INFO) << "after jobMgr->showJob"; ASSERT_TRUE(nebula::ok(showResult)); auto& jobs = nebula::value(showResult).first; auto& tasks = nebula::value(showResult).second; - ASSERT_EQ(jobs.get_id(), iJob); + ASSERT_EQ(jobs.get_space_id(), spaceId); + ASSERT_EQ(jobs.get_job_id(), jobId1); ASSERT_EQ(jobs.get_type(), cpp2::JobType::COMPACT); - ASSERT_EQ(jobs.get_paras()[0], "test_space"); + ASSERT_TRUE(jobs.get_paras().empty()); ASSERT_EQ(jobs.get_status(), cpp2::JobStatus::FINISHED); - ASSERT_EQ(jobs.get_start_time(), jd.startTime_); - ASSERT_EQ(jobs.get_stop_time(), jd.stopTime_); + ASSERT_EQ(jobs.get_start_time(), jd.getStartTime()); + ASSERT_EQ(jobs.get_stop_time(), jd.getStopTime()); + ASSERT_EQ(tasks[0].get_space_id(), spaceId); + ASSERT_EQ(tasks[0].get_job_id(), jobId1); ASSERT_EQ(tasks[0].get_task_id(), task1); - ASSERT_EQ(tasks[0].get_job_id(), iJob); ASSERT_EQ(tasks[0].get_host().host, host1.host); ASSERT_EQ(tasks[0].get_status(), cpp2::JobStatus::FINISHED); - ASSERT_EQ(tasks[0].get_start_time(), td1.startTime_); - ASSERT_EQ(tasks[0].get_stop_time(), td1.stopTime_); + ASSERT_EQ(tasks[0].get_start_time(), td1.getStartTime()); + ASSERT_EQ(tasks[0].get_stop_time(), td1.getStopTime()); + ASSERT_EQ(tasks[1].get_space_id(), spaceId); + ASSERT_EQ(tasks[1].get_job_id(), jobId1); ASSERT_EQ(tasks[1].get_task_id(), task2); - ASSERT_EQ(tasks[1].get_job_id(), iJob); ASSERT_EQ(tasks[1].get_host().host, host2.host); ASSERT_EQ(tasks[1].get_status(), cpp2::JobStatus::FAILED); - ASSERT_EQ(tasks[1].get_start_time(), td2.startTime_); - ASSERT_EQ(tasks[1].get_stop_time(), td2.stopTime_); + ASSERT_EQ(tasks[1].get_start_time(), td2.getStartTime()); + ASSERT_EQ(tasks[1].get_stop_time(), td2.getStopTime()); } TEST_F(JobManagerTest, ShowJobInOtherSpace) { std::unique_ptr> jobMgr = getJobManager(); - std::vector paras{"test_space"}; - - JobDescription jd(1, cpp2::JobType::COMPACT, paras); + GraphSpaceID spaceId1 = 1; + JobID jobId1 = 1; + JobDescription jd(spaceId1, jobId1, cpp2::JobType::COMPACT); jd.setStatus(cpp2::JobStatus::RUNNING); jd.setStatus(cpp2::JobStatus::FINISHED); jobMgr->addJob(jd, adminClient_.get()); - int32_t iJob = jd.id_; + int32_t jobId2 = jd.getJobId(); int32_t task1 = 0; auto host1 = toHost("127.0.0.1"); - TaskDescription td1(iJob, task1, host1); + TaskDescription td1(spaceId1, jobId2, task1, host1); td1.setStatus(cpp2::JobStatus::RUNNING); td1.setStatus(cpp2::JobStatus::FINISHED); - jobMgr->save(td1.taskKey(), td1.taskVal()); + auto taskKey1 = MetaKeyUtils::taskKey(td1.getSpace(), td1.getJobId(), td1.getTaskId()); + auto taskVal1 = + MetaKeyUtils::taskVal(td1.getHost(), td1.getStatus(), td1.getStartTime(), td1.getStopTime()); + jobMgr->save(taskKey1, taskVal1); int32_t task2 = 1; auto host2 = toHost("127.0.0.1"); - TaskDescription td2(iJob, task2, host2); + TaskDescription td2(spaceId1, jobId2, task2, host2); td2.setStatus(cpp2::JobStatus::RUNNING); td2.setStatus(cpp2::JobStatus::FAILED); - jobMgr->save(td2.taskKey(), td2.taskVal()); + auto taskKey2 = MetaKeyUtils::taskKey(td2.getSpace(), td2.getJobId(), td2.getTaskId()); + auto taskVal2 = + MetaKeyUtils::taskVal(td2.getHost(), td2.getStatus(), td2.getStartTime(), td2.getStopTime()); + jobMgr->save(taskKey2, taskVal2); LOG(INFO) << "before jobMgr->showJob"; - std::string chosenSpace = "spaceWithNoJob"; - auto showResult = jobMgr->showJob(iJob, chosenSpace); + GraphSpaceID spaceId2 = 2; + auto showResult = jobMgr->showJob(spaceId2, jobId1); LOG(INFO) << "after jobMgr->showJob"; ASSERT_TRUE(!nebula::ok(showResult)); } @@ -400,156 +464,129 @@ TEST_F(JobManagerTest, RecoverJob) { // set status to prevent running the job since AdminClient is a injector jobMgr->status_ = JobManager::JbmgrStatus::STOPPED; jobMgr->bgThread_.join(); - auto spaceName = "test_space"; + GraphSpaceID spaceId = 1; + int32_t nJob = 3; - for (auto i = 0; i != nJob; ++i) { - JobDescription jd(i, cpp2::JobType::FLUSH, {spaceName}); - jobMgr->save(jd.jobKey(), jd.jobVal()); + for (auto jobId = 0; jobId < nJob; ++jobId) { + JobDescription jd(spaceId, jobId, cpp2::JobType::FLUSH); + auto jobKey = MetaKeyUtils::jobKey(jd.getSpace(), jd.getJobId()); + auto jobVal = MetaKeyUtils::jobVal( + jd.getJobType(), jd.getParas(), jd.getStatus(), jd.getStartTime(), jd.getStopTime()); + jobMgr->save(jobKey, jobVal); } - auto nJobRecovered = jobMgr->recoverJob(spaceName, nullptr); + auto nJobRecovered = jobMgr->recoverJob(spaceId, nullptr); ASSERT_EQ(nebula::value(nJobRecovered), 1); } TEST(JobDescriptionTest, Ctor) { - std::vector paras1{"test_space"}; - JobDescription jd1(1, cpp2::JobType::COMPACT, paras1); + GraphSpaceID spaceId = 1; + JobID jobId1 = 1; + JobDescription jd1(spaceId, jobId1, cpp2::JobType::COMPACT); jd1.setStatus(cpp2::JobStatus::RUNNING); jd1.setStatus(cpp2::JobStatus::FINISHED); LOG(INFO) << "jd1 ctored"; } TEST(JobDescriptionTest, Ctor2) { - std::vector paras1{"test_space"}; - JobDescription jd1(1, cpp2::JobType::COMPACT, paras1); + GraphSpaceID spaceId = 1; + JobID jobId1 = 1; + JobDescription jd1(spaceId, jobId1, cpp2::JobType::COMPACT); jd1.setStatus(cpp2::JobStatus::RUNNING); jd1.setStatus(cpp2::JobStatus::FINISHED); LOG(INFO) << "jd1 ctored"; - std::string strKey = jd1.jobKey(); - std::string strVal = jd1.jobVal(); - auto optJobRet = JobDescription::makeJobDescription(strKey, strVal); - ASSERT_TRUE(nebula::ok(optJobRet)); -} - -TEST(JobDescriptionTest, Ctor3) { - std::vector paras1{"test_space"}; - JobDescription jd1(1, cpp2::JobType::COMPACT, paras1); - jd1.setStatus(cpp2::JobStatus::RUNNING); - jd1.setStatus(cpp2::JobStatus::FINISHED); - LOG(INFO) << "jd1 ctored"; - - std::string strKey = jd1.jobKey(); - std::string strVal = jd1.jobVal(); - folly::StringPiece spKey(&strKey[0], strKey.length()); - folly::StringPiece spVal(&strVal[0], strVal.length()); - auto optJobRet = JobDescription::makeJobDescription(spKey, spVal); + auto jobKey = MetaKeyUtils::jobKey(jd1.getSpace(), jd1.getJobId()); + auto jobVal = MetaKeyUtils::jobVal( + jd1.getJobType(), jd1.getParas(), jd1.getStatus(), jd1.getStartTime(), jd1.getStopTime()); + auto optJobRet = JobDescription::makeJobDescription(jobKey, jobVal); ASSERT_TRUE(nebula::ok(optJobRet)); } TEST(JobDescriptionTest, ParseKey) { - int32_t iJob = std::pow(2, 16); - std::vector paras{"test_space"}; - JobDescription jd(iJob, cpp2::JobType::COMPACT, paras); - auto sKey = jd.jobKey(); - ASSERT_EQ(iJob, jd.getJobId()); + GraphSpaceID spaceId = 1; + int32_t jobId = std::pow(2, 16); + JobDescription jd(spaceId, jobId, cpp2::JobType::COMPACT); + ASSERT_EQ(jobId, jd.getJobId()); ASSERT_EQ(cpp2::JobType::COMPACT, jd.getJobType()); - folly::StringPiece spKey(&sKey[0], sKey.length()); - auto parsedKeyId = JobDescription::parseKey(spKey); - ASSERT_EQ(iJob, parsedKeyId); + auto jobKey = MetaKeyUtils::jobKey(jd.getSpace(), jd.getJobId()); + auto parsedSpaceJobId = MetaKeyUtils::parseJobKey(jobKey); + ASSERT_EQ(spaceId, parsedSpaceJobId.first); + ASSERT_EQ(jobId, parsedSpaceJobId.second); } TEST(JobDescriptionTest, ParseVal) { - int32_t iJob = std::pow(2, 15); - std::vector paras{"nba"}; - JobDescription jd(iJob, cpp2::JobType::FLUSH, paras); + GraphSpaceID spaceId = 1; + int32_t jobId = std::pow(2, 15); + JobDescription jd(spaceId, jobId, cpp2::JobType::FLUSH); auto status = cpp2::JobStatus::FINISHED; jd.setStatus(cpp2::JobStatus::RUNNING); jd.setStatus(status); - auto startTime = jd.startTime_; - auto stopTime = jd.stopTime_; + auto startTime = jd.getStartTime(); + auto stopTime = jd.getStopTime(); - auto strVal = jd.jobVal(); - folly::StringPiece rawVal(&strVal[0], strVal.length()); - auto parsedVal = JobDescription::parseVal(rawVal); + auto jobVal = MetaKeyUtils::jobVal( + jd.getJobType(), jd.getParas(), jd.getStatus(), jd.getStartTime(), jd.getStopTime()); + auto parsedVal = MetaKeyUtils::parseJobVal(jobVal); ASSERT_EQ(cpp2::JobType::FLUSH, std::get<0>(parsedVal)); - ASSERT_EQ(paras, std::get<1>(parsedVal)); + auto paras = std::get<1>(parsedVal); + ASSERT_TRUE(paras.empty()); ASSERT_EQ(status, std::get<2>(parsedVal)); ASSERT_EQ(startTime, std::get<3>(parsedVal)); ASSERT_EQ(stopTime, std::get<4>(parsedVal)); } TEST(TaskDescriptionTest, Ctor) { - int32_t iJob = std::pow(2, 4); - int32_t iTask = 0; + GraphSpaceID spaceId = 1; + int32_t jobId = std::pow(2, 4); + int32_t taskId = 2; auto dest = toHost(""); - TaskDescription td(iJob, iTask, dest); + TaskDescription td(spaceId, jobId, taskId, dest); auto status = cpp2::JobStatus::RUNNING; - ASSERT_EQ(iJob, td.iJob_); - ASSERT_EQ(iTask, td.iTask_); - ASSERT_EQ(dest.host, td.dest_.host); - ASSERT_EQ(dest.port, td.dest_.port); - ASSERT_EQ(status, td.status_); + ASSERT_EQ(spaceId, td.getSpace()); + ASSERT_EQ(jobId, td.getJobId()); + ASSERT_EQ(taskId, td.getTaskId()); + ASSERT_EQ(dest.host, td.getHost().host); + ASSERT_EQ(dest.port, td.getHost().port); + ASSERT_EQ(status, td.getStatus()); } TEST(TaskDescriptionTest, ParseKey) { - int32_t iJob = std::pow(2, 5); - int32_t iTask = 0; + GraphSpaceID spaceId = 1; + int32_t jobId = std::pow(2, 5); + int32_t taskId = 2; std::string dest{"127.0.0.1"}; - TaskDescription td(iJob, iTask, toHost(dest)); + TaskDescription td(spaceId, jobId, taskId, toHost(dest)); + + auto taskKey = MetaKeyUtils::taskKey(td.getSpace(), td.getJobId(), td.getTaskId()); - std::string strKey = td.taskKey(); - folly::StringPiece rawKey(&strKey[0], strKey.length()); - auto tup = TaskDescription::parseKey(rawKey); - ASSERT_EQ(iJob, std::get<0>(tup)); - ASSERT_EQ(iTask, std::get<1>(tup)); + auto tup = MetaKeyUtils::parseTaskKey(taskKey); + ASSERT_EQ(td.getSpace(), std::get<0>(tup)); + ASSERT_EQ(td.getJobId(), std::get<1>(tup)); + ASSERT_EQ(td.getTaskId(), std::get<2>(tup)); } TEST(TaskDescriptionTest, ParseVal) { - int32_t iJob = std::pow(2, 5); - int32_t iTask = 0; + GraphSpaceID spaceId = 1; + int32_t jobId = std::pow(2, 5); + int32_t taskId = 3; std::string dest{"127.0.0.1"}; - TaskDescription td(iJob, iTask, toHost(dest)); + TaskDescription td(spaceId, jobId, taskId, toHost(dest)); td.setStatus(cpp2::JobStatus::RUNNING); auto status = cpp2::JobStatus::FINISHED; td.setStatus(status); - std::string strVal = td.taskVal(); - folly::StringPiece rawVal(&strVal[0], strVal.length()); - auto parsedVal = TaskDescription::parseVal(rawVal); - - ASSERT_EQ(td.dest_, std::get<0>(parsedVal)); - ASSERT_EQ(td.status_, std::get<1>(parsedVal)); - ASSERT_EQ(td.startTime_, std::get<2>(parsedVal)); - ASSERT_EQ(td.stopTime_, std::get<3>(parsedVal)); -} - -TEST(TaskDescriptionTest, Ctor2) { - int32_t iJob = std::pow(2, 6); - int32_t iTask = 0; - auto dest = toHost("127.0.0.1"); - - TaskDescription td1(iJob, iTask, dest); - ASSERT_EQ(td1.status_, cpp2::JobStatus::RUNNING); - auto status = cpp2::JobStatus::FINISHED; - td1.setStatus(status); - - std::string strKey = td1.taskKey(); - std::string strVal = td1.taskVal(); - - folly::StringPiece rawKey(&strKey[0], strKey.length()); - folly::StringPiece rawVal(&strVal[0], strVal.length()); - TaskDescription td2(rawKey, rawVal); + auto strVal = + MetaKeyUtils::taskVal(td.getHost(), td.getStatus(), td.getStartTime(), td.getStopTime()); + auto parsedVal = MetaKeyUtils::parseTaskVal(strVal); - ASSERT_EQ(td1.iJob_, td2.iJob_); - ASSERT_EQ(td1.iTask_, td2.iTask_); - ASSERT_EQ(td1.dest_, td2.dest_); - ASSERT_EQ(td1.status_, td2.status_); - ASSERT_EQ(td1.startTime_, td2.startTime_); - ASSERT_EQ(td1.stopTime_, td2.stopTime_); + ASSERT_EQ(td.getHost(), std::get<0>(parsedVal)); + ASSERT_EQ(td.getStatus(), std::get<1>(parsedVal)); + ASSERT_EQ(td.getStartTime(), std::get<2>(parsedVal)); + ASSERT_EQ(td.getStopTime(), std::get<3>(parsedVal)); } } // namespace meta diff --git a/src/storage/StorageServer.cpp b/src/storage/StorageServer.cpp index 4ccdc2307c8..90b4305877f 100644 --- a/src/storage/StorageServer.cpp +++ b/src/storage/StorageServer.cpp @@ -133,14 +133,14 @@ bool StorageServer::initWebService() { } std::unique_ptr StorageServer::getAdminStoreInstance() { - int32_t vIdLen = NebulaKeyUtils::adminTaskKey(-1, 0, 0).size(); + int32_t vIdLen = NebulaKeyUtils::adminTaskKey(-1, 0, 0, 0).size(); std::unique_ptr re( new kvstore::RocksEngine(0, vIdLen, dataPaths_[0], walPath_)); return re; } int32_t StorageServer::getAdminStoreSeqId() { - std::string key = NebulaKeyUtils::adminTaskKey(-1, 0, 0); + std::string key = NebulaKeyUtils::adminTaskKey(-1, 0, 0, 0); std::string val; nebula::cpp2::ErrorCode rc = env_->adminStore_->get(key, &val); int32_t curSeqId = 1; diff --git a/src/storage/admin/AdminTaskManager.cpp b/src/storage/admin/AdminTaskManager.cpp index 9183f7b592d..ca764ce6f71 100644 --- a/src/storage/admin/AdminTaskManager.cpp +++ b/src/storage/admin/AdminTaskManager.cpp @@ -46,6 +46,10 @@ void AdminTaskManager::handleUnreportedTasks() { std::tuple>>; if (env_ == nullptr) return; unreportedAdminThread_.reset(new std::thread([this] { + int32_t seqId; + GraphSpaceID spaceId; + JobID jobId; + TaskID taskId; while (true) { std::unique_lock lk(unreportedMutex_); if (!ifAnyUnreported_) { @@ -65,13 +69,14 @@ void AdminTaskManager::handleUnreportedTasks() { std::vector futVec; for (; iter->valid(); iter->next()) { folly::StringPiece key = iter->key(); - int32_t seqId = *reinterpret_cast(key.data()); + if (!NebulaKeyUtils::isAdminTaskKey(key)) { + continue; + } + + std::tie(seqId, spaceId, jobId, taskId) = NebulaKeyUtils::parseAdminTaskKey(key); if (seqId < 0) { continue; } - JobID jobId = *reinterpret_cast(key.data() + sizeof(int32_t)); - TaskID taskId = - *reinterpret_cast(key.data() + sizeof(int32_t) + sizeof(JobID)); folly::StringPiece val = iter->val(); folly::StringPiece statsVal(val.data() + sizeof(nebula::cpp2::ErrorCode), val.size() - sizeof(nebula::cpp2::ErrorCode)); @@ -92,30 +97,30 @@ void AdminTaskManager::handleUnreportedTasks() { if (jobStatus == nebula::meta::cpp2::JobStatus::RUNNING && pStats != nullptr) { pStats->status_ref() = nebula::meta::cpp2::JobStatus::FAILED; } - auto fut = env_->metaClient_->reportTaskFinish(jobId, taskId, errCode, pStats); + auto fut = env_->metaClient_->reportTaskFinish(spaceId, jobId, taskId, errCode, pStats); futVec.emplace_back(std::move(jobId), std::move(taskId), std::move(key), std::move(fut)); } else if (jobStatus != nebula::meta::cpp2::JobStatus::RUNNING) { - auto fut = env_->metaClient_->reportTaskFinish(jobId, taskId, errCode, pStats); + auto fut = env_->metaClient_->reportTaskFinish(spaceId, jobId, taskId, errCode, pStats); futVec.emplace_back(std::move(jobId), std::move(taskId), std::move(key), std::move(fut)); } } for (auto& p : futVec) { - JobID jobId = std::get<0>(p); - TaskID taskId = std::get<1>(p); + JobID jId = std::get<0>(p); + TaskID tId = std::get<1>(p); std::string& key = std::get<2>(p); auto& fut = std::get<3>(p); auto rc = nebula::cpp2::ErrorCode::SUCCEEDED; fut.wait(); if (!fut.hasValue()) { LOG(INFO) << folly::sformat( - "reportTaskFinish() got rpc error:, job={}, task={}", jobId, taskId); + "reportTaskFinish() got rpc error:, job={}, task={}", jId, tId); ifAnyUnreported_ = true; continue; } if (!fut.value().ok()) { LOG(INFO) << folly::sformat("reportTaskFinish() has bad status:, job={}, task={}, rc={}", - jobId, - taskId, + jId, + tId, fut.value().status().toString()); if (fut.value().status() == Status::Error("Space not existed!")) { // space has been droped, remove the task status. @@ -127,8 +132,8 @@ void AdminTaskManager::handleUnreportedTasks() { } rc = fut.value().value(); LOG(INFO) << folly::sformat("reportTaskFinish(), job={}, task={}, rc={}", - jobId, - taskId, + jId, + tId, apache::thrift::util::enumNameSafe(rc)); if (rc == nebula::cpp2::ErrorCode::E_LEADER_CHANGED || rc == nebula::cpp2::ErrorCode::E_STORE_FAILURE) { @@ -153,7 +158,7 @@ void AdminTaskManager::addAsyncTask(std::shared_ptr task) { LOG(INFO) << folly::stringPrintf("enqueue task(%d, %d)", task->getJobId(), task->getTaskId()); } -nebula::cpp2::ErrorCode AdminTaskManager::cancelJob(JobID jobId) { +nebula::cpp2::ErrorCode AdminTaskManager::cancelTask(JobID jobId) { // When the job does not exist on the host, // it should return success instead of failure auto ret = nebula::cpp2::ErrorCode::SUCCEEDED; @@ -162,7 +167,7 @@ nebula::cpp2::ErrorCode AdminTaskManager::cancelJob(JobID jobId) { auto handle = it->first; if (handle.first == jobId) { it->second->cancel(); - removeTaskStatus(it->second->getJobId(), it->second->getTaskId()); + removeTaskStatus(it->second->getSpaceId(), it->second->getJobId(), it->second->getTaskId()); FLOG_INFO("task(%d, %d) cancelled", jobId, handle.second); } ++it; @@ -170,22 +175,6 @@ nebula::cpp2::ErrorCode AdminTaskManager::cancelJob(JobID jobId) { return ret; } -nebula::cpp2::ErrorCode AdminTaskManager::cancelTask(JobID jobId, TaskID taskId) { - if (taskId < 0) { - return cancelJob(jobId); - } - auto ret = nebula::cpp2::ErrorCode::SUCCEEDED; - TaskHandle handle = std::make_pair(jobId, taskId); - auto it = tasks_.find(handle); - if (it == tasks_.cend()) { - ret = nebula::cpp2::ErrorCode::E_KEY_NOT_FOUND; - } else { - it->second->cancel(); - removeTaskStatus(it->second->getJobId(), it->second->getTaskId()); - } - return ret; -} - void AdminTaskManager::shutdown() { LOG(INFO) << "enter AdminTaskManager::shutdown()"; shutdown_.store(true, std::memory_order_release); @@ -207,12 +196,13 @@ void AdminTaskManager::shutdown() { LOG(INFO) << "exit AdminTaskManager::shutdown()"; } -void AdminTaskManager::saveTaskStatus(JobID jobId, +void AdminTaskManager::saveTaskStatus(GraphSpaceID spaceId, + JobID jobId, TaskID taskId, nebula::cpp2::ErrorCode rc, const nebula::meta::cpp2::StatsItem& result) { if (env_ == nullptr) return; - std::string key = NebulaKeyUtils::adminTaskKey(env_->adminSeqId_, jobId, taskId); + std::string key = NebulaKeyUtils::adminTaskKey(env_->adminSeqId_, spaceId, jobId, taskId); std::string val; val.append(reinterpret_cast(&rc), sizeof(nebula::cpp2::ErrorCode)); std::string resVal; @@ -225,9 +215,9 @@ void AdminTaskManager::saveTaskStatus(JobID jobId, } } -void AdminTaskManager::removeTaskStatus(JobID jobId, TaskID taskId) { +void AdminTaskManager::removeTaskStatus(GraphSpaceID spaceId, JobID jobId, TaskID taskId) { if (env_ == nullptr) return; - std::string key = NebulaKeyUtils::adminTaskKey(env_->adminSeqId_, jobId, taskId); + std::string key = NebulaKeyUtils::adminTaskKey(env_->adminSeqId_, spaceId, jobId, taskId); env_->adminStore_->remove(key); } @@ -346,12 +336,13 @@ void AdminTaskManager::notifyReporting() { unreportedCV_.notify_one(); } -void AdminTaskManager::saveAndNotify(JobID jobId, +void AdminTaskManager::saveAndNotify(GraphSpaceID spaceId, + JobID jobId, TaskID taskId, nebula::cpp2::ErrorCode rc, const nebula::meta::cpp2::StatsItem& result) { std::unique_lock lk(unreportedMutex_); - saveTaskStatus(jobId, taskId, rc, result); + saveTaskStatus(spaceId, jobId, taskId, rc, result); ifAnyUnreported_ = true; unreportedCV_.notify_one(); } @@ -370,7 +361,7 @@ void AdminTaskManager::cancelTasks(GraphSpaceID spaceId) { while (it != tasks_.end()) { if (it->second->getSpaceId() == spaceId) { it->second->cancel(); - removeTaskStatus(it->second->getJobId(), it->second->getTaskId()); + removeTaskStatus(spaceId, it->second->getJobId(), it->second->getTaskId()); FLOG_INFO("cancel task(%d, %d), spaceId: %d", it->first.first, it->first.second, spaceId); } ++it; diff --git a/src/storage/admin/AdminTaskManager.h b/src/storage/admin/AdminTaskManager.h index f8503771650..4541c63d856 100644 --- a/src/storage/admin/AdminTaskManager.h +++ b/src/storage/admin/AdminTaskManager.h @@ -59,8 +59,7 @@ class AdminTaskManager { void invoke(); - nebula::cpp2::ErrorCode cancelJob(JobID jobId); - nebula::cpp2::ErrorCode cancelTask(JobID jobId, TaskID taskId = -1); + nebula::cpp2::ErrorCode cancelTask(JobID jobId); void cancelTasks(GraphSpaceID spaceId); int32_t runningTaskCnt(GraphSpaceID spaceId); @@ -72,18 +71,20 @@ class AdminTaskManager { bool isFinished(JobID jobID, TaskID taskID); - void saveTaskStatus(JobID jobId, + void saveTaskStatus(GraphSpaceID spaceId, + JobID jobId, TaskID taskId, nebula::cpp2::ErrorCode rc, const nebula::meta::cpp2::StatsItem& result); - void removeTaskStatus(JobID jobId, TaskID taskId); + void removeTaskStatus(GraphSpaceID spaceId, JobID jobId, TaskID taskId); void handleUnreportedTasks(); void notifyReporting(); - void saveAndNotify(JobID jobId, + void saveAndNotify(GraphSpaceID spaceId, + JobID jobId, TaskID taskId, nebula::cpp2::ErrorCode rc, const nebula::meta::cpp2::StatsItem& result); diff --git a/src/storage/admin/AdminTaskProcessor.cpp b/src/storage/admin/AdminTaskProcessor.cpp index f517025895a..6738519ffc0 100644 --- a/src/storage/admin/AdminTaskProcessor.cpp +++ b/src/storage/admin/AdminTaskProcessor.cpp @@ -16,9 +16,12 @@ namespace storage { void AdminTaskProcessor::process(const cpp2::AddTaskRequest& req) { auto taskManager = AdminTaskManager::instance(); - auto cb = [taskManager, jobId = req.get_job_id(), taskId = req.get_task_id()]( - nebula::cpp2::ErrorCode errCode, nebula::meta::cpp2::StatsItem& result) { - taskManager->saveAndNotify(jobId, taskId, errCode, result); + auto cb = [taskManager, + spaceId = req.get_para().get_space_id(), + jobId = req.get_job_id(), + taskId = req.get_task_id()](nebula::cpp2::ErrorCode errCode, + nebula::meta::cpp2::StatsItem& result) { + taskManager->saveAndNotify(spaceId, jobId, taskId, errCode, result); }; TaskContext ctx(req, std::move(cb)); @@ -27,8 +30,11 @@ void AdminTaskProcessor::process(const cpp2::AddTaskRequest& req) { nebula::meta::cpp2::StatsItem statsItem; statsItem.status_ref() = nebula::meta::cpp2::JobStatus::RUNNING; // write an initial state of task - taskManager->saveTaskStatus( - ctx.jobId_, ctx.taskId_, nebula::cpp2::ErrorCode::E_TASK_EXECUTION_FAILED, statsItem); + taskManager->saveTaskStatus(ctx.parameters_.get_space_id(), + ctx.jobId_, + ctx.taskId_, + nebula::cpp2::ErrorCode::E_TASK_EXECUTION_FAILED, + statsItem); taskManager->addAsyncTask(task); } else { resp_.code_ref() = nebula::cpp2::ErrorCode::E_INVALID_TASK_PARA; diff --git a/src/storage/admin/RebuildIndexTask.h b/src/storage/admin/RebuildIndexTask.h index 772de08710a..6c889855cb6 100644 --- a/src/storage/admin/RebuildIndexTask.h +++ b/src/storage/admin/RebuildIndexTask.h @@ -47,12 +47,6 @@ class RebuildIndexTask : public AdminTask { const IndexItems& items, kvstore::RateLimiter* rateLimiter) = 0; - void cancel() override { - canceled_ = true; - auto suc = nebula::cpp2::ErrorCode::SUCCEEDED; - rc_.compare_exchange_strong(suc, nebula::cpp2::ErrorCode::E_USER_CANCEL); - } - nebula::cpp2::ErrorCode buildIndexOnOperations(GraphSpaceID space, PartitionID part, kvstore::RateLimiter* rateLimiter); diff --git a/src/storage/admin/StatsTask.h b/src/storage/admin/StatsTask.h index 5b353b7ff1f..9de607e151e 100644 --- a/src/storage/admin/StatsTask.h +++ b/src/storage/admin/StatsTask.h @@ -43,16 +43,6 @@ class StatsTask : public AdminTask { void finish(nebula::cpp2::ErrorCode rc) override; protected: - /** - * @brief Cancel task and set result to be cancelled. - * - */ - void cancel() override { - canceled_ = true; - auto suc = nebula::cpp2::ErrorCode::SUCCEEDED; - rc_.compare_exchange_strong(suc, nebula::cpp2::ErrorCode::E_USER_CANCEL); - } - nebula::cpp2::ErrorCode genSubTask(GraphSpaceID space, PartitionID part, std::unordered_map tags, diff --git a/src/storage/admin/StopAdminTaskProcessor.cpp b/src/storage/admin/StopAdminTaskProcessor.cpp index fa73a5e2f7f..1aef5532728 100644 --- a/src/storage/admin/StopAdminTaskProcessor.cpp +++ b/src/storage/admin/StopAdminTaskProcessor.cpp @@ -13,7 +13,7 @@ namespace storage { void StopAdminTaskProcessor::process(const cpp2::StopTaskRequest& req) { auto taskManager = AdminTaskManager::instance(); - auto rc = taskManager->cancelJob(req.get_job_id()); + auto rc = taskManager->cancelTask(req.get_job_id()); if (rc != nebula::cpp2::ErrorCode::SUCCEEDED) { resp_.code_ref() = rc; diff --git a/src/storage/exec/UpdateNode.h b/src/storage/exec/UpdateNode.h index bea2758a323..876d788952b 100644 --- a/src/storage/exec/UpdateNode.h +++ b/src/storage/exec/UpdateNode.h @@ -384,7 +384,7 @@ class UpdateTagNode : public UpdateNode { * * @param partId * @param vId - * @return folly::Optional BatchHolder encode value. + * @return std::Optional BatchHolder encode value. * @see BatchHolder */ diff --git a/src/storage/test/AdminTaskManagerTest.cpp b/src/storage/test/AdminTaskManagerTest.cpp index 1939e165405..7173eaee892 100644 --- a/src/storage/test/AdminTaskManagerTest.cpp +++ b/src/storage/test/AdminTaskManagerTest.cpp @@ -680,10 +680,10 @@ TEST(TaskManagerTest, cancel_a_task_before_all_sub_task_running) { taskMgr->addAsyncTask(vtask0); - LOG(INFO) << "before taskMgr->cancelTask(1);"; + LOG(INFO) << folly::sformat("Before taskMgr->cancelTask({}).", jobId); fRunTask.wait(); taskMgr->cancelTask(jobId); - LOG(INFO) << "after taskMgr->cancelTask(1);"; + LOG(INFO) << folly::sformat("After taskMgr->cancelTask({}).", jobId); pCancelTask.setValue(0); fFiniTask0.wait(); @@ -786,9 +786,9 @@ TEST(TaskManagerTest, cancel_a_task_while_some_sub_task_running) { taskMgr->addAsyncTask(vtask0); subtask_run_f.wait(); - LOG(INFO) << "before taskMgr->cancelTask(1);"; + LOG(INFO) << folly::sformat("Before taskMgr->cancelTask({}).", jobId); taskMgr->cancelTask(jobId); - LOG(INFO) << "after taskMgr->cancelTask(1);"; + LOG(INFO) << folly::sformat("After taskMgr->cancelTask({}).", jobId); cancel_p.setValue(0); task1_f.wait(); diff --git a/tests/tck/features/index/Index.feature b/tests/tck/features/index/Index.feature index a1e25e6c0a5..ef663791259 100644 --- a/tests/tck/features/index/Index.feature +++ b/tests/tck/features/index/Index.feature @@ -736,8 +736,8 @@ Feature: IndexTest_Vid_String SHOW TAG INDEX STATUS; """ Then the result should contain: - | Name | Index Status | - | "rebuild_tag_space_all_tag_indexes" | "FINISHED" | + | Name | Index Status | + | "all_tag_indexes" | "FINISHED" | When executing query: """ LOOKUP ON id_tag WHERE id_tag.id == 100 YIELD id(vertex) as id @@ -850,8 +850,8 @@ Feature: IndexTest_Vid_String SHOW EDGE INDEX STATUS; """ Then the result should contain: - | Name | Index Status | - | "rebuild_edge_space_all_edge_indexes" | "FINISHED" | + | Name | Index Status | + | "all_edge_indexes" | "FINISHED" | When executing query: """ LOOKUP ON id_edge WHERE id_edge.id == 100 YIELD src(edge) as src, dst(edge) as dst, rank(edge) as rank diff --git a/tests/tck/job/Job.feature b/tests/tck/job/Job.feature index cd41904c8bd..20c4d3bfa20 100644 --- a/tests/tck/job/Job.feature +++ b/tests/tck/job/Job.feature @@ -59,12 +59,12 @@ Feature: Submit job space requirements """ SHOW JOB 123456; """ - Then a ExecutionError should be raised at runtime: Key not existed! + Then a ExecutionError should be raised at runtime: Job not existed in chosen space! When executing query: """ STOP JOB 123456; """ - Then a ExecutionError should be raised at runtime: Key not existed! + Then a ExecutionError should be raised at runtime: Job not existed in chosen space! Scenario: Submit and show jobs Given create a space with following options: @@ -172,12 +172,12 @@ Feature: Submit job space requirements """ SHOW JOB {}; """ - Then an ExecutionError should be raised at runtime:Job not in chosen space! + Then an ExecutionError should be raised at runtime:Job not existed in chosen space! When executing query, fill replace holders with element index of 0 in job_id: """ STOP JOB {}; """ - Then an ExecutionError should be raised at runtime:Job not in chosen space! + Then an ExecutionError should be raised at runtime:Job not existed in chosen space! # This is skipped because it is hard to simulate the situation # When executing query: