From 59c3b31edb2f4b0c399ee036e1a09e141545c040 Mon Sep 17 00:00:00 2001 From: fly_1997 Date: Wed, 19 Jun 2024 20:29:22 +0800 Subject: [PATCH] update version to v1.0.2-1 (cherry picked from commit f8fc1fd7a70ee5a61c1099a17ad2d71d5ca31f99) --- 0001-fix-issues.patch | 1204 ----------------- 0002-refactor-plugin-interface.patch | 1032 -------------- ...s-to-the-new-interface-and-refactor-.patch | 1080 --------------- ...nterfaces-and-add-interface-comments.patch | 121 -- ...ignal-processing-and-singleton-class.patch | 401 ------ ...-add-dynamic-dependencncy-adjustment.patch | 682 ---------- ...isabled-failed-and-pre-enable-illega.patch | 115 -- ...ncy-error-and-add-enable-failed-logs.patch | 138 -- oeAware-manager-v1.0.1.tar.gz | Bin 26719 -> 0 bytes oeAware-manager-v1.0.2.tar.gz | Bin 0 -> 27100 bytes oeAware-manager.spec | 17 +- 11 files changed, 6 insertions(+), 4784 deletions(-) delete mode 100644 0001-fix-issues.patch delete mode 100644 0002-refactor-plugin-interface.patch delete mode 100644 0003-the-client-adapts-to-the-new-interface-and-refactor-.patch delete mode 100644 0004-modify-some-interfaces-and-add-interface-comments.patch delete mode 100644 0005-add-the-SIGINT-signal-processing-and-singleton-class.patch delete mode 100644 0006-add-dynamic-dependencncy-adjustment.patch delete mode 100644 0007-fix-dependency-disabled-failed-and-pre-enable-illega.patch delete mode 100644 0008-fix-dependency-error-and-add-enable-failed-logs.patch delete mode 100644 oeAware-manager-v1.0.1.tar.gz create mode 100644 oeAware-manager-v1.0.2.tar.gz diff --git a/0001-fix-issues.patch b/0001-fix-issues.patch deleted file mode 100644 index ee6b360..0000000 --- a/0001-fix-issues.patch +++ /dev/null @@ -1,1204 +0,0 @@ -From 75c6db6769e7b08c1f842d6984fd3bfb341ab1ad Mon Sep 17 00:00:00 2001 -From: fly_1997 -Date: Wed, 15 May 2024 17:01:35 +0800 -Subject: [PATCH] fix issues - ---- - src/client/CMakeLists.txt | 2 +- - src/client/arg_parse.cpp | 23 ++++---- - src/client/arg_parse.h | 22 ++++---- - src/client/client.cpp | 31 +++++------ - src/client/client.h | 10 ++-- - src/client/cmd_handler.cpp | 41 +++++++------- - src/client/cmd_handler.h | 27 +++++----- - src/client/main.cpp | 1 - - src/client/tcp_socket.cpp | 10 +--- - src/client/tcp_socket.h | 6 ++- - src/common/CMakeLists.txt | 2 +- - src/common/message_protocol.cpp | 34 ++++++------ - src/common/message_protocol.h | 71 +++++++++++++------------ - src/plugin_mgr/CMakeLists.txt | 2 +- - src/plugin_mgr/config.cpp | 16 +++--- - src/plugin_mgr/config.h | 4 +- - src/plugin_mgr/dep_handler.h | 4 +- - src/plugin_mgr/error_code.cpp | 11 ++++ - src/plugin_mgr/error_code.h | 11 ++++ - src/plugin_mgr/instance_run_handler.cpp | 48 ++++++++++++----- - src/plugin_mgr/main.cpp | 2 +- - src/plugin_mgr/message_manager.cpp | 9 ++-- - src/plugin_mgr/message_manager.h | 5 +- - src/plugin_mgr/plugin.h | 4 +- - src/plugin_mgr/plugin_manager.cpp | 37 +++++++------ - 25 files changed, 243 insertions(+), 190 deletions(-) - -diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt -index d584d7d..11f9a5b 100644 ---- a/src/client/CMakeLists.txt -+++ b/src/client/CMakeLists.txt -@@ -1,7 +1,7 @@ - cmake_minimum_required (VERSION 3.22) - project(oeAware-client) - --SET(CMAKE_CXX_FLAGS "-rdynamic -std=c++11 -g -Wl,-z,relro,-z,now") -+SET(CMAKE_CXX_FLAGS "-rdynamic -std=c++11 -g -Wl,-z,relro,-z,now -O2 -Wall -Wextra") - - aux_source_directory(. SOURCE) - include_directories(../common) -diff --git a/src/client/arg_parse.cpp b/src/client/arg_parse.cpp -index 805f5a7..947c4c4 100644 ---- a/src/client/arg_parse.cpp -+++ b/src/client/arg_parse.cpp -@@ -13,7 +13,7 @@ - #include - #include - --const std::string ArgParse::OPT_STRING = "Qqd:t:l:r:e:"; -+const std::string ArgParse::OPT_STRING = "Qqd:t:l:r:e:i:"; - const struct option ArgParse::long_options[] = { - {"help", no_argument, NULL, 'h'}, - {"load", required_argument, NULL, 'l'}, -@@ -58,7 +58,7 @@ void ArgParse::print_help() { - " -Q query all instances dependencies.\n" - " --query-dep [instance] query the instance dependency.\n" - " --list the list of supported plugins.\n" -- " --install [plugin] install plugin from the list.\n" -+ " -i|--install [plugin] install plugin from the list.\n" - " --help show this help message.\n"; - } - -@@ -69,7 +69,6 @@ void ArgParse::init_opts() { - opts.insert('Q'); - opts.insert('e'); - opts.insert('d'); -- opts.insert('L'); - opts.insert('i'); - opts.insert('t'); - } -@@ -90,13 +89,18 @@ int ArgParse::init(int argc, char *argv[]) { - help = true; - break; - case '?': { -- std::string err; -- err += optopt; -+ std::string opt_string; -+ if (optind == argc) { -+ opt_string += argv[optind - 1]; -+ } else { -+ opt_string += argv[optind]; -+ } - if (!opts.count(optopt)) { -- arg_error("unknown option '-" + err + "'."); -+ arg_error("unknown option '" + opt_string + "'."); - } else{ -- arg_error("option -" + err + " requires an argument."); -+ arg_error("option " + opt_string + " requires an argument."); - } -+ break; - } - default: { - if (opt == 'l' || opt == 'r' || opt == 'q' || opt == 'Q' || opt == 'e' || opt == 'd' || opt == 'L' || opt == 'i') { -@@ -109,19 +113,20 @@ int ArgParse::init(int argc, char *argv[]) { - set_arg(optarg); - } - } -+ break; - } - - } - } - if (cmd == 'l' && type.empty()) { -- arg_error("option '-t' is required."); -+ arg_error("missing arguments."); - } - if (help) { - print_help(); - exit(EXIT_SUCCESS); - } - if (cmd < 0) { -- arg_error("no option."); -+ arg_error("option error."); - } - return cmd; - } -diff --git a/src/client/arg_parse.h b/src/client/arg_parse.h -index 682f0e5..6a0a25b 100644 ---- a/src/client/arg_parse.h -+++ b/src/client/arg_parse.h -@@ -18,20 +18,20 @@ class ArgParse { - public: - static void arg_error(const std::string &msg); - static void print_help(); -- int init(int argc, char *argv[]); -- void init_opts(); -- void set_type(char* _type); -- void set_arg(char* _arg); -- std::string get_type() const { -- return this->type; -+ static int init(int argc, char *argv[]); -+ static void init_opts(); -+ static void set_type(char* _type); -+ static void set_arg(char* _arg); -+ static std::string get_type() { -+ return type; - } -- std::string get_arg() const { -- return this->arg; -+ static std::string get_arg() { -+ return arg; - } - private: -- std::string arg; -- std::string type; -- std::unordered_set opts; -+ static std::string arg; -+ static std::string type; -+ static std::unordered_set opts; - static const std::string OPT_STRING; - static const int MAX_OPT_SIZE = 20; - static const struct option long_options[MAX_OPT_SIZE]; -diff --git a/src/client/client.cpp b/src/client/client.cpp -index 39a0072..afaa189 100644 ---- a/src/client/client.cpp -+++ b/src/client/client.cpp -@@ -11,18 +11,23 @@ - ******************************************************************************/ - #include "client.h" - -+std::string ArgParse::arg; -+std::string ArgParse::type; -+std::unordered_set ArgParse::opts; -+ - void Client::cmd_groups_init() { -- cmd_handler_groups.insert(std::make_pair('l', new LoadHandler())); -- cmd_handler_groups.insert(std::make_pair('q', new QueryHandler())); -- cmd_handler_groups.insert(std::make_pair('r', new RemoveHandler())); -- cmd_handler_groups.insert(std::make_pair('Q', new QueryTopHandler())); -- cmd_handler_groups.insert(std::make_pair('e', new EnabledHandler())); -- cmd_handler_groups.insert(std::make_pair('d', new DisabledHandler())); -- cmd_handler_groups.insert(std::make_pair('L', new ListHandler())); -- cmd_handler_groups.insert(std::make_pair('i', new InstallHandler(arg_parse.get_arg()))); -+ cmd_handler_groups.insert(std::make_pair('l', std::make_shared())); -+ cmd_handler_groups.insert(std::make_pair('q', std::make_shared())); -+ cmd_handler_groups.insert(std::make_pair('r', std::make_shared())); -+ cmd_handler_groups.insert(std::make_pair('Q', std::make_shared())); -+ cmd_handler_groups.insert(std::make_pair('e', std::make_shared())); -+ cmd_handler_groups.insert(std::make_pair('d', std::make_shared())); -+ cmd_handler_groups.insert(std::make_pair('L', std::make_shared())); -+ cmd_handler_groups.insert(std::make_pair('i', std::make_shared())); - } -+ - bool Client::init(int argc, char *argv[]) { -- if ((cmd = arg_parse.init(argc, argv)) < 0) { -+ if ((cmd = ArgParse::init(argc, argv)) < 0) { - return false; - } - cmd_groups_init(); -@@ -34,8 +39,8 @@ void Client::run_cmd() { - Msg res; - MessageHeader header; - this->cmd_handler = cmd_handler_groups[cmd]; -- this->cmd_handler->handler(arg_parse, msg); -- if(!this->tcp_socket.send_msg(msg)) { -+ this->cmd_handler->handler(msg); -+ if(!this->tcp_socket.send_msg(msg, header)) { - return; - } - if (!this->tcp_socket.recv_msg(res, header)) { -@@ -43,7 +48,3 @@ void Client::run_cmd() { - } - this->cmd_handler->res_handler(res); - } -- --void Client::close() { -- tcp_socket.clear(); --} -diff --git a/src/client/client.h b/src/client/client.h -index 9e60251..82cf613 100644 ---- a/src/client/client.h -+++ b/src/client/client.h -@@ -14,14 +14,11 @@ - #include "tcp_socket.h" - #include "cmd_handler.h" - #include -+#include - - class Client { - public: - Client() : cmd_handler(nullptr) { } -- ~Client() { -- if (cmd_handler) -- delete cmd_handler; -- } - bool init(int argc, char *argv[]); - void run_cmd(); - void close(); -@@ -30,9 +27,8 @@ private: - - int cmd; - TcpSocket tcp_socket; -- ArgParse arg_parse; -- CmdHandler *cmd_handler; -- std::unordered_map cmd_handler_groups; -+ std::shared_ptr cmd_handler; -+ std::unordered_map> cmd_handler_groups; - }; - - #endif // !CLIENT_H -diff --git a/src/client/cmd_handler.cpp b/src/client/cmd_handler.cpp -index b410968..6f3f760 100644 ---- a/src/client/cmd_handler.cpp -+++ b/src/client/cmd_handler.cpp -@@ -15,16 +15,16 @@ - - std::unordered_set LoadHandler::types = {"collector", "scenario", "tune"}; - --void LoadHandler::check(const std::string &arg, const std::string &type) { -+void LoadHandler::check(const std::string &type) { - if (!types.count(type)) { - ArgParse::arg_error("type '" + type + "' is not supported."); - } - } - --void LoadHandler::handler(const ArgParse &arg_parse, Msg &msg) { -- std::string arg = arg_parse.get_arg(); -- std::string type = arg_parse.get_type(); -- check(arg, type); -+void LoadHandler::handler(Msg &msg) { -+ std::string arg = ArgParse::get_arg(); -+ std::string type = ArgParse::get_type(); -+ check(type); - msg.add_payload(arg); - msg.add_payload(type); - msg.set_opt(Opt::LOAD); -@@ -47,8 +47,8 @@ void LoadHandler::res_handler(Msg &msg) { - - } - --void QueryHandler::handler(const ArgParse &arg_parse, Msg &msg) { -- std::string arg = arg_parse.get_arg(); -+void QueryHandler::handler(Msg &msg) { -+ std::string arg = ArgParse::get_arg(); - if (arg.empty()) { - msg.set_opt(Opt::QUERY_ALL); - } else { -@@ -80,8 +80,8 @@ void QueryHandler::res_handler(Msg &msg) { - print_format(); - } - --void RemoveHandler::handler(const ArgParse &arg_parse, Msg &msg) { -- std::string arg = arg_parse.get_arg(); -+void RemoveHandler::handler(Msg &msg) { -+ std::string arg = ArgParse::get_arg(); - msg.add_payload(arg); - msg.set_opt(Opt::REMOVE); - } -@@ -106,8 +106,8 @@ void write_to_file(const std::string &file_name, const std::string &text) { - out.close(); - } - --void QueryTopHandler::handler(const ArgParse &arg_parse, Msg &msg) { -- std::string arg = arg_parse.get_arg(); -+void QueryTopHandler::handler(Msg &msg) { -+ std::string arg = ArgParse::get_arg(); - if (arg.empty()) { - msg.set_opt(Opt::QUERY_ALL_TOP); - } else { -@@ -127,8 +127,8 @@ void QueryTopHandler::res_handler(Msg &msg) { - std::cout << "Generate dependencies graph dep.png.\n"; - } - --void EnabledHandler::handler(const ArgParse &arg_parse, Msg &msg) { -- std::string arg = arg_parse.get_arg(); -+void EnabledHandler::handler(Msg &msg) { -+ std::string arg = ArgParse::get_arg(); - msg.add_payload(arg); - msg.set_opt(Opt::ENABLED); - } -@@ -141,8 +141,8 @@ void EnabledHandler::res_handler(Msg &msg) { - } - } - --void DisabledHandler::handler(const ArgParse &arg_parse, Msg &msg) { -- std::string arg = arg_parse.get_arg(); -+void DisabledHandler::handler(Msg &msg) { -+ std::string arg = ArgParse::get_arg(); - msg.add_payload(arg); - msg.set_opt(Opt::DISABLED); - } -@@ -155,7 +155,7 @@ void DisabledHandler::res_handler(Msg &msg) { - } - } - --void ListHandler::handler(const ArgParse &arg_parse, Msg &msg) { -+void ListHandler::handler(Msg &msg) { - msg.set_opt(Opt::LIST); - } - -@@ -172,18 +172,19 @@ void ListHandler::res_handler(Msg &msg) { - std::cout << "------------------------------------------------------------\n"; - } - --void InstallHandler::handler(const ArgParse &arg_parse, Msg &msg) { -- std::string arg = arg_parse.get_arg(); -+void InstallHandler::handler(Msg &msg) { -+ std::string arg = ArgParse::get_arg(); - msg.set_opt(Opt::DOWNLOAD); - msg.add_payload(arg); - } - - void InstallHandler::res_handler(Msg &msg) { -+ std::string arg = ArgParse::get_arg(); - if (msg.get_opt() == Opt::RESPONSE_ERROR) { -- std::cout << "Download failed, because " << msg.payload(0) <<": " << this->arg.c_str() << '\n'; -+ std::cout << "Download failed, because " << msg.payload(0) <<": " << arg.c_str() << '\n'; - return; - } -- std::string path = this->arg; -+ std::string path = arg; - std::string url = msg.payload(0); - if (!download(url, path)) { - std::cout << "Download failed, please check url or your network.\n"; -diff --git a/src/client/cmd_handler.h b/src/client/cmd_handler.h -index 1b6f1c1..2e32098 100644 ---- a/src/client/cmd_handler.h -+++ b/src/client/cmd_handler.h -@@ -19,23 +19,25 @@ - - class CmdHandler { - public: -- virtual void handler(const ArgParse &arg_parse, Msg &msg) = 0; -+ virtual void handler(Msg &msg) = 0; - virtual void res_handler(Msg &msg) = 0; --private: -+ -+ static ArgParse &arg_parse; - }; - - class LoadHandler : public CmdHandler { - public: -- void handler(const ArgParse &arg_parse, Msg &msg) override; -+ // LoadHandler(const ArgParse &arg_parse) { } -+ void handler(Msg &msg) override; - void res_handler(Msg &msg) override; - private: -- void check(const std::string &arg, const std::string &type); -+ void check(const std::string &type); - static std::unordered_set types; - }; - - class QueryHandler : public CmdHandler { - public: -- void handler(const ArgParse &arg_parse, Msg &msg) override; -+ void handler(Msg &msg) override; - void res_handler(Msg &msg) override; - private: - void print_format(); -@@ -43,42 +45,39 @@ private: - - class RemoveHandler : public CmdHandler { - public: -- void handler(const ArgParse &arg_parse, Msg &msg) override; -+ void handler(Msg &msg) override; - void res_handler(Msg &msg) override; - }; - - - class QueryTopHandler : public CmdHandler { - public: -- void handler(const ArgParse &arg_parse, Msg &msg) override; -+ void handler(Msg &msg) override; - void res_handler(Msg &msg) override; - }; - - class EnabledHandler : public CmdHandler { - public: -- void handler(const ArgParse &arg_parse, Msg &msg) override; -+ void handler(Msg &msg) override; - void res_handler(Msg &msg) override; - }; - - class DisabledHandler : public CmdHandler { - public: -- void handler(const ArgParse &arg_parse, Msg &msg) override; -+ void handler(Msg &msg) override; - void res_handler(Msg &msg) override; - }; - - class ListHandler : public CmdHandler { - public: -- void handler(const ArgParse &arg_parse, Msg &msg) override; -+ void handler(Msg &msg) override; - void res_handler(Msg &msg) override; - }; - - class InstallHandler : public CmdHandler { - public: -- InstallHandler(const std::string &arg) : arg(arg) { } -- void handler(const ArgParse &arg_parse, Msg &msg) override; -+ void handler(Msg &msg) override; - void res_handler(Msg &msg) override; --private: -- std::string arg; - }; - - #endif // !CLIENT_CMD_HANDLER_H -diff --git a/src/client/main.cpp b/src/client/main.cpp -index 62b7ca5..e47c523 100644 ---- a/src/client/main.cpp -+++ b/src/client/main.cpp -@@ -17,6 +17,5 @@ int main(int argc, char *argv[]) { - exit(EXIT_FAILURE); - } - client.run_cmd(); -- client.close(); - return 0; - } -diff --git a/src/client/tcp_socket.cpp b/src/client/tcp_socket.cpp -index d0721cc..7781183 100644 ---- a/src/client/tcp_socket.cpp -+++ b/src/client/tcp_socket.cpp -@@ -15,7 +15,7 @@ - - bool TcpSocket::recv_msg(Msg &res, MessageHeader &header) { - MessageProtocol proto; -- if (handle_request(stream, proto) < 0) { -+ if (!handle_request(stream, proto)) { - printf("can't connect to server!\n"); - return false; - } -@@ -24,8 +24,7 @@ bool TcpSocket::recv_msg(Msg &res, MessageHeader &header) { - return true; - } - --bool TcpSocket::send_msg(Msg &msg) { -- MessageHeader header; -+bool TcpSocket::send_msg(Msg &msg, MessageHeader &header) { - if (!send_response(stream, msg, header)) { - return false; - } -@@ -52,13 +51,8 @@ bool TcpSocket::init() { - return -1; - } - if (file_connect(SOCK_PATH.c_str()) < 0) { -- close(sock); - return false; - } - stream.set_sock(sock); - return true; - } -- --void TcpSocket::clear() { -- close(sock); --} -\ No newline at end of file -diff --git a/src/client/tcp_socket.h b/src/client/tcp_socket.h -index fa0073b..1a3dfef 100644 ---- a/src/client/tcp_socket.h -+++ b/src/client/tcp_socket.h -@@ -16,11 +16,13 @@ - class TcpSocket { - public: - TcpSocket() { } -+ ~TcpSocket() { -+ close(sock); -+ } - bool recv_msg(Msg &res, MessageHeader &header); -- bool send_msg(Msg &msg); -+ bool send_msg(Msg &msg, MessageHeader &header); - int file_connect(const char *name); - bool init(); -- void clear(); - private: - int sock; - SocketStream stream; -diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt -index dece483..ac7525b 100644 ---- a/src/common/CMakeLists.txt -+++ b/src/common/CMakeLists.txt -@@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 3.22) - project(common) - - aux_source_directory(. SOURCE) --SET(CMAKE_CXX_FLAGS "-rdynamic -std=c++11 -g -Wl,-z,relro,-z,now") -+SET(CMAKE_CXX_FLAGS "-rdynamic -std=c++11 -g -Wl,-z,relro,-z,now -Wall -Wextra -fPIC -O2") - - - include_directories(/usr/include/yaml-cpp) -diff --git a/src/common/message_protocol.cpp b/src/common/message_protocol.cpp -index 05d437c..a813a6c 100644 ---- a/src/common/message_protocol.cpp -+++ b/src/common/message_protocol.cpp -@@ -13,7 +13,7 @@ - #include - - template --inline ssize_t handle_EINTR(T fn) { -+inline ssize_t handle_error(T fn) { - ssize_t res = 0; - while (true) { - res = fn(); -@@ -25,27 +25,27 @@ inline ssize_t handle_EINTR(T fn) { - return res; - } - --inline ssize_t read_socket(int sock, void *ptr, size_t size, int flags) { -- return handle_EINTR([&]() { -- return recv(sock, ptr, size, flags); -+inline ssize_t read_socket(int sock, void *buf, size_t size, int flags) { -+ return handle_error([&]() { -+ return recv(sock, buf, size, flags); - }); - } - --inline ssize_t send_socket(int sock, const void *ptr, size_t size, int flags) { -- return handle_EINTR([&]() { -- return send(sock, ptr, size, flags); -+inline ssize_t send_socket(int sock, const void *buf, size_t size, int flags) { -+ return handle_error([&]() { -+ return send(sock, buf, size, flags); - }); - } - --ssize_t SocketStream::read(char *ptr, size_t size) { -+ssize_t SocketStream::read(char *buf, size_t size) { - if (read_buff_off < read_buff_content_size) { - auto remaining_size = read_buff_content_size - read_buff_off; - if (size <= remaining_size) { -- memcpy(ptr, read_buff.data() + read_buff_off, size); -+ memcpy(buf, read_buff.data() + read_buff_off, size); - read_buff_off += size; - return size; - } else { -- memcpy(ptr, read_buff.data() + read_buff_off, remaining_size); -+ memcpy(buf, read_buff.data() + read_buff_off, remaining_size); - read_buff_off += remaining_size; - return remaining_size; - } -@@ -56,22 +56,22 @@ ssize_t SocketStream::read(char *ptr, size_t size) { - auto n = read_socket(sock, read_buff.data(), MAX_BUFF_SIZE, 0); - if (n <= 0) { - return n; -- } else if (n < size) { -- memcpy(ptr, read_buff.data(), n); -+ } else if (static_cast(n) < size) { -+ memcpy(buf, read_buff.data(), n); - return n; - } else { -- memcpy(ptr, read_buff.data(), size); -+ memcpy(buf, read_buff.data(), size); - read_buff_off = size; - read_buff_content_size = n; - return size; - } - } else { -- return read_socket(sock, ptr, size, 0); -+ return read_socket(sock, buf, size, 0); - } - } - --ssize_t SocketStream::write(const char *ptr, size_t size) { -- return send_socket(sock, ptr, size, 0); -+ssize_t SocketStream::write(const char *buf, size_t size) { -+ return send_socket(sock, buf, size, 0); - } - - static std::string to_hex(size_t x) { -@@ -80,7 +80,7 @@ static std::string to_hex(size_t x) { - ss << std::hex << std::uppercase << x; - result = ss.str(); - std::string zero = ""; -- for (int i = result.length(); i < sizeof(size_t); ++i) { -+ for (size_t i = result.length(); i < sizeof(size_t); ++i) { - zero += "0"; - } - result = zero + result; -diff --git a/src/common/message_protocol.h b/src/common/message_protocol.h -index 3771298..b2c3c0d 100644 ---- a/src/common/message_protocol.h -+++ b/src/common/message_protocol.h -@@ -44,38 +44,39 @@ enum class Opt { - }; - - class Msg { -- private: -- friend class boost::serialization::access; -- template -- void serialize(Archive &ar, const unsigned int version) { -- ar & _opt; -- ar & _payload; -- } -- public: -- int payload_size() const { -- return this->_payload.size(); -- } -- std::string payload(int id) const { -- return this->_payload[id]; -- } -- Opt opt() { -- return this->_opt; -- } -- void add_payload(std::string &context) { -- this->_payload.emplace_back(context); -- } -- void add_payload(std::string &&context) { -- this->_payload.emplace_back(context); -- } -- void set_opt(Opt opt) { -- this->_opt = opt; -- } -- Opt get_opt() const { -- return this->_opt; -- } -- private: -- Opt _opt; -- std::vector _payload; -+private: -+ friend class boost::serialization::access; -+ template -+ void serialize(Archive &ar, const unsigned int version) { -+ ar & _opt; -+ ar & _payload; -+ } -+public: -+ Msg() { } -+ int payload_size() const { -+ return this->_payload.size(); -+ } -+ std::string payload(int id) const { -+ return this->_payload[id]; -+ } -+ Opt opt() { -+ return this->_opt; -+ } -+ void add_payload(std::string &context) { -+ this->_payload.emplace_back(context); -+ } -+ void add_payload(std::string &&context) { -+ this->_payload.emplace_back(context); -+ } -+ void set_opt(Opt opt) { -+ this->_opt = opt; -+ } -+ Opt get_opt() const { -+ return this->_opt; -+ } -+private: -+ Opt _opt; -+ std::vector _payload; - }; - - class MessageHeader { -@@ -86,6 +87,7 @@ private: - ar & code; - } - public: -+ MessageHeader() { } - void set_state_code(int code) { - this->code = code; - } -@@ -109,8 +111,8 @@ class SocketStream { - public: - SocketStream() : read_buff(MAX_BUFF_SIZE, 0) { } - SocketStream(int sock) : sock(sock), read_buff(MAX_BUFF_SIZE, 0) { } -- ssize_t read(char *ptr, size_t size); -- ssize_t write(const char *ptr, size_t size); -+ ssize_t read(char *buf, size_t size); -+ ssize_t write(const char *buf, size_t size); - void set_sock(int sock) { - this->sock = sock; - } -@@ -135,7 +137,6 @@ std::string encode(const T &msg) { - - template - int decode(T &msg, const std::string &content) { -- int len = 0; - try { - std::stringstream ss(content); - boost::archive::binary_iarchive ia(ss); -diff --git a/src/plugin_mgr/CMakeLists.txt b/src/plugin_mgr/CMakeLists.txt -index a32c800..8642a63 100644 ---- a/src/plugin_mgr/CMakeLists.txt -+++ b/src/plugin_mgr/CMakeLists.txt -@@ -1,7 +1,7 @@ - cmake_minimum_required (VERSION 3.22) - project(oeAware-server) - --SET(CMAKE_CXX_FLAGS "-rdynamic -std=c++11 -g -Wl,-z,relro,-z,now") -+SET(CMAKE_CXX_FLAGS "-rdynamic -std=c++11 -g -Wl,-z,relro,-z,now -Wall -Wextra -O2") - - if("${OEAWARE_DEBUG}" EQUAL 1) - add_definitions(-DOEAWARE_DEBUG) -diff --git a/src/plugin_mgr/config.cpp b/src/plugin_mgr/config.cpp -index f50399b..588eda0 100644 ---- a/src/plugin_mgr/config.cpp -+++ b/src/plugin_mgr/config.cpp -@@ -32,11 +32,11 @@ bool create_dir(const std::string &path) { - - bool check_plugin_list(YAML::Node plugin_list_item) { - if (plugin_list_item["name"].IsNull()) { -- std::cerr << "Warn: null name in plugin_list.\n"; -+ std::cerr << "WARN: null name in plugin_list.\n"; - return false; - } - if (plugin_list_item["url"].IsNull()) { -- std::cerr << "Warn: null url in plugin_list.\n"; -+ std::cerr << "WARN: null url in plugin_list.\n"; - return false; - } - return true; -@@ -60,7 +60,7 @@ bool Config::load(const std::string path) { - if (!node["plugin_list"].IsNull()) { - YAML::Node plugin_list = node["plugin_list"]; - if (plugin_list.IsSequence()) { -- for (int i = 0; i < plugin_list.size(); ++i) { -+ for (size_t i = 0; i < plugin_list.size(); ++i) { - if (!check_plugin_list(plugin_list[i])){ - continue; - } -@@ -81,15 +81,14 @@ bool Config::load(const std::string path) { - if (!node["enable_list"].IsNull()) { - YAML::Node enable_list = node["enable_list"]; - if (enable_list.IsSequence()) { -- for (int i = 0; i < enable_list.size(); ++i) { -- YAML::Node plugin = enable_list[i]["name"]; -+ for (size_t i = 0; i < enable_list.size(); ++i) { - std::string name = enable_list[i]["name"].as(); - YAML::Node instances = enable_list[i]["instances"]; - EnableItem enable_item(name); -- if (instances.IsNull()) { -+ if (!instances.IsDefined() || instances.IsNull()) { - enable_item.set_enabled(true); - } else { -- for (int j = 0; j < instances.size(); ++j) { -+ for (size_t j = 0; j < instances.size(); ++j) { - std::string i_name = instances[j].as(); - enable_item.add_instance(i_name); - } -@@ -118,6 +117,9 @@ std::string get_path(PluginType type) { - case PluginType::TUNE: { - return DEFAULT_TUNE_PATH; - } -+ default: { -+ break; -+ } - } - return ""; - } -\ No newline at end of file -diff --git a/src/plugin_mgr/config.h b/src/plugin_mgr/config.h -index 6d0ee4d..c2d1f37 100644 ---- a/src/plugin_mgr/config.h -+++ b/src/plugin_mgr/config.h -@@ -72,9 +72,9 @@ public: - return this->name; - } - private: -- bool enabled; -- std::string name; - std::vector instance; -+ std::string name; -+ bool enabled; - }; - - class Config { -diff --git a/src/plugin_mgr/dep_handler.h b/src/plugin_mgr/dep_handler.h -index 76abf49..b81d574 100644 ---- a/src/plugin_mgr/dep_handler.h -+++ b/src/plugin_mgr/dep_handler.h -@@ -33,8 +33,8 @@ struct Node { - int cnt; - int real_cnt; - bool state; // dependency closed-loop -- Node() : next(nullptr), head(nullptr), state(true), cnt(0), real_cnt(0) {} -- Node(std::string name): name(name), next(nullptr), head(nullptr), state(true), cnt(0), real_cnt(0) {} -+ Node() : next(nullptr), head(nullptr), cnt(0), real_cnt(0), state(true) {} -+ Node(std::string name): next(nullptr), head(nullptr), name(name), cnt(0), real_cnt(0), state(true) {} - }; - - class DepHandler { -diff --git a/src/plugin_mgr/error_code.cpp b/src/plugin_mgr/error_code.cpp -index 30cc4f8..09f0eb9 100644 ---- a/src/plugin_mgr/error_code.cpp -+++ b/src/plugin_mgr/error_code.cpp -@@ -1,3 +1,14 @@ -+/****************************************************************************** -+ * Copyright (c) 2024 Huawei Technologies Co., Ltd. -+ * oeAware is licensed under Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ ******************************************************************************/ - #include "error_code.h" - - const std::unordered_map ErrorText::error_codes = { -diff --git a/src/plugin_mgr/error_code.h b/src/plugin_mgr/error_code.h -index 7c06054..dd028f3 100644 ---- a/src/plugin_mgr/error_code.h -+++ b/src/plugin_mgr/error_code.h -@@ -1,3 +1,14 @@ -+/****************************************************************************** -+ * Copyright (c) 2024 Huawei Technologies Co., Ltd. -+ * oeAware is licensed under Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, -+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ ******************************************************************************/ - #ifndef PLUGIN_MGR_ERROR_CODE_H - #define PLUGIN_MGR_ERROR_CODE_H - #include -diff --git a/src/plugin_mgr/instance_run_handler.cpp b/src/plugin_mgr/instance_run_handler.cpp -index 862e806..8ba10db 100644 ---- a/src/plugin_mgr/instance_run_handler.cpp -+++ b/src/plugin_mgr/instance_run_handler.cpp -@@ -18,12 +18,18 @@ static void* get_ring_buf(std::shared_ptr instance) { - return nullptr; - } - switch (instance->get_type()) { -- case PluginType::COLLECTOR: -+ case PluginType::COLLECTOR: { - return (std::dynamic_pointer_cast(instance))->get_interface()->get_ring_buf(); -- case PluginType::SCENARIO: -+ } -+ case PluginType::SCENARIO: { - return (std::dynamic_pointer_cast(instance))->get_interface()->get_ring_buf(); -- case PluginType::TUNE: -+ } -+ case PluginType::TUNE: { - break; -+ } -+ default: { -+ break; -+ } - } - return nullptr; - } -@@ -34,7 +40,7 @@ static void reflash_ring_buf(std::shared_ptr instance) { - - void InstanceRunHandler::run_aware(std::shared_ptr instance, std::vector &deps) { - void *a[MAX_DEPENDENCIES_SIZE]; -- for (int i = 0; i < deps.size(); ++i) { -+ for (size_t i = 0; i < deps.size(); ++i) { - std::shared_ptr ins = memory_store.get_instance(deps[i]); - a[i] = get_ring_buf(ins); - } -@@ -43,7 +49,7 @@ void InstanceRunHandler::run_aware(std::shared_ptr instance, std::vect - - void InstanceRunHandler::run_tune(std::shared_ptr instance, std::vector &deps) { - void *a[MAX_DEPENDENCIES_SIZE]; -- for (int i = 0; i < deps.size(); ++i) { -+ for (size_t i = 0; i < deps.size(); ++i) { - std::shared_ptr ins = memory_store.get_instance(deps[i]); - a[i] = get_ring_buf(ins); - } -@@ -52,36 +58,48 @@ void InstanceRunHandler::run_tune(std::shared_ptr instance, std::vecto - - void InstanceRunHandler::insert_instance(std::shared_ptr instance) { - switch (instance->get_type()) { -- case PluginType::COLLECTOR: -+ case PluginType::COLLECTOR: { - collector[instance->get_name()] = instance; - (std::dynamic_pointer_cast(instance))->get_interface()->enable(); - break; -- case PluginType::SCENARIO: -+ } -+ case PluginType::SCENARIO: { - scenario[instance->get_name()] = instance; - (std::dynamic_pointer_cast(instance))->get_interface()->enable(); - break; -- case PluginType::TUNE: -+ } -+ case PluginType::TUNE: { - tune[instance->get_name()] = instance; - (std::dynamic_pointer_cast(instance))->get_interface()->enable(); - break; -+ } -+ default: { -+ break; -+ } - } - INFO("[PluginManager] " << instance->get_name() << " instance insert into running queue."); - } - - void InstanceRunHandler::delete_instance(std::shared_ptr instance) { - switch (instance->get_type()) { -- case PluginType::COLLECTOR: -+ case PluginType::COLLECTOR: { - collector.erase(instance->get_name()); - (std::dynamic_pointer_cast(instance))->get_interface()->disable(); - break; -- case PluginType::SCENARIO: -+ } -+ case PluginType::SCENARIO: { - scenario.erase(instance->get_name()); - (std::dynamic_pointer_cast(instance))->get_interface()->disable(); - break; -- case PluginType::TUNE: -+ } -+ case PluginType::TUNE: { - tune.erase(instance->get_name()); - (std::dynamic_pointer_cast(instance))->get_interface()->disable(); - break; -+ } -+ default: { -+ break; -+ } - } - INFO("[PluginManager] " << instance->get_name() << " instance delete from running queue."); - } -@@ -91,12 +109,14 @@ void InstanceRunHandler::handle_instance() { - while(this->recv_queue_try_pop(msg)){ - std::shared_ptr instance = msg.get_instance(); - switch (msg.get_type()){ -- case RunType::ENABLED: -+ case RunType::ENABLED: { - insert_instance(std::move(instance)); - break; -- case RunType::DISABLED: -+ } -+ case RunType::DISABLED: { - delete_instance(std::move(instance)); - break; -+ } - } - } - } -@@ -107,7 +127,7 @@ static std::vector get_deps(std::shared_ptr instance) { - std::string deps = (t_instance)->get_interface()->get_dep(); - std::string dep = ""; - std::vector vec; -- for (int i = 0; i < deps.length(); ++i) { -+ for (size_t i = 0; i < deps.length(); ++i) { - if (deps[i] != '-') { - dep += deps[i]; - }else { -diff --git a/src/plugin_mgr/main.cpp b/src/plugin_mgr/main.cpp -index 92f48bb..4e6acdc 100644 ---- a/src/plugin_mgr/main.cpp -+++ b/src/plugin_mgr/main.cpp -@@ -48,7 +48,7 @@ int main(int argc, char **argv) { - SafeQueue res_msg; - INFO("[MessageManager] Start message manager!"); - MessageManager message_manager(&handler_msg, &res_msg); -- message_manager.init(&config); -+ message_manager.init(); - message_manager.run(); - INFO("[PluginManager] Start plugin manager!"); - PluginManager plugin_manager(config, handler_msg, res_msg); -diff --git a/src/plugin_mgr/message_manager.cpp b/src/plugin_mgr/message_manager.cpp -index f081f20..815122c 100644 ---- a/src/plugin_mgr/message_manager.cpp -+++ b/src/plugin_mgr/message_manager.cpp -@@ -44,7 +44,6 @@ bool TcpSocket::init() { - return false; - } - if (domain_listen(path.c_str()) < 0) { -- close(sock); - return false; - } - epfd = epoll_create(1); -@@ -52,6 +51,9 @@ bool TcpSocket::init() { - ev.events = EPOLLIN; - ev.data.fd = sock; - int ret = epoll_ctl(epfd, EPOLL_CTL_ADD, sock, &ev); -+ if (ret < 0) { -+ return false; -+ } - return true; - - } -@@ -64,7 +66,7 @@ static void send_msg(Msg &msg, SafeQueue *handler_msg) { - } - handler_msg->push(message); - } --static void recv_msg(Msg &msg, MessageHeader &header, SafeQueue *res_msg) { -+static void recv_msg(Msg &msg, SafeQueue *res_msg) { - Message res; - res_msg->wait_and_pop(res); - msg.set_opt(res.get_opt()); -@@ -76,7 +78,6 @@ static void recv_msg(Msg &msg, MessageHeader &header, SafeQueue *res_ms - void TcpSocket::serve_accept(SafeQueue *handler_msg, SafeQueue *res_msg){ - struct epoll_event evs[MAX_EVENT_SIZE]; - int sz = sizeof(evs) / sizeof(struct epoll_event); -- char buf[MAX_RECV_BUFF_SIZE]; - while (true) { - int num = epoll_wait(epfd, evs, sz, -1); - for (int i = 0; i < num; ++i) { -@@ -102,7 +103,7 @@ void TcpSocket::serve_accept(SafeQueue *handler_msg, SafeQueue - } - decode(client_msg, msg_protocol.body); - send_msg(client_msg, handler_msg); -- recv_msg(internal_msg, header, res_msg); -+ recv_msg(internal_msg, res_msg); - if (!send_response(stream, internal_msg, header)) { - WARN("[MessageManager] send msg to client failed!"); - } -diff --git a/src/plugin_mgr/message_manager.h b/src/plugin_mgr/message_manager.h -index 4cd7311..416be48 100644 ---- a/src/plugin_mgr/message_manager.h -+++ b/src/plugin_mgr/message_manager.h -@@ -62,6 +62,9 @@ private: - class TcpSocket { - public: - TcpSocket() {} -+ ~TcpSocket() { -+ close(sock); -+ } - bool init(); - void serve_accept(SafeQueue *handler_msg, SafeQueue *res_msg); - private: -@@ -77,7 +80,7 @@ public: - this->handler_msg = handler_msg; - this->res_msg = res_msg; - } -- void init(Config *config){ -+ void init(){ - this->tcp_socket = new TcpSocket(); - } - void run(); -diff --git a/src/plugin_mgr/plugin.h b/src/plugin_mgr/plugin.h -index a2a1815..d59ab8a 100644 ---- a/src/plugin_mgr/plugin.h -+++ b/src/plugin_mgr/plugin.h -@@ -148,10 +148,10 @@ public: - return handler; - } - private: -- void *handler; - std::vector> instances; -- PluginType type; - std::string name; -+ PluginType type; -+ void *handler; - }; - - #endif -diff --git a/src/plugin_mgr/plugin_manager.cpp b/src/plugin_mgr/plugin_manager.cpp -index 77acc40..5324512 100644 ---- a/src/plugin_mgr/plugin_manager.cpp -+++ b/src/plugin_mgr/plugin_manager.cpp -@@ -34,7 +34,7 @@ ErrorCode PluginManager::remove(const std::string &name) { - } - std::shared_ptr plugin = memory_store.get_plugin(name); - std::vector instance_names; -- for (int i = 0; i < plugin->get_instance_len(); ++i) { -+ for (size_t i = 0; i < plugin->get_instance_len(); ++i) { - std::shared_ptr instance = plugin->get_instance(i); - std::string iname = instance->get_name(); - if (instance->get_enabled()) { -@@ -57,7 +57,7 @@ ErrorCode PluginManager::query_all_plugins(std::string &res) { - std::vector> all_plugins = memory_store.get_all_plugins(); - for (auto &p : all_plugins) { - res += p->get_name() + "\n"; -- for (int i = 0; i < p->get_instance_len(); ++i) { -+ for (size_t i = 0; i < p->get_instance_len(); ++i) { - std::string info = p->get_instance(i)->get_info(); - res += "\t" + info + "\n"; - } -@@ -71,7 +71,7 @@ ErrorCode PluginManager::query_plugin(const std::string &name, std::string &res) - } - std::shared_ptr plugin = memory_store.get_plugin(name); - res += name + "\n"; -- for (int i = 0; i < plugin->get_instance_len(); ++i) { -+ for (size_t i = 0; i < plugin->get_instance_len(); ++i) { - std::string info = plugin->get_instance(i)->get_info(); - res += "\t" + info + "\n"; - } -@@ -92,7 +92,6 @@ int PluginManager::load_dl_instance(std::shared_ptr plugin, T **interfac - - template - std::vector get_dep(T *interface) { -- int dep_len = 0; - char *deps = interface->get_dep(); - std::vector res; - std::string dep; -@@ -152,12 +151,16 @@ bool PluginManager::load_instance(std::shared_ptr plugin) { - save_instance(plugin, interface_list, len); - break; - } -- case PluginType::TUNE: -+ case PluginType::TUNE: { - TuneInterface *interface_list = nullptr; - len = load_dl_instance(plugin, &interface_list); - if (len == -1) return false; - save_instance(plugin, interface_list, len); - break; -+ } -+ default: { -+ return false; -+ } - } - update_instance_state(); - return true; -@@ -211,9 +214,13 @@ std::string generate_dot(MemoryStore &memory_store, const std::vectorget_plugin_name()].insert(vec[1]); -- res += vec[0] + "->" + vec[1] + ";"; -+ if (memory_store.is_instance_exist(vec[1])) { -+ instance = memory_store.get_instance(vec[1]); -+ sub_graph[instance->get_plugin_name()].insert(vec[1]); -+ } else { -+ res += vec[1] + "[label=\"(missing)\\n" + vec[1] + "\", fontcolor=red];\n"; -+ } -+ res += vec[0] + "->" + vec[1] + ";\n"; - } - int id = 0; - for (auto &p : sub_graph) { -@@ -339,7 +346,7 @@ ErrorCode PluginManager::download(const std::string &name, std::string &res) { - } - - void PluginManager::pre_enable() { -- for (int i = 0; i < config.get_enable_list_size(); ++i) { -+ for (size_t i = 0; i < config.get_enable_list_size(); ++i) { - EnableItem item = config.get_enable_list(i); - if (item.get_enabled()) { - std::string name = item.get_name(); -@@ -348,11 +355,11 @@ void PluginManager::pre_enable() { - continue; - } - std::shared_ptr plugin = memory_store.get_plugin(name); -- for (int j = 0; j < plugin->get_instance_len(); ++j) { -+ for (size_t j = 0; j < plugin->get_instance_len(); ++j) { - instance_enabled(plugin->get_instance(j)->get_name()); - } - } else { -- for (int j = 0; j < item.get_instance_size(); ++j) { -+ for (size_t j = 0; j < item.get_instance_size(); ++j) { - std::string name = item.get_instance_name(j); - if (!memory_store.is_instance_exist(name)) { - WARN("[PluginManager] instance " << name << " cannot be enabled, because it does not exist."); -@@ -410,7 +417,7 @@ void* PluginManager::get_data_buffer(std::string name) { - std::string PluginManager::instance_dep_check(const std::string &name) { - std::shared_ptr plugin = memory_store.get_plugin(name); - std::string res; -- for (int i = 0; i < plugin->get_instance_len(); ++i) { -+ for (size_t i = 0; i < plugin->get_instance_len(); ++i) { - std::string instance_name = plugin->get_instance(i)->get_name(); - std::vector> query; - dep_handler.query_node(instance_name, query); -@@ -422,9 +429,9 @@ std::string PluginManager::instance_dep_check(const std::string &name) { - } - } - if (!lack.empty()) { -- for (int i = 0; i < lack.size(); ++i) { -- res += "\t" + lack[i]; -- if (i != lack.size() - 1) res += '\n'; -+ for (size_t j = 0; j < lack.size(); ++j) { -+ res += "\t" + lack[j]; -+ if (j != lack.size() - 1) res += '\n'; - } - } - } --- -2.33.0 - diff --git a/0002-refactor-plugin-interface.patch b/0002-refactor-plugin-interface.patch deleted file mode 100644 index db9666a..0000000 --- a/0002-refactor-plugin-interface.patch +++ /dev/null @@ -1,1032 +0,0 @@ -From 3d8160661afa6dfd045dc51577c4bb040c25b591 Mon Sep 17 00:00:00 2001 -From: fly_1997 -Date: Sat, 25 May 2024 15:48:33 +0800 -Subject: [PATCH 1/4] refactor plugin interface - ---- - src/common/default_path.h | 4 +- - src/plugin_mgr/config.cpp | 20 +-- - src/plugin_mgr/config.h | 8 +- - src/plugin_mgr/dep_handler.cpp | 7 +- - src/plugin_mgr/dep_handler.h | 6 +- - src/plugin_mgr/error_code.cpp | 1 + - src/plugin_mgr/error_code.h | 1 + - src/plugin_mgr/instance_run_handler.cpp | 181 ++++-------------------- - src/plugin_mgr/instance_run_handler.h | 25 ++-- - src/plugin_mgr/interface.h | 44 +++--- - src/plugin_mgr/message_manager.h | 2 +- - src/plugin_mgr/plugin.cpp | 23 ++- - src/plugin_mgr/plugin.h | 84 ++--------- - src/plugin_mgr/plugin_manager.cpp | 142 +++++++------------ - src/plugin_mgr/plugin_manager.h | 12 +- - 15 files changed, 166 insertions(+), 394 deletions(-) - -diff --git a/src/common/default_path.h b/src/common/default_path.h -index 4ce68b4..0ef3aae 100644 ---- a/src/common/default_path.h -+++ b/src/common/default_path.h -@@ -14,9 +14,7 @@ - - #include - --const std::string DEFAULT_COLLECTOR_PATH = "/usr/lib64/oeAware-plugin/collector"; --const std::string DEFAULT_SCENARIO_PATH = "/usr/lib64/oeAware-plugin/scenario"; --const std::string DEFAULT_TUNE_PATH = "/usr/lib64/oeAware-plugin/tune"; -+const std::string DEFAULT_PLUGIN_PATH = "/usr/lib64/oeAware-plugin"; - const std::string DEFAULT_RUN_PATH = "/var/run/oeAware"; - const std::string DEFAULT_LOG_PATH = "/var/log/oeAware"; - -diff --git a/src/plugin_mgr/config.cpp b/src/plugin_mgr/config.cpp -index 588eda0..6e0e231 100644 ---- a/src/plugin_mgr/config.cpp -+++ b/src/plugin_mgr/config.cpp -@@ -42,7 +42,7 @@ bool check_plugin_list(YAML::Node plugin_list_item) { - return true; - } - --bool Config::load(const std::string path) { -+bool Config::load(const std::string &path) { - YAML::Node node; - struct stat buffer; - if (stat(path.c_str(), &buffer) != 0) { -@@ -106,20 +106,6 @@ bool Config::load(const std::string path) { - return true; - } - --std::string get_path(PluginType type) { -- switch (type) { -- case PluginType::COLLECTOR:{ -- return DEFAULT_COLLECTOR_PATH; -- } -- case PluginType::SCENARIO: { -- return DEFAULT_SCENARIO_PATH; -- } -- case PluginType::TUNE: { -- return DEFAULT_TUNE_PATH; -- } -- default: { -- break; -- } -- } -- return ""; -+std::string get_path() { -+ return DEFAULT_PLUGIN_PATH; - } -\ No newline at end of file -diff --git a/src/plugin_mgr/config.h b/src/plugin_mgr/config.h -index c2d1f37..3844f71 100644 ---- a/src/plugin_mgr/config.h -+++ b/src/plugin_mgr/config.h -@@ -22,7 +22,7 @@ static int log_levels[] = {0, 10000, 20000, 30000, 40000, 50000, 60000}; - - class PluginInfo { - public: -- PluginInfo(std::string name, std::string description, std::string url) : name(name), description(description), url(url) { } -+ PluginInfo(const std::string &name, const std::string &description, const std::string &url) : name(name), description(description), url(url) { } - std::string get_name() const { - return this->name; - } -@@ -52,7 +52,7 @@ namespace std { - - class EnableItem { - public: -- EnableItem(std::string name) : name(name), enabled(false) { } -+ EnableItem(const std::string &name) : name(name), enabled(false) { } - void set_enabled(bool enabled) { - this->enabled = enabled; - } -@@ -82,7 +82,7 @@ public: - Config() { - this->log_level = log_levels[2]; - } -- bool load(const std::string path); -+ bool load(const std::string &path); - int get_log_level() const { - return this->log_level; - } -@@ -122,7 +122,7 @@ private: - std::vector enable_list; - }; - --std::string get_path(PluginType type); -+std::string get_path(); - bool create_dir(const std::string &path); - - #endif -\ No newline at end of file -diff --git a/src/plugin_mgr/dep_handler.cpp b/src/plugin_mgr/dep_handler.cpp -index 816056d..c6d0985 100644 ---- a/src/plugin_mgr/dep_handler.cpp -+++ b/src/plugin_mgr/dep_handler.cpp -@@ -39,7 +39,7 @@ void DepHandler::add_arc_node(std::shared_ptr node, const std::vector dep_nodes) { -+void DepHandler::add_node(const std::string &name, const std::vector &dep_nodes) { - std::shared_ptr cur_node = add_new_node(name); - this->nodes[name] = cur_node; - add_arc_node(cur_node, dep_nodes); -@@ -52,11 +52,10 @@ void DepHandler::del_node(const std::string &name) { - } - - --std::shared_ptr DepHandler::get_node(std::string name) { -+std::shared_ptr DepHandler::get_node(const std::string &name) { - return this->nodes[name]; - } - -- - std::shared_ptr DepHandler::add_new_node(std::string name) { - std::shared_ptr cur_node = std::make_shared(name); - cur_node->head = std::make_shared(); -@@ -80,6 +79,7 @@ void DepHandler::del_node_and_arc_nodes(std::shared_ptr node) { - arc = tmp; - } - } -+ - void DepHandler::change_arc_nodes(std::string name, bool state) { - if (!nodes[name]->state || !arc_nodes.count(name)) return; - std::unordered_map, bool> &mp = arc_nodes[name]; -@@ -101,7 +101,6 @@ void DepHandler::change_arc_nodes(std::string name, bool state) { - } - } - -- - void DepHandler::query_all_top(std::vector> &query) { - for (auto &p : nodes) { - query_node_top(p.first, query); -diff --git a/src/plugin_mgr/dep_handler.h b/src/plugin_mgr/dep_handler.h -index b81d574..40b8748 100644 ---- a/src/plugin_mgr/dep_handler.h -+++ b/src/plugin_mgr/dep_handler.h -@@ -34,7 +34,7 @@ struct Node { - int real_cnt; - bool state; // dependency closed-loop - Node() : next(nullptr), head(nullptr), cnt(0), real_cnt(0), state(true) {} -- Node(std::string name): next(nullptr), head(nullptr), name(name), cnt(0), real_cnt(0), state(true) {} -+ Node(const std::string &name): next(nullptr), head(nullptr), name(name), cnt(0), real_cnt(0), state(true) {} - }; - - class DepHandler { -@@ -43,11 +43,11 @@ public: - this->head = std::make_shared(); - this->tail = head; - } -- std::shared_ptr get_node(std::string name); -+ std::shared_ptr get_node(const std::string &name); - bool get_node_state(std::string name) { - return this->nodes[name]->state; - } -- void add_node(const std::string &name, std::vector dep_nodes = {}); -+ void add_node(const std::string &name, const std::vector &dep_nodes = {}); - void del_node(const std::string &name); - std::vector get_pre_dependencies(const std::string &name); - // query instance dependency -diff --git a/src/plugin_mgr/error_code.cpp b/src/plugin_mgr/error_code.cpp -index 09f0eb9..8c7af00 100644 ---- a/src/plugin_mgr/error_code.cpp -+++ b/src/plugin_mgr/error_code.cpp -@@ -15,6 +15,7 @@ const std::unordered_map ErrorText::error_codes = { - {ErrorCode::ENABLE_INSTANCE_NOT_LOAD, "instance is not loaded"}, - {ErrorCode::ENABLE_INSTANCE_UNAVAILABLE, "instance is unavailable"}, - {ErrorCode::ENABLE_INSTANCE_ALREADY_ENABLED, "instance is already enabled"}, -+ {ErrorCode::ENABLE_INSTANCE_ENV, "instance init environment failed"}, - {ErrorCode::DISABLE_INSTANCE_NOT_LOAD, "instance is not loaded"}, - {ErrorCode::DISABLE_INSTANCE_UNAVAILABLE, "instance is unavailable"}, - {ErrorCode::DISABLE_INSTANCE_ALREADY_DISABLED, "instance is already disabled"}, -diff --git a/src/plugin_mgr/error_code.h b/src/plugin_mgr/error_code.h -index dd028f3..cdbf542 100644 ---- a/src/plugin_mgr/error_code.h -+++ b/src/plugin_mgr/error_code.h -@@ -18,6 +18,7 @@ enum class ErrorCode { - ENABLE_INSTANCE_NOT_LOAD, - ENABLE_INSTANCE_UNAVAILABLE, - ENABLE_INSTANCE_ALREADY_ENABLED, -+ ENABLE_INSTANCE_ENV, - DISABLE_INSTANCE_NOT_LOAD, - DISABLE_INSTANCE_UNAVAILABLE, - DISABLE_INSTANCE_ALREADY_DISABLED, -diff --git a/src/plugin_mgr/instance_run_handler.cpp b/src/plugin_mgr/instance_run_handler.cpp -index 8ba10db..9eed762 100644 ---- a/src/plugin_mgr/instance_run_handler.cpp -+++ b/src/plugin_mgr/instance_run_handler.cpp -@@ -13,104 +13,45 @@ - #include - #include - --static void* get_ring_buf(std::shared_ptr instance) { -+static const void* get_ring_buf(std::shared_ptr instance) { - if (instance == nullptr) { - return nullptr; - } -- switch (instance->get_type()) { -- case PluginType::COLLECTOR: { -- return (std::dynamic_pointer_cast(instance))->get_interface()->get_ring_buf(); -- } -- case PluginType::SCENARIO: { -- return (std::dynamic_pointer_cast(instance))->get_interface()->get_ring_buf(); -- } -- case PluginType::TUNE: { -- break; -- } -- default: { -- break; -- } -- } -- return nullptr; --} -- --static void reflash_ring_buf(std::shared_ptr instance) { -- (std::dynamic_pointer_cast(instance))->get_interface()->reflash_ring_buf(); --} -- --void InstanceRunHandler::run_aware(std::shared_ptr instance, std::vector &deps) { -- void *a[MAX_DEPENDENCIES_SIZE]; -- for (size_t i = 0; i < deps.size(); ++i) { -- std::shared_ptr ins = memory_store.get_instance(deps[i]); -- a[i] = get_ring_buf(ins); -- } -- (std::dynamic_pointer_cast(instance))->get_interface()->aware(a, (int)deps.size()); -+ return instance->get_interface()->get_ring_buf(); - } - --void InstanceRunHandler::run_tune(std::shared_ptr instance, std::vector &deps) { -- void *a[MAX_DEPENDENCIES_SIZE]; -+void InstanceRunHandler::run_instance(std::shared_ptr instance) { -+ std::vector input_data; -+ std::vector deps = instance->get_deps(); - for (size_t i = 0; i < deps.size(); ++i) { - std::shared_ptr ins = memory_store.get_instance(deps[i]); -- a[i] = get_ring_buf(ins); -+ input_data.emplace_back(get_ring_buf(ins)); - } -- (std::dynamic_pointer_cast(instance))->get_interface()->tune(a, (int)deps.size()); -+ Param param; -+ param.args = input_data.data(); -+ param.len = input_data.size(); -+ instance->get_interface()->run(¶m); - } - --void InstanceRunHandler::insert_instance(std::shared_ptr instance) { -- switch (instance->get_type()) { -- case PluginType::COLLECTOR: { -- collector[instance->get_name()] = instance; -- (std::dynamic_pointer_cast(instance))->get_interface()->enable(); -- break; -- } -- case PluginType::SCENARIO: { -- scenario[instance->get_name()] = instance; -- (std::dynamic_pointer_cast(instance))->get_interface()->enable(); -- break; -- } -- case PluginType::TUNE: { -- tune[instance->get_name()] = instance; -- (std::dynamic_pointer_cast(instance))->get_interface()->enable(); -- break; -- } -- default: { -- break; -- } -- } -+void InstanceRunHandler::insert_instance(std::shared_ptr instance, uint64_t time) { -+ instance->set_enabled(true); -+ schedule_queue.push(ScheduleInstance{instance, time}); - INFO("[PluginManager] " << instance->get_name() << " instance insert into running queue."); - } - - void InstanceRunHandler::delete_instance(std::shared_ptr instance) { -- switch (instance->get_type()) { -- case PluginType::COLLECTOR: { -- collector.erase(instance->get_name()); -- (std::dynamic_pointer_cast(instance))->get_interface()->disable(); -- break; -- } -- case PluginType::SCENARIO: { -- scenario.erase(instance->get_name()); -- (std::dynamic_pointer_cast(instance))->get_interface()->disable(); -- break; -- } -- case PluginType::TUNE: { -- tune.erase(instance->get_name()); -- (std::dynamic_pointer_cast(instance))->get_interface()->disable(); -- break; -- } -- default: { -- break; -- } -- } -+ instance->get_interface()->disable(); -+ instance->set_enabled(false); - INFO("[PluginManager] " << instance->get_name() << " instance delete from running queue."); - } - --void InstanceRunHandler::handle_instance() { -+void InstanceRunHandler::handle_instance(uint64_t time) { - InstanceRunMessage msg; - while(this->recv_queue_try_pop(msg)){ - std::shared_ptr instance = msg.get_instance(); - switch (msg.get_type()){ - case RunType::ENABLED: { -- insert_instance(std::move(instance)); -+ insert_instance(std::move(instance), time); - break; - } - case RunType::DISABLED: { -@@ -121,78 +62,19 @@ void InstanceRunHandler::handle_instance() { - } - } - --template --static std::vector get_deps(std::shared_ptr instance) { -- std::shared_ptr t_instance = std::dynamic_pointer_cast(instance); -- std::string deps = (t_instance)->get_interface()->get_dep(); -- std::string dep = ""; -- std::vector vec; -- for (size_t i = 0; i < deps.length(); ++i) { -- if (deps[i] != '-') { -- dep += deps[i]; -- }else { -- vec.emplace_back(dep); -- dep = ""; -- } -- } -- vec.emplace_back(dep); -- return vec; --} -- --void InstanceRunHandler::adjust_collector_queue(const std::vector &deps, const std::vector &m_deps, bool flag) { -- for (auto &m_dep : m_deps) { -- bool ok = false; -- for (auto &dep : deps) { -- if (m_dep == dep) { -- ok = true; -- } -+void InstanceRunHandler::schedule(uint64_t time) { -+ while (!schedule_queue.empty()) { -+ auto schedule_instance = schedule_queue.top(); -+ if (schedule_instance.time != time) { -+ break; - } -- if (ok) continue; -- if (flag) { -- if (is_instance_exist(m_dep) && !collector.count(m_dep)) { -- this->insert_instance(memory_store.get_instance(m_dep)); -- } -- } else { -- if (is_instance_exist(m_dep) && collector.count(m_dep)) { -- this->delete_instance(memory_store.get_instance(m_dep)); -- } -+ schedule_queue.pop(); -+ if (!schedule_instance.instance->get_enabled()) { -+ break; - } -- } --} -- --void InstanceRunHandler::check_scenario_dependency(const std::vector &origin_deps, const std::vector &cur_deps) { -- adjust_collector_queue(origin_deps, cur_deps, true); -- adjust_collector_queue(cur_deps, origin_deps, false); --} -- --void InstanceRunHandler::schedule_collector(uint64_t time) { -- for (auto &p : collector) { -- std::shared_ptr instance = p.second; -- int t = (std::dynamic_pointer_cast(instance))->get_interface()->get_cycle(); -- if (time % t != 0) return; -- reflash_ring_buf(instance); -- } --} -- --void InstanceRunHandler::schedule_scenario(uint64_t time) { -- for (auto &p : scenario) { -- std::shared_ptr instance = p.second; -- int t = (std::dynamic_pointer_cast(instance))->get_interface()->get_cycle(); -- if (time % t != 0) return; -- std::vector origin_deps = get_deps(instance); -- run_aware(instance, origin_deps); -- std::vector cur_deps = get_deps(instance); -- check_scenario_dependency(origin_deps, cur_deps); -- } --} -- --void InstanceRunHandler::schedule_tune(uint64_t time) { -- for (auto &p : tune) { -- std::shared_ptr instance = p.second; -- int t = (std::dynamic_pointer_cast(instance))->get_interface()->get_cycle(); -- if (time % t != 0) return; -- std::vector deps = get_deps(instance); -- run_tune(instance, deps); -+ run_instance(schedule_instance.instance); -+ schedule_instance.time += schedule_instance.instance->get_interface()->get_cycle(); -+ schedule_queue.push(schedule_instance); - } - } - -@@ -200,11 +82,8 @@ void start(InstanceRunHandler *instance_run_handler) { - unsigned long long time = 0; - INFO("[PluginManager] instance schedule started!"); - while(true) { -- instance_run_handler->handle_instance(); -- instance_run_handler->schedule_collector(time); -- instance_run_handler->schedule_scenario(time); -- instance_run_handler->schedule_tune(time); -- -+ instance_run_handler->handle_instance(time); -+ instance_run_handler->schedule(time); - usleep(instance_run_handler->get_cycle() * 1000); - time += instance_run_handler->get_cycle(); - } -diff --git a/src/plugin_mgr/instance_run_handler.h b/src/plugin_mgr/instance_run_handler.h -index 83f9f4a..4172e99 100644 ---- a/src/plugin_mgr/instance_run_handler.h -+++ b/src/plugin_mgr/instance_run_handler.h -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - #include - - enum class RunType { -@@ -43,15 +44,22 @@ private: - std::shared_ptr instance; - }; - -+class ScheduleInstance { -+public: -+ bool operator < (const ScheduleInstance &rhs) const { -+ return time > rhs.time || (time == rhs.time && instance->get_type() > rhs.instance->get_type()); -+ } -+ std::shared_ptr instance; -+ uint64_t time; -+}; -+ - // A handler to schedule plugin instance - class InstanceRunHandler { - public: - InstanceRunHandler(MemoryStore &memory_store) : memory_store(memory_store), cycle(DEFAULT_CYCLE_SIZE) {} - void run(); -- void schedule_collector(uint64_t time); -- void schedule_scenario(uint64_t time); -- void schedule_tune(uint64_t time); -- void handle_instance(); -+ void schedule(uint64_t time); -+ void handle_instance(uint64_t time); - void set_cycle(int cycle) { - this->cycle = cycle; - } -@@ -71,16 +79,13 @@ public: - return this->recv_queue.try_pop(msg); - } - private: -- void run_aware(std::shared_ptr instance, std::vector &deps); -- void run_tune(std::shared_ptr instance, std::vector &deps); -+ void run_instance(std::shared_ptr instance); - void delete_instance(std::shared_ptr instance); -- void insert_instance(std::shared_ptr instance); -+ void insert_instance(std::shared_ptr instance, uint64_t time); - void adjust_collector_queue(const std::vector &deps, const std::vector &m_deps, bool flag); - void check_scenario_dependency(const std::vector &deps, const std::vector &m_deps); - -- std::unordered_map> collector; -- std::unordered_map> scenario; -- std::unordered_map> tune; -+ std::priority_queue schedule_queue; - SafeQueue recv_queue; - MemoryStore &memory_store; - int cycle; -diff --git a/src/plugin_mgr/interface.h b/src/plugin_mgr/interface.h -index 075378a..2106698 100644 ---- a/src/plugin_mgr/interface.h -+++ b/src/plugin_mgr/interface.h -@@ -12,40 +12,28 @@ - #ifndef PLUGIN_MGR_INTERFACE_H - #define PLUGIN_MGR_INTERFACE_H - --struct CollectorInterface { -- char* (*get_version)(); -- char* (*get_name)(); -- char* (*get_description)(); -- char* (*get_type)(); -- int (*get_cycle)(); -- char* (*get_dep)(); -- void (*enable)(); -- void (*disable)(); -- void* (*get_ring_buf)(); -- void (*reflash_ring_buf)(); -+enum PluginType { -+ COLLECTOR, -+ SCENARIO, -+ TUNE, - }; - --struct ScenarioInterface { -- char* (*get_version)(); -- char* (*get_name)(); -- char* (*get_description)(); -- char* (*get_dep)(); -- int (*get_cycle)(); -- void (*enable)(); -- void (*disable)(); -- void (*aware)(void*[], int); -- void* (*get_ring_buf)(); -+struct Param { -+ void *args; -+ int len; - }; - --struct TuneInterface { -- char* (*get_version)(); -- char* (*get_name)(); -- char* (*get_description)(); -- char* (*get_dep)(); -+struct Interface { -+ const char* (*get_version)(); -+ const char* (*get_name)(); -+ const char* (*get_description)(); -+ const char* (*get_dep)(); -+ PluginType (*get_type)(); - int (*get_cycle)(); -- void (*enable)(); -+ bool (*enable)(); - void (*disable)(); -- void (*tune)(void*[], int); -+ const void* (*get_ring_buf)(); -+ void (*run)(const Param*); - }; - - #endif // !PLUGIN_MGR_INTERFACE_H -diff --git a/src/plugin_mgr/message_manager.h b/src/plugin_mgr/message_manager.h -index 416be48..00ea4c7 100644 ---- a/src/plugin_mgr/message_manager.h -+++ b/src/plugin_mgr/message_manager.h -@@ -31,7 +31,7 @@ public: - Message() : type(MessageType::EXTERNAL) {} - Message(Opt opt) : opt(opt) {} - Message(Opt opt, MessageType type) : opt(opt), type(type) {} -- Message(Opt opt, std::vector payload) : opt(opt), payload(payload) {} -+ Message(Opt opt, const std::vector &payload) : opt(opt), payload(payload) {} - Opt get_opt() { - return this->opt; - } -diff --git a/src/plugin_mgr/plugin.cpp b/src/plugin_mgr/plugin.cpp -index 1a2db0d..bdd8226 100644 ---- a/src/plugin_mgr/plugin.cpp -+++ b/src/plugin_mgr/plugin.cpp -@@ -16,7 +16,7 @@ const std::string Instance::PLUGIN_DISABLED = "close"; - const std::string Instance::PLUGIN_STATE_ON = "available"; - const std::string Instance::PLUGIN_STATE_OFF = "unavailable"; - --int Plugin::load(const std::string dl_path) { -+int Plugin::load(const std::string &dl_path) { - void *handler = dlopen(dl_path.c_str(), RTLD_LAZY); - if (handler == nullptr) { - return -1; -@@ -30,3 +30,24 @@ std::string Instance::get_info() const { - std::string run_text = this->enabled ? PLUGIN_ENABLED : PLUGIN_DISABLED; - return name + "(" + state_text + ", " + run_text + ")"; - } -+ -+std::vector Instance::get_deps() { -+ std::vector vec; -+ if (get_interface()->get_dep == nullptr) { -+ return vec; -+ } -+ std::string deps = get_interface()->get_dep(); -+ std::string dep = ""; -+ for (size_t i = 0; i < deps.length(); ++i) { -+ if (deps[i] != '-') { -+ dep += deps[i]; -+ } else { -+ vec.emplace_back(dep); -+ dep = ""; -+ } -+ } -+ if (!dep.empty()) { -+ vec.emplace_back(dep); -+ } -+ return vec; -+} -diff --git a/src/plugin_mgr/plugin.h b/src/plugin_mgr/plugin.h -index d59ab8a..ac0e0b5 100644 ---- a/src/plugin_mgr/plugin.h -+++ b/src/plugin_mgr/plugin.h -@@ -17,31 +17,21 @@ - #include - #include - --enum class PluginType { -- COLLECTOR, -- SCENARIO, -- TUNE, -- EMPTY, --}; -- --std::string plugin_type_to_string(PluginType type); -- - class Instance { - public: -- virtual ~Instance() = default; -- void set_name(std::string name) { -+ void set_name(const std::string &name) { - this->name = name; - } - std::string get_name() const { - return this->name; - } -- void set_type(PluginType type) { -- this->type = type; -- } - PluginType get_type() const { -- return type; -+ return interface->get_type(); -+ } -+ Interface* get_interface() const { -+ return this->interface; - } -- void set_plugin_name(std::string name) { -+ void set_plugin_name(const std::string &name) { - this->plugin_name = name; - } - std::string get_plugin_name() const { -@@ -59,82 +49,35 @@ public: - bool get_enabled() const { - return this->enabled; - } -+ void set_interface(Interface *interface) { -+ this->interface = interface; -+ } - std::string get_info() const; -+ std::vector get_deps(); - private: - std::string name; - std::string plugin_name; -- PluginType type; - bool state; - bool enabled; -+ Interface *interface; - const static std::string PLUGIN_ENABLED; - const static std::string PLUGIN_DISABLED; - const static std::string PLUGIN_STATE_ON; - const static std::string PLUGIN_STATE_OFF; - }; - --class CollectorInstance : public Instance { --public: -- CollectorInstance() : interface(nullptr) { } -- ~CollectorInstance() { -- interface = nullptr; -- } -- void set_interface(CollectorInterface *interface) { -- this->interface = interface; -- } -- CollectorInterface* get_interface() const { -- return this->interface; -- } --private: -- CollectorInterface* interface; --}; -- --class ScenarioInstance : public Instance { --public: -- ScenarioInstance() : interface(nullptr) { } -- ~ScenarioInstance() { -- interface = nullptr; -- } -- void set_interface(ScenarioInterface *interface) { -- this->interface = interface; -- } -- ScenarioInterface* get_interface() const { -- return this->interface; -- } --private: -- ScenarioInterface* interface; --}; -- --class TuneInstance : public Instance { --public: -- TuneInstance() : interface(nullptr) { } -- ~TuneInstance() { -- interface = nullptr; -- } -- void set_interface(TuneInterface *interface) { -- this->interface = interface; -- } -- TuneInterface* get_interface() const { -- return this->interface; -- } --private: -- TuneInterface *interface; --}; -- - class Plugin { - public: -- Plugin(std::string name, PluginType type) : name(name), type(type), handler(nullptr) { } -+ Plugin(const std::string &name) : name(name), handler(nullptr) { } - ~Plugin() { - if (handler != nullptr) { - dlclose(handler); - } - } -- int load(const std::string dl_path); -+ int load(const std::string &dl_path); - std::string get_name() const { - return this->name; - } -- PluginType get_type() const { -- return this->type; -- } - void add_instance(std::shared_ptr ins) { - instances.emplace_back(ins); - } -@@ -150,7 +93,6 @@ public: - private: - std::vector> instances; - std::string name; -- PluginType type; - void *handler; - }; - -diff --git a/src/plugin_mgr/plugin_manager.cpp b/src/plugin_mgr/plugin_manager.cpp -index 5324512..1503fc1 100644 ---- a/src/plugin_mgr/plugin_manager.cpp -+++ b/src/plugin_mgr/plugin_manager.cpp -@@ -78,9 +78,8 @@ ErrorCode PluginManager::query_plugin(const std::string &name, std::string &res) - return ErrorCode::OK; - } - --template --int PluginManager::load_dl_instance(std::shared_ptr plugin, T **interface_list) { -- int (*get_instance)(T**) = (int(*)(T**))dlsym(plugin->get_handler(), "get_instance"); -+int PluginManager::load_dl_instance(std::shared_ptr plugin, Interface **interface_list) { -+ int (*get_instance)(Interface**) = (int(*)(Interface**))dlsym(plugin->get_handler(), "get_instance"); - if (get_instance == nullptr) { - ERROR("[PluginManager] dlsym error!\n"); - return -1; -@@ -90,78 +89,33 @@ int PluginManager::load_dl_instance(std::shared_ptr plugin, T **interfac - return len; - } - --template --std::vector get_dep(T *interface) { -- char *deps = interface->get_dep(); -- std::vector res; -- std::string dep; -- for (int i = 0; deps[i] != 0; ++i) { -- if (deps[i] != '-') { -- dep += deps[i]; -- } else { -- res.emplace_back(dep); -- dep = ""; -- } -- } -- if (!dep.empty()) res.emplace_back(dep); -- return res; --} -- --template --void PluginManager::save_instance(std::shared_ptr plugin, T *interface_list, int len) { -+void PluginManager::save_instance(std::shared_ptr plugin, Interface *interface_list, int len) { - if (interface_list == nullptr) return; - for (int i = 0; i < len; ++i) { -- T *interface = interface_list + i; -- std::shared_ptr instance = std::make_shared(); -+ Interface *interface = interface_list + i; -+ std::shared_ptr instance = std::make_shared(); - std::string name = interface->get_name(); -+ instance->set_interface(interface); - instance->set_name(name); - instance->set_plugin_name(plugin->get_name()); -- instance->set_type(plugin->get_type()); - instance->set_enabled(false); -- if (plugin->get_type() == PluginType::COLLECTOR) { -- DEBUG("[PluginManager] add node"); -- dep_handler.add_node(name); -- } else { -- dep_handler.add_node(name, get_dep(interface)); -- } -+ dep_handler.add_node(name, instance->get_deps()); - instance->set_state(dep_handler.get_node_state(name)); -- (std::dynamic_pointer_cast(instance))->set_interface(interface); - DEBUG("[PluginManager] Instance: " << name.c_str()); - memory_store.add_instance(name, instance); -- plugin->add_instance(instance); -+ plugin->add_instance(instance); - } - } - - bool PluginManager::load_instance(std::shared_ptr plugin) { - int len = 0; - DEBUG("plugin: " << plugin->get_name()); -- switch (plugin->get_type()) { -- case PluginType::COLLECTOR: { -- CollectorInterface *interface_list = nullptr; -- len = load_dl_instance(plugin, &interface_list); -- if (len == -1) return false; -- DEBUG("[PluginManager] save collect instance"); -- save_instance(plugin, interface_list, len); -- break; -- } -- case PluginType::SCENARIO: { -- ScenarioInterface *interface_list = nullptr; -- len = load_dl_instance(plugin, &interface_list); -- if (len == -1) return false; -- save_instance(plugin, interface_list, len); -- break; -- } -- case PluginType::TUNE: { -- TuneInterface *interface_list = nullptr; -- len = load_dl_instance(plugin, &interface_list); -- if (len == -1) return false; -- save_instance(plugin, interface_list, len); -- break; -- } -- default: { -- return false; -- } -+ Interface *interface_list = nullptr; -+ len = load_dl_instance(plugin, &interface_list); -+ if (len < 0) { -+ return false; - } -+ save_instance(plugin, interface_list, len); - update_instance_state(); - return true; - } -@@ -177,8 +131,8 @@ void PluginManager::update_instance_state() { - } - } - --ErrorCode PluginManager::load_plugin(const std::string &name, PluginType type) { -- std::string plugin_path = get_path(type) + "/" + name; -+ErrorCode PluginManager::load_plugin(const std::string &name) { -+ std::string plugin_path = get_path() + "/" + name; - if (!file_exist(plugin_path)) { - return ErrorCode::LOAD_PLUGIN_FILE_NOT_EXIST; - } -@@ -191,9 +145,8 @@ ErrorCode PluginManager::load_plugin(const std::string &name, PluginType type) { - if (memory_store.is_plugin_exist(name)) { - return ErrorCode::LOAD_PLUGIN_EXIST; - } -- const std::string dl_path = get_path(type) + '/' + name; -- std::shared_ptr plugin = std::make_shared(name, type); -- int error = plugin->load(dl_path); -+ std::shared_ptr plugin = std::make_shared(name); -+ int error = plugin->load(plugin_path); - if (error) { - return ErrorCode::LOAD_PLUGIN_DLOPEN_FAILED; - } -@@ -268,16 +221,35 @@ ErrorCode PluginManager::instance_enabled(std::string name) { - return ErrorCode::ENABLE_INSTANCE_ALREADY_ENABLED; - } - std::vector pre_dependencies = dep_handler.get_pre_dependencies(name); -+ std::vector> new_enabled; -+ bool enabled = true; - for (int i = pre_dependencies.size() - 1; i >= 0; --i) { - instance = memory_store.get_instance(pre_dependencies[i]); - if (instance->get_enabled()) { - continue; - } -- instance->set_enabled(true); -- instance_run_handler->recv_queue_push(InstanceRunMessage(RunType::ENABLED, instance)); -- DEBUG("[PluginManager] " << instance->get_name() << " instance enabled."); -+ new_enabled.emplace_back(instance); -+ if (!instance->get_interface()->enable()) { -+ enabled = false; -+ WARN("[PluginManager] " << instance->get_name() << " instance enabled failed, because instance init environment failed."); -+ break; -+ } -+ } -+ if (enabled) { -+ for (int i = pre_dependencies.size() - 1; i >= 0; --i) { -+ instance = memory_store.get_instance(pre_dependencies[i]); -+ if (instance->get_enabled()) { -+ continue; -+ } -+ instance_run_handler->recv_queue_push(InstanceRunMessage(RunType::ENABLED, instance)); -+ } -+ return ErrorCode::OK; -+ } else { -+ for (auto instance : new_enabled) { -+ instance->get_interface()->disable(); -+ } -+ return ErrorCode::ENABLE_INSTANCE_ENV; - } -- return ErrorCode::OK; - } - - ErrorCode PluginManager::instance_disabled(std::string name) { -@@ -291,7 +263,6 @@ ErrorCode PluginManager::instance_disabled(std::string name) { - if (!instance->get_enabled()) { - return ErrorCode::DISABLE_INSTANCE_ALREADY_DISABLED; - } -- instance->set_enabled(false); - instance_run_handler->recv_queue_push(InstanceRunMessage(RunType::DISABLED, instance)); - return ErrorCode::OK; - } -@@ -331,9 +302,7 @@ ErrorCode PluginManager::add_list(std::string &res) { - res += p.first + "\n"; - } - res += "Installed Plugins:\n"; -- res += get_plugin_in_dir(DEFAULT_COLLECTOR_PATH); -- res += get_plugin_in_dir(DEFAULT_SCENARIO_PATH); -- res += get_plugin_in_dir(DEFAULT_TUNE_PATH); -+ res += get_plugin_in_dir(DEFAULT_PLUGIN_PATH); - return ErrorCode::OK; - } - -@@ -371,15 +340,15 @@ void PluginManager::pre_enable() { - } - } - --void PluginManager::pre_load_plugin(PluginType type) { -- std::string path = get_path(type); -+void PluginManager::pre_load_plugin() { -+ std::string path = get_path(); - DIR *dir = opendir(path.c_str()); - if (dir == nullptr) return; - struct dirent *entry; - while ((entry = readdir(dir)) != nullptr) { - std::string name = entry->d_name; - if (end_with(name, ".so")) { -- auto ret = load_plugin(name, type); -+ auto ret = load_plugin(name); - if (ret != ErrorCode::OK) { - WARN("[PluginManager] " << name << " plugin preload failed, because " << ErrorText::get_error_text(ret) << "."); - } else { -@@ -391,27 +360,13 @@ void PluginManager::pre_load_plugin(PluginType type) { - } - - void PluginManager::pre_load() { -- pre_load_plugin(PluginType::COLLECTOR); -- pre_load_plugin(PluginType::SCENARIO); -- pre_load_plugin(PluginType::TUNE); -+ pre_load_plugin(); - pre_enable(); - } - --void* PluginManager::get_data_buffer(std::string name) { -+const void* PluginManager::get_data_buffer(std::string name) { - std::shared_ptr instance = memory_store.get_instance(name); -- switch (instance->get_type()) { -- case PluginType::COLLECTOR: { -- CollectorInterface *collector_interface = (std::dynamic_pointer_cast(instance))->get_interface(); -- return collector_interface->get_ring_buf(); -- } -- case PluginType::SCENARIO: { -- ScenarioInterface *scenario_interface = (std::dynamic_pointer_cast(instance))->get_interface(); -- return scenario_interface->get_ring_buf(); -- } -- default: -- return nullptr; -- } -- return nullptr; -+ return instance->get_interface()->get_ring_buf(); - } - - std::string PluginManager::instance_dep_check(const std::string &name) { -@@ -465,8 +420,7 @@ int PluginManager::run() { - switch (msg.get_opt()) { - case Opt::LOAD: { - std::string plugin_name = msg.get_payload(0); -- PluginType type = plugin_types[msg.get_payload(1)]; -- ErrorCode ret_code = load_plugin(plugin_name, type); -+ ErrorCode ret_code = load_plugin(plugin_name); - if(ret_code == ErrorCode::OK) { - INFO("[PluginManager] " << plugin_name << " plugin loaded."); - res.set_opt(Opt::RESPONSE_OK); -diff --git a/src/plugin_mgr/plugin_manager.h b/src/plugin_mgr/plugin_manager.h -index 709d42e..9339f0d 100644 ---- a/src/plugin_mgr/plugin_manager.h -+++ b/src/plugin_mgr/plugin_manager.h -@@ -33,10 +33,10 @@ public: - void pre_load(); - void pre_enable(); - void init(); -- void* get_data_buffer(std::string name); -+ const void* get_data_buffer(std::string name); - private: -- void pre_load_plugin(PluginType type); -- ErrorCode load_plugin(const std::string &path, PluginType type); -+ void pre_load_plugin(); -+ ErrorCode load_plugin(const std::string &path); - ErrorCode remove(const std::string &name); - ErrorCode query_all_plugins(std::string &res); - ErrorCode query_plugin(const std::string &name, std::string &res); -@@ -47,10 +47,8 @@ private: - ErrorCode add_list(std::string &res); - ErrorCode download(const std::string &name, std::string &res); - std::string instance_dep_check(const std::string &name); -- template -- int load_dl_instance(std::shared_ptr plugin, T **interface_list); -- template -- void save_instance(std::shared_ptr plugin, T *interface_list, int len); -+ int load_dl_instance(std::shared_ptr plugin, Interface **interface_list); -+ void save_instance(std::shared_ptr plugin, Interface *interface_list, int len); - bool load_instance(std::shared_ptr plugin); - void batch_load(); - void batch_remove(); --- -2.33.0 - diff --git a/0003-the-client-adapts-to-the-new-interface-and-refactor-.patch b/0003-the-client-adapts-to-the-new-interface-and-refactor-.patch deleted file mode 100644 index 1c7f8c2..0000000 --- a/0003-the-client-adapts-to-the-new-interface-and-refactor-.patch +++ /dev/null @@ -1,1080 +0,0 @@ -From 2f00d1f6c4a0dd199cdfb13e9a541c5f87f5cf4e Mon Sep 17 00:00:00 2001 -From: fly_1997 -Date: Tue, 28 May 2024 11:09:13 +0800 -Subject: [PATCH 2/4] the client adapts to the new interface and refactor - memory store - ---- - src/client/arg_parse.cpp | 18 +----- - src/client/arg_parse.h | 4 -- - src/client/client.cpp | 1 - - src/client/cmd_handler.cpp | 7 +-- - src/client/cmd_handler.h | 4 -- - src/common/message_protocol.cpp | 1 - - src/common/message_protocol.h | 4 +- - src/plugin_mgr/config.h | 7 +-- - src/plugin_mgr/dep_handler.cpp | 84 +++++++++++++------------ - src/plugin_mgr/dep_handler.h | 56 ++++++++--------- - src/plugin_mgr/instance_run_handler.cpp | 8 +-- - src/plugin_mgr/instance_run_handler.h | 11 +--- - src/plugin_mgr/interface.h | 33 ++++++++-- - src/plugin_mgr/logger.cpp | 1 - - src/plugin_mgr/main.cpp | 1 - - src/plugin_mgr/memory_store.h | 39 +++++++----- - src/plugin_mgr/message_manager.h | 3 +- - src/plugin_mgr/plugin.cpp | 2 +- - src/plugin_mgr/plugin.h | 2 +- - src/plugin_mgr/plugin_manager.cpp | 75 ++++++++-------------- - src/plugin_mgr/plugin_manager.h | 29 +++------ - 21 files changed, 174 insertions(+), 216 deletions(-) - -diff --git a/src/client/arg_parse.cpp b/src/client/arg_parse.cpp -index 947c4c4..75e9671 100644 ---- a/src/client/arg_parse.cpp -+++ b/src/client/arg_parse.cpp -@@ -13,11 +13,10 @@ - #include - #include - --const std::string ArgParse::OPT_STRING = "Qqd:t:l:r:e:i:"; -+const std::string ArgParse::OPT_STRING = "Qqd:l:r:e:i:"; - const struct option ArgParse::long_options[] = { - {"help", no_argument, NULL, 'h'}, - {"load", required_argument, NULL, 'l'}, -- {"type", required_argument, NULL, 't'}, - {"remove", required_argument, NULL, 'r'}, - {"query", required_argument, NULL, 'q'}, - {"query-dep", required_argument, NULL, 'Q'}, -@@ -34,10 +33,6 @@ void ArgParse::arg_error(const std::string &msg) { - exit(EXIT_FAILURE); - } - --void ArgParse::set_type(char *_type) { -- type = _type; --} -- - void ArgParse::set_arg(char *_arg) { - arg = std::string(_arg); - } -@@ -46,10 +41,6 @@ void ArgParse::print_help() { - std::cout << "usage: oeawarectl [options]...\n" - " options\n" - " -l|--load [plugin] load plugin and need plugin type.\n" -- " -t|--type [plugin_type] assign plugin type. there are three types:\n" -- " collector: collection plugin.\n" -- " scenario: awareness plugin.\n" -- " tune: tune plugin.\n" - " -r|--remove [plugin] remove plugin from system.\n" - " -e|--enable [instance] enable the plugin instance.\n" - " -d|--disable [instance] disable the plugin instance.\n" -@@ -70,7 +61,6 @@ void ArgParse::init_opts() { - opts.insert('e'); - opts.insert('d'); - opts.insert('i'); -- opts.insert('t'); - } - - int ArgParse::init(int argc, char *argv[]) { -@@ -82,9 +72,6 @@ int ArgParse::init(int argc, char *argv[]) { - while((opt = getopt_long(argc, argv, OPT_STRING.c_str(), long_options, nullptr)) != -1) { - std::string full_opt; - switch (opt) { -- case 't': -- set_type(optarg); -- break; - case 'h': - help = true; - break; -@@ -118,9 +105,6 @@ int ArgParse::init(int argc, char *argv[]) { - - } - } -- if (cmd == 'l' && type.empty()) { -- arg_error("missing arguments."); -- } - if (help) { - print_help(); - exit(EXIT_SUCCESS); -diff --git a/src/client/arg_parse.h b/src/client/arg_parse.h -index 6a0a25b..e3e55cd 100644 ---- a/src/client/arg_parse.h -+++ b/src/client/arg_parse.h -@@ -22,15 +22,11 @@ public: - static void init_opts(); - static void set_type(char* _type); - static void set_arg(char* _arg); -- static std::string get_type() { -- return type; -- } - static std::string get_arg() { - return arg; - } - private: - static std::string arg; -- static std::string type; - static std::unordered_set opts; - static const std::string OPT_STRING; - static const int MAX_OPT_SIZE = 20; -diff --git a/src/client/client.cpp b/src/client/client.cpp -index afaa189..6318d5d 100644 ---- a/src/client/client.cpp -+++ b/src/client/client.cpp -@@ -12,7 +12,6 @@ - #include "client.h" - - std::string ArgParse::arg; --std::string ArgParse::type; - std::unordered_set ArgParse::opts; - - void Client::cmd_groups_init() { -diff --git a/src/client/cmd_handler.cpp b/src/client/cmd_handler.cpp -index 6f3f760..009a9bc 100644 ---- a/src/client/cmd_handler.cpp -+++ b/src/client/cmd_handler.cpp -@@ -23,10 +23,7 @@ void LoadHandler::check(const std::string &type) { - - void LoadHandler::handler(Msg &msg) { - std::string arg = ArgParse::get_arg(); -- std::string type = ArgParse::get_type(); -- check(type); - msg.add_payload(arg); -- msg.add_payload(type); - msg.set_opt(Opt::LOAD); - } - -@@ -109,10 +106,10 @@ void write_to_file(const std::string &file_name, const std::string &text) { - void QueryTopHandler::handler(Msg &msg) { - std::string arg = ArgParse::get_arg(); - if (arg.empty()) { -- msg.set_opt(Opt::QUERY_ALL_TOP); -+ msg.set_opt(Opt::QUERY_ALL_DEPS); - } else { - msg.add_payload(arg); -- msg.set_opt(Opt::QUERY_TOP); -+ msg.set_opt(Opt::QUERY_DEP); - } - } - -diff --git a/src/client/cmd_handler.h b/src/client/cmd_handler.h -index 2e32098..53178fd 100644 ---- a/src/client/cmd_handler.h -+++ b/src/client/cmd_handler.h -@@ -13,9 +13,6 @@ - #define CLIENT_CMD_HANDLER_H - #include "message_protocol.h" - #include "arg_parse.h" --#include --#include --#include - - class CmdHandler { - public: -@@ -27,7 +24,6 @@ public: - - class LoadHandler : public CmdHandler { - public: -- // LoadHandler(const ArgParse &arg_parse) { } - void handler(Msg &msg) override; - void res_handler(Msg &msg) override; - private: -diff --git a/src/common/message_protocol.cpp b/src/common/message_protocol.cpp -index a813a6c..9cf9415 100644 ---- a/src/common/message_protocol.cpp -+++ b/src/common/message_protocol.cpp -@@ -10,7 +10,6 @@ - * See the Mulan PSL v2 for more details. - ******************************************************************************/ - #include "message_protocol.h" --#include - - template - inline ssize_t handle_error(T fn) { -diff --git a/src/common/message_protocol.h b/src/common/message_protocol.h -index b2c3c0d..d659f59 100644 ---- a/src/common/message_protocol.h -+++ b/src/common/message_protocol.h -@@ -34,8 +34,8 @@ enum class Opt { - REMOVE, - QUERY, - QUERY_ALL, -- QUERY_TOP, -- QUERY_ALL_TOP, -+ QUERY_DEP, -+ QUERY_ALL_DEPS, - LIST, - DOWNLOAD, - RESPONSE_OK, -diff --git a/src/plugin_mgr/config.h b/src/plugin_mgr/config.h -index 3844f71..9d097ab 100644 ---- a/src/plugin_mgr/config.h -+++ b/src/plugin_mgr/config.h -@@ -13,7 +13,6 @@ - #define PLUGIN_MGR_CONFIG_H - - #include "plugin.h" --#include - #include - #include - #include -@@ -52,7 +51,7 @@ namespace std { - - class EnableItem { - public: -- EnableItem(const std::string &name) : name(name), enabled(false) { } -+ explicit EnableItem(const std::string &name) : name(name), enabled(false) { } - void set_enabled(bool enabled) { - this->enabled = enabled; - } -@@ -86,9 +85,6 @@ public: - int get_log_level() const { - return this->log_level; - } -- int get_schedule_cycle() const { -- return this->schedule_cycle; -- } - std::string get_log_type() const { - return this->log_type; - } -@@ -115,7 +111,6 @@ public: - } - private: - int log_level; -- int schedule_cycle; - std::string log_path; - std::string log_type; - std::unordered_map plugin_list; -diff --git a/src/plugin_mgr/dep_handler.cpp b/src/plugin_mgr/dep_handler.cpp -index c6d0985..1006175 100644 ---- a/src/plugin_mgr/dep_handler.cpp -+++ b/src/plugin_mgr/dep_handler.cpp -@@ -11,39 +11,52 @@ - ******************************************************************************/ - #include "dep_handler.h" - #include --#include --#include - -+bool DepHandler::is_instance_exist(const std::string &name) { -+ return nodes.count(name); -+} -+ -+void DepHandler::add_instance(std::shared_ptr instance) { -+ add_node(instance); -+} -+ -+void DepHandler::delete_instance(const std::string &name) { -+ del_node(name); -+} -+ - void DepHandler::add_arc_node(std::shared_ptr node, const std::vector &dep_nodes) { - std::shared_ptr arc_head = node->head; - node->cnt = dep_nodes.size(); - int real_cnt = 0; -- bool state = true; - for (auto name : dep_nodes) { - std::shared_ptr tmp = std::make_shared(); - tmp->arc_name = name; -- tmp->node_name = node->name; -+ tmp->node_name = node->instance->get_name(); - tmp->next = arc_head->next; - arc_head->next = tmp; - - if (nodes.count(name)) { -- arc_nodes[name][tmp] = true; -+ tmp->is_exist = true; -+ arc_nodes[name].insert(tmp); - real_cnt++; - } else { -- arc_nodes[name][tmp] = false; -- state = false; -+ tmp->is_exist = false; -+ arc_nodes[name].insert(tmp); - } - } -- node->state = state; -+ if (real_cnt == node->cnt) { -+ node->instance->set_state(true); -+ } - node->real_cnt = real_cnt; - } - -- --void DepHandler::add_node(const std::string &name, const std::vector &dep_nodes) { -- std::shared_ptr cur_node = add_new_node(name); -+void DepHandler::add_node(std::shared_ptr instance) { -+ std::string name = instance->get_name(); -+ std::shared_ptr cur_node = add_new_node(instance); - this->nodes[name] = cur_node; -+ std::vector dep_nodes = instance->get_deps(); - add_arc_node(cur_node, dep_nodes); -- change_arc_nodes(name, true); -+ update_instance_state(name); - } - - void DepHandler::del_node(const std::string &name) { -@@ -56,16 +69,14 @@ std::shared_ptr DepHandler::get_node(const std::string &name) { - return this->nodes[name]; - } - --std::shared_ptr DepHandler::add_new_node(std::string name) { -- std::shared_ptr cur_node = std::make_shared(name); -+std::shared_ptr DepHandler::add_new_node(std::shared_ptr instance) { -+ std::shared_ptr cur_node = std::make_shared(); -+ cur_node->instance = instance; - cur_node->head = std::make_shared(); -- tail->next = cur_node; -- tail = cur_node; - return cur_node; - } - - void DepHandler::del_node_and_arc_nodes(std::shared_ptr node) { -- std::shared_ptr next = node->next; - std::shared_ptr arc = node->head; - while(arc) { - std::shared_ptr tmp = arc->next; -@@ -80,34 +91,28 @@ void DepHandler::del_node_and_arc_nodes(std::shared_ptr node) { - } - } - --void DepHandler::change_arc_nodes(std::string name, bool state) { -- if (!nodes[name]->state || !arc_nodes.count(name)) return; -- std::unordered_map, bool> &mp = arc_nodes[name]; -- for (auto &vec : mp) { -- vec.second = state; -- if (nodes.count(vec.first->node_name)) { -- std::shared_ptr tmp = nodes[vec.first->node_name]; -- if (state) { -- tmp->real_cnt++; -- if (tmp->real_cnt == tmp->cnt) { -- tmp->state = true; -- } -- } else { -- tmp->real_cnt--; -- tmp->state = false; -+void DepHandler::update_instance_state(const std::string &name) { -+ if (!nodes[name]->instance->get_state() || !arc_nodes.count(name)) return; -+ std::unordered_set> &arcs = arc_nodes[name]; -+ for (auto &arc_node : arcs) { -+ if (nodes.count(arc_node->node_name)) { -+ auto tmp = nodes[arc_node->node_name]; -+ tmp->real_cnt++; -+ if (tmp->real_cnt == tmp->cnt) { -+ tmp->instance->set_state(true); - } -- change_arc_nodes(vec.first->node_name, state); -+ update_instance_state(tmp->instance->get_name()); - } - } - } - --void DepHandler::query_all_top(std::vector> &query) { -+void DepHandler::query_all_dependencies(std::vector> &query) { - for (auto &p : nodes) { - query_node_top(p.first, query); - } - } - --void DepHandler::query_node_top(std::string name, std::vector> &query) { -+void DepHandler::query_node_top(const std::string &name, std::vector> &query) { - std::shared_ptr p = nodes[name]->head; - if (p->next == nullptr) { - query.emplace_back(std::vector{name}); -@@ -119,7 +124,7 @@ void DepHandler::query_node_top(std::string name, std::vector> &query) { -+void DepHandler::query_node_dependency(const std::string &name, std::vector> &query) { - if (!nodes.count(name)) return; - std::queue q; - std::unordered_set vis; -@@ -128,9 +133,10 @@ void DepHandler::query_node(const std::string &name, std::vector{node->name}); -+ std::string node_name = node->instance->get_name(); -+ query.emplace_back(std::vector{node_name}); - for (auto cur = node->head->next; cur != nullptr; cur = cur->next) { -- query.emplace_back(std::vector{node->name, cur->arc_name}); -+ query.emplace_back(std::vector{node_name, cur->arc_name}); - if (!vis.count(cur->arc_name) && nodes.count(cur->arc_name)) { - vis.insert(cur->arc_name); - q.push(cur->arc_name); -@@ -148,7 +154,7 @@ std::vector DepHandler::get_pre_dependencies(const std::string &nam - while (!q.empty()) { - auto &node = q.front(); - q.pop(); -- res.emplace_back(node->name); -+ res.emplace_back(node->instance->get_name()); - for (auto arc_node = node->head->next; arc_node != nullptr; arc_node = arc_node->next) { - if (!vis.count(arc_node->arc_name)) { - vis.insert(arc_node->arc_name); -diff --git a/src/plugin_mgr/dep_handler.h b/src/plugin_mgr/dep_handler.h -index 40b8748..a7a8ef6 100644 ---- a/src/plugin_mgr/dep_handler.h -+++ b/src/plugin_mgr/dep_handler.h -@@ -12,68 +12,62 @@ - #ifndef PLUGIN_MGR_DEP_HANDLER_H - #define PLUGIN_MGR_DEP_HANDLER_H - -+#include "plugin.h" - #include --#include --#include --#include --#include -+#include - - struct ArcNode { - std::shared_ptr next; - std::string arc_name; - std::string node_name; -- ArcNode() : next(nullptr) {} -+ bool is_exist; -+ ArcNode() : next(nullptr), is_exist(false) { } - }; - - // a instance node - struct Node { - std::shared_ptr next; - std::shared_ptr head; -- std::string name; -+ std::shared_ptr instance; - int cnt; - int real_cnt; -- bool state; // dependency closed-loop -- Node() : next(nullptr), head(nullptr), cnt(0), real_cnt(0), state(true) {} -- Node(const std::string &name): next(nullptr), head(nullptr), name(name), cnt(0), real_cnt(0), state(true) {} -+ Node(): next(nullptr), head(nullptr), cnt(0), real_cnt(0) { } - }; - - class DepHandler { - public: - DepHandler() { - this->head = std::make_shared(); -- this->tail = head; - } - std::shared_ptr get_node(const std::string &name); -- bool get_node_state(std::string name) { -- return this->nodes[name]->state; -+ bool get_node_state(const std::string &name) { -+ return this->nodes[name]->instance->get_state(); - } -- void add_node(const std::string &name, const std::vector &dep_nodes = {}); -- void del_node(const std::string &name); -- std::vector get_pre_dependencies(const std::string &name); -- // query instance dependency -- void query_node(const std::string &name, std::vector> &query); -- // query all instance dependencies -- void query_all_top(std::vector> &query); -+ void add_instance(std::shared_ptr instance); -+ void delete_instance(const std::string &name); -+ bool is_instance_exist(const std::string &name); -+ std::shared_ptr get_instance(const std::string &name) const { -+ return nodes.at(name)->instance; -+ } -+ void query_node_dependency(const std::string &name, std::vector> &query); -+ void query_all_dependencies(std::vector> &query); -+ /* check whether the instance has dependencies */ - bool have_dep(const std::string &name) { - return arc_nodes.count(name); - } -- bool is_empty() const { -- return nodes.empty(); -- } -- size_t get_node_nums() const { -- return nodes.size(); -- } -+ std::vector get_pre_dependencies(const std::string &name); - private: -- void query_node_top(std::string name, std::vector> &query); -+ void add_node(std::shared_ptr instance); -+ void del_node(const std::string &name); -+ void query_node_top(const std::string &name, std::vector> &query); - void add_arc_node(std::shared_ptr node, const std::vector &dep_nodes); -- void change_arc_nodes(std::string name, bool state); -+ void update_instance_state(const std::string &name); - void del_node_and_arc_nodes(std::shared_ptr node); -- std::shared_ptr add_new_node(std::string name); -- -- std::unordered_map, bool>> arc_nodes; -+ std::shared_ptr add_new_node(std::shared_ptr instance); -+ /* indegree edges */ -+ std::unordered_map>> arc_nodes; - std::unordered_map> nodes; - std::shared_ptr head; -- std::shared_ptr tail; - }; - - #endif // !PLUGIN_MGR_DEP_HANDLER_H -diff --git a/src/plugin_mgr/instance_run_handler.cpp b/src/plugin_mgr/instance_run_handler.cpp -index 9eed762..c60207b 100644 ---- a/src/plugin_mgr/instance_run_handler.cpp -+++ b/src/plugin_mgr/instance_run_handler.cpp -@@ -13,7 +13,7 @@ - #include - #include - --static const void* get_ring_buf(std::shared_ptr instance) { -+static const DataRingBuf* get_ring_buf(std::shared_ptr instance) { - if (instance == nullptr) { - return nullptr; - } -@@ -21,14 +21,14 @@ static const void* get_ring_buf(std::shared_ptr instance) { - } - - void InstanceRunHandler::run_instance(std::shared_ptr instance) { -- std::vector input_data; -+ std::vector input_data; - std::vector deps = instance->get_deps(); - for (size_t i = 0; i < deps.size(); ++i) { - std::shared_ptr ins = memory_store.get_instance(deps[i]); - input_data.emplace_back(get_ring_buf(ins)); - } - Param param; -- param.args = input_data.data(); -+ param.ring_bufs = input_data.data(); - param.len = input_data.size(); - instance->get_interface()->run(¶m); - } -@@ -73,7 +73,7 @@ void InstanceRunHandler::schedule(uint64_t time) { - break; - } - run_instance(schedule_instance.instance); -- schedule_instance.time += schedule_instance.instance->get_interface()->get_cycle(); -+ schedule_instance.time += schedule_instance.instance->get_interface()->get_period(); - schedule_queue.push(schedule_instance); - } - } -diff --git a/src/plugin_mgr/instance_run_handler.h b/src/plugin_mgr/instance_run_handler.h -index 4172e99..fc45874 100644 ---- a/src/plugin_mgr/instance_run_handler.h -+++ b/src/plugin_mgr/instance_run_handler.h -@@ -16,19 +16,14 @@ - #include "plugin.h" - #include "logger.h" - #include "memory_store.h" --#include --#include --#include --#include - #include --#include - - enum class RunType { - ENABLED, - DISABLED, - }; - --// Message for communication between plugin manager and instance scheduling -+/* Message for communication between plugin manager and instance scheduling */ - class InstanceRunMessage { - public: - InstanceRunMessage() {} -@@ -53,10 +48,10 @@ public: - uint64_t time; - }; - --// A handler to schedule plugin instance -+/* A handler to schedule instances. */ - class InstanceRunHandler { - public: -- InstanceRunHandler(MemoryStore &memory_store) : memory_store(memory_store), cycle(DEFAULT_CYCLE_SIZE) {} -+ explicit InstanceRunHandler(MemoryStore &memory_store) : memory_store(memory_store), cycle(DEFAULT_CYCLE_SIZE) {} - void run(); - void schedule(uint64_t time); - void handle_instance(uint64_t time); -diff --git a/src/plugin_mgr/interface.h b/src/plugin_mgr/interface.h -index 2106698..6495b92 100644 ---- a/src/plugin_mgr/interface.h -+++ b/src/plugin_mgr/interface.h -@@ -11,6 +11,8 @@ - ******************************************************************************/ - #ifndef PLUGIN_MGR_INTERFACE_H - #define PLUGIN_MGR_INTERFACE_H -+#include -+#include - - enum PluginType { - COLLECTOR, -@@ -18,8 +20,24 @@ enum PluginType { - TUNE, - }; - -+struct DataBuf { -+ int len; -+ void *data; -+}; -+ -+struct DataRingBuf { -+ /* instance name */ -+ const char *instance_name; -+ /* buf write index, initial value is -1 */ -+ int index; -+ /* instance run times */ -+ uint64_t count; -+ struct DataBuf *buf; -+ int buf_len; -+}; -+ - struct Param { -- void *args; -+ const struct DataRingBuf **ring_bufs; - int len; - }; - -@@ -28,12 +46,17 @@ struct Interface { - const char* (*get_name)(); - const char* (*get_description)(); - const char* (*get_dep)(); -- PluginType (*get_type)(); -- int (*get_cycle)(); -+ enum PluginType (*get_type)(); -+ int (*get_period)(); - bool (*enable)(); - void (*disable)(); -- const void* (*get_ring_buf)(); -- void (*run)(const Param*); -+ const struct DataRingBuf* (*get_ring_buf)(); -+ void (*run)(const struct Param*); - }; - -+/* Obtains the instances from the plugin. -+ * The return value is the number of instances. -+ */ -+int get_instance(struct Interface **interface); -+ - #endif // !PLUGIN_MGR_INTERFACE_H -diff --git a/src/plugin_mgr/logger.cpp b/src/plugin_mgr/logger.cpp -index 318eafb..7a924c2 100644 ---- a/src/plugin_mgr/logger.cpp -+++ b/src/plugin_mgr/logger.cpp -@@ -11,7 +11,6 @@ - ******************************************************************************/ - #include "logger.h" - #include --#include - - Logger::Logger() { - logger = log4cplus::Logger::getInstance("oeAware"); -diff --git a/src/plugin_mgr/main.cpp b/src/plugin_mgr/main.cpp -index 4e6acdc..698ba62 100644 ---- a/src/plugin_mgr/main.cpp -+++ b/src/plugin_mgr/main.cpp -@@ -53,7 +53,6 @@ int main(int argc, char **argv) { - INFO("[PluginManager] Start plugin manager!"); - PluginManager plugin_manager(config, handler_msg, res_msg); - plugin_manager.init(); -- plugin_manager.pre_load(); - plugin_manager.run(); - return 0; - } -\ No newline at end of file -diff --git a/src/plugin_mgr/memory_store.h b/src/plugin_mgr/memory_store.h -index ac3ff98..999795a 100644 ---- a/src/plugin_mgr/memory_store.h -+++ b/src/plugin_mgr/memory_store.h -@@ -11,37 +11,36 @@ - ******************************************************************************/ - #ifndef PLUGIN_MGR_MEMORY_STORE_H - #define PLUGIN_MGR_MEMORY_STORE_H --#include "plugin.h" - #include "logger.h" -+#include "dep_handler.h" - #include --#include - --//OeAware memory storage, which is used to store plugins and instances in the memory. -+/* OeAware memory storage, which is used to store plugins and instances in the memory. */ - class MemoryStore { - public: - void add_plugin(const std::string &name, std::shared_ptr plugin) { - this->plugins.insert(std::make_pair(name, plugin)); - } -- void add_instance(const std::string &name, std::shared_ptr instance) { -- this->instances.insert(std::make_pair(name, instance)); -+ void add_instance(std::shared_ptr instance) { -+ dep_handler.add_instance(instance); - } - std::shared_ptr get_plugin(const std::string &name) const { - return this->plugins.at(name); - } - std::shared_ptr get_instance(const std::string &name) const { -- return this->instances.at(name); -+ return dep_handler.get_instance(name); - } - void delete_plugin(const std::string &name) { - this->plugins.erase(name); - } - void delete_instance(const std::string &name) { -- this->instances.erase(name); -+ dep_handler.delete_instance(name); - } - bool is_plugin_exist(const std::string &name) const { - return this->plugins.count(name); - } -- bool is_instance_exist(const std::string &name) const { -- return this->instances.count(name); -+ bool is_instance_exist(const std::string &name) { -+ return dep_handler.is_instance_exist(name); - } - std::vector> get_all_plugins() { - std::vector> res; -@@ -50,16 +49,24 @@ public: - } - return res; - } -- std::vector> get_all_instances() { -- std::vector> res; -- for (auto &p : instances) { -- res.emplace_back(p.second); -- } -- return res; -+ void query_node_dependency(const std::string &name, std::vector> &query) { -+ return dep_handler.query_node_dependency(name, query); -+ } -+ void query_all_dependencies(std::vector> &query) { -+ return dep_handler.query_all_dependencies(query); -+ } -+ bool have_dep(const std::string &name) { -+ return dep_handler.have_dep(name); -+ } -+ std::vector get_pre_dependencies(const std::string &name) { -+ return dep_handler.get_pre_dependencies(name); - } - private: -+ /* instance are stored in the form of DAG. -+ * DepHandler stores instances and manages dependencies. -+ */ -+ DepHandler dep_handler; - std::unordered_map> plugins; -- std::unordered_map> instances; - }; - - #endif // !PLUGIN_MGR_MEMORY_STORE_H -diff --git a/src/plugin_mgr/message_manager.h b/src/plugin_mgr/message_manager.h -index 00ea4c7..95bbd1a 100644 ---- a/src/plugin_mgr/message_manager.h -+++ b/src/plugin_mgr/message_manager.h -@@ -29,7 +29,7 @@ enum class MessageType { - class Message { - public: - Message() : type(MessageType::EXTERNAL) {} -- Message(Opt opt) : opt(opt) {} -+ explicit Message(Opt opt) : opt(opt) {} - Message(Opt opt, MessageType type) : opt(opt), type(type) {} - Message(Opt opt, const std::vector &payload) : opt(opt), payload(payload) {} - Opt get_opt() { -@@ -79,6 +79,7 @@ public: - MessageManager(SafeQueue *handler_msg, SafeQueue *res_msg) { - this->handler_msg = handler_msg; - this->res_msg = res_msg; -+ this->tcp_socket = nullptr; - } - void init(){ - this->tcp_socket = new TcpSocket(); -diff --git a/src/plugin_mgr/plugin.cpp b/src/plugin_mgr/plugin.cpp -index bdd8226..4096fef 100644 ---- a/src/plugin_mgr/plugin.cpp -+++ b/src/plugin_mgr/plugin.cpp -@@ -33,7 +33,7 @@ std::string Instance::get_info() const { - - std::vector Instance::get_deps() { - std::vector vec; -- if (get_interface()->get_dep == nullptr) { -+ if (get_interface()->get_dep == nullptr || get_interface()->get_dep() == nullptr) { - return vec; - } - std::string deps = get_interface()->get_dep(); -diff --git a/src/plugin_mgr/plugin.h b/src/plugin_mgr/plugin.h -index ac0e0b5..f6b5029 100644 ---- a/src/plugin_mgr/plugin.h -+++ b/src/plugin_mgr/plugin.h -@@ -68,7 +68,7 @@ private: - - class Plugin { - public: -- Plugin(const std::string &name) : name(name), handler(nullptr) { } -+ explicit Plugin(const std::string &name) : name(name), handler(nullptr) { } - ~Plugin() { - if (handler != nullptr) { - dlclose(handler); -diff --git a/src/plugin_mgr/plugin_manager.cpp b/src/plugin_mgr/plugin_manager.cpp -index 1503fc1..7900ecf 100644 ---- a/src/plugin_mgr/plugin_manager.cpp -+++ b/src/plugin_mgr/plugin_manager.cpp -@@ -11,21 +11,13 @@ - ******************************************************************************/ - #include "plugin_manager.h" - #include "default_path.h" --#include "utils.h" --#include --#include - #include --#include - --const std::string PluginManager::COLLECTOR_TEXT = "collector"; --const std::string PluginManager::SCENARIO_TEXT = "scenario"; --const std::string PluginManager::TUNE_TEXT = "tune"; - const static int ST_MODE_MASK = 0777; - - void PluginManager::init() { -- plugin_types[COLLECTOR_TEXT] = PluginType::COLLECTOR; -- plugin_types[SCENARIO_TEXT] = PluginType::SCENARIO; -- plugin_types[TUNE_TEXT] = PluginType::TUNE; -+ instance_run_handler.reset(new InstanceRunHandler(memory_store)); -+ pre_load(); - } - - ErrorCode PluginManager::remove(const std::string &name) { -@@ -40,19 +32,18 @@ ErrorCode PluginManager::remove(const std::string &name) { - if (instance->get_enabled()) { - return ErrorCode::REMOVE_INSTANCE_IS_RUNNING; - } -- if (dep_handler.have_dep(iname)) { -+ if (memory_store.have_dep(iname)) { - return ErrorCode::REMOVE_INSTANCE_HAVE_DEP; - } - instance_names.emplace_back(iname); - } - for(auto &iname : instance_names) { - memory_store.delete_instance(iname); -- dep_handler.del_node(iname); - } - memory_store.delete_plugin(name); -- update_instance_state(); - return ErrorCode::OK; - } -+ - ErrorCode PluginManager::query_all_plugins(std::string &res) { - std::vector> all_plugins = memory_store.get_all_plugins(); - for (auto &p : all_plugins) { -@@ -99,10 +90,8 @@ void PluginManager::save_instance(std::shared_ptr plugin, Interface *int - instance->set_name(name); - instance->set_plugin_name(plugin->get_name()); - instance->set_enabled(false); -- dep_handler.add_node(name, instance->get_deps()); -- instance->set_state(dep_handler.get_node_state(name)); - DEBUG("[PluginManager] Instance: " << name.c_str()); -- memory_store.add_instance(name, instance); -+ memory_store.add_instance(instance); - plugin->add_instance(instance); - } - } -@@ -116,21 +105,9 @@ bool PluginManager::load_instance(std::shared_ptr plugin) { - return false; - } - save_instance(plugin, interface_list, len); -- update_instance_state(); - return true; - } - --void PluginManager::update_instance_state() { -- std::vector> all_instances = memory_store.get_all_instances(); -- for (auto &instance : all_instances) { -- if (dep_handler.get_node_state(instance->get_name())) { -- instance->set_state(true); -- } else { -- instance->set_state(false); -- } -- } --} -- - ErrorCode PluginManager::load_plugin(const std::string &name) { - std::string plugin_path = get_path() + "/" + name; - if (!file_exist(plugin_path)) { -@@ -160,6 +137,8 @@ ErrorCode PluginManager::load_plugin(const std::string &name) { - std::string generate_dot(MemoryStore &memory_store, const std::vector> &query) { - std::string res; - res += "digraph G {\n"; -+ res += " rankdir = TB\n"; -+ res += " ranksep = 1\n"; - std::unordered_map> sub_graph; - for (auto &vec : query) { - std::shared_ptr instance = memory_store.get_instance(vec[0]); -@@ -171,45 +150,45 @@ std::string generate_dot(MemoryStore &memory_store, const std::vectorget_plugin_name()].insert(vec[1]); - } else { -- res += vec[1] + "[label=\"(missing)\\n" + vec[1] + "\", fontcolor=red];\n"; -+ res += " " + vec[1] + "[label=\"(missing)\\n" + vec[1] + "\", fontcolor=red];\n"; - } -- res += vec[0] + "->" + vec[1] + ";\n"; -+ res += " " + vec[0] + "->" + vec[1] + ";\n"; - } - int id = 0; - for (auto &p : sub_graph) { -- res += "subgraph cluster_" + std::to_string(id) + " {\n"; -- res += "node [style=filled];\n"; -- res += "label = \"" + p.first + "\";\n"; -+ res += " subgraph cluster_" + std::to_string(id) + " {\n"; -+ res += " node [style=filled];\n"; -+ res += " label = \"" + p.first + "\";\n"; - for (auto &i_name : p.second) { -- res += i_name + ";\n"; -+ res += " " + i_name + ";\n"; - } -- res += "}\n"; -+ res += " }\n"; - id++; - } - res += "}"; - return res; - } - --ErrorCode PluginManager::query_top(const std::string &name, std::string &res) { -+ErrorCode PluginManager::query_dependency(const std::string &name, std::string &res) { - if (!memory_store.is_instance_exist(name)) { - return ErrorCode::QUERY_DEP_NOT_EXIST; - } - DEBUG("[PluginManager] query top : " << name); - std::vector> query; -- dep_handler.query_node(name, query); -+ memory_store.query_node_dependency(name, query); - res = generate_dot(memory_store, query); - return ErrorCode::OK; - } - --ErrorCode PluginManager::query_all_tops(std::string &res) { -+ErrorCode PluginManager::query_all_dependencies(std::string &res) { - std::vector> query; -- dep_handler.query_all_top(query); -+ memory_store.query_all_dependencies(query); - DEBUG("[PluginManager] query size:" << query.size()); - res = generate_dot(memory_store, query); - return ErrorCode::OK; - } - --ErrorCode PluginManager::instance_enabled(std::string name) { -+ErrorCode PluginManager::instance_enabled(const std::string &name) { - if (!memory_store.is_instance_exist(name)) { - return ErrorCode::ENABLE_INSTANCE_NOT_LOAD; - } -@@ -220,7 +199,7 @@ ErrorCode PluginManager::instance_enabled(std::string name) { - if (instance->get_enabled()) { - return ErrorCode::ENABLE_INSTANCE_ALREADY_ENABLED; - } -- std::vector pre_dependencies = dep_handler.get_pre_dependencies(name); -+ std::vector pre_dependencies = memory_store.get_pre_dependencies(name); - std::vector> new_enabled; - bool enabled = true; - for (int i = pre_dependencies.size() - 1; i >= 0; --i) { -@@ -252,7 +231,7 @@ ErrorCode PluginManager::instance_enabled(std::string name) { - } - } - --ErrorCode PluginManager::instance_disabled(std::string name) { -+ErrorCode PluginManager::instance_disabled(const std::string &name) { - if (!memory_store.is_instance_exist(name)) { - return ErrorCode::DISABLE_INSTANCE_NOT_LOAD; - } -@@ -364,7 +343,7 @@ void PluginManager::pre_load() { - pre_enable(); - } - --const void* PluginManager::get_data_buffer(std::string name) { -+const void* PluginManager::get_data_buffer(const std::string &name) { - std::shared_ptr instance = memory_store.get_instance(name); - return instance->get_interface()->get_ring_buf(); - } -@@ -375,7 +354,7 @@ std::string PluginManager::instance_dep_check(const std::string &name) { - for (size_t i = 0; i < plugin->get_instance_len(); ++i) { - std::string instance_name = plugin->get_instance(i)->get_name(); - std::vector> query; -- dep_handler.query_node(instance_name, query); -+ memory_store.query_node_dependency(instance_name, query); - std::vector lack; - for (auto &item : query) { - if (item.size() < 2) continue; -@@ -478,10 +457,10 @@ int PluginManager::run() { - } - break; - } -- case Opt::QUERY_TOP: { -+ case Opt::QUERY_DEP: { - std::string res_text; - std::string name = msg.get_payload(0); -- ErrorCode ret_code = query_top(name , res_text); -+ ErrorCode ret_code = query_dependency(name , res_text); - if (ret_code == ErrorCode::OK) { - INFO("[PluginManager] query " << name << " instance dependencies."); - res.set_opt(Opt::RESPONSE_OK); -@@ -494,9 +473,9 @@ int PluginManager::run() { - } - break; - } -- case Opt::QUERY_ALL_TOP: { -+ case Opt::QUERY_ALL_DEPS: { - std::string res_text; -- ErrorCode ret_code = query_all_tops(res_text); -+ ErrorCode ret_code = query_all_dependencies(res_text); - if (ret_code == ErrorCode::OK) { - INFO("[PluginManager] query all instances dependencies."); - res.set_opt(Opt::RESPONSE_OK); -diff --git a/src/plugin_mgr/plugin_manager.h b/src/plugin_mgr/plugin_manager.h -index 9339f0d..18d3f35 100644 ---- a/src/plugin_mgr/plugin_manager.h -+++ b/src/plugin_mgr/plugin_manager.h -@@ -15,35 +15,28 @@ - #include "instance_run_handler.h" - #include "config.h" - #include "memory_store.h" --#include "dep_handler.h" - #include "message_manager.h" - #include "error_code.h" --#include --#include --#include --#include - - class PluginManager { - public: - PluginManager(Config &config, SafeQueue &handler_msg, SafeQueue &res_msg) : -- config(config), handler_msg(handler_msg), res_msg(res_msg) { -- instance_run_handler.reset(new InstanceRunHandler(memory_store)); -- } -+ config(config), handler_msg(handler_msg), res_msg(res_msg) { } - int run(); -- void pre_load(); -- void pre_enable(); - void init(); -- const void* get_data_buffer(std::string name); -+ const void* get_data_buffer(const std::string &name); - private: -+ void pre_load(); -+ void pre_enable(); - void pre_load_plugin(); - ErrorCode load_plugin(const std::string &path); - ErrorCode remove(const std::string &name); - ErrorCode query_all_plugins(std::string &res); - ErrorCode query_plugin(const std::string &name, std::string &res); -- ErrorCode query_top(const std::string &name, std::string &res); -- ErrorCode query_all_tops(std::string &res); -- ErrorCode instance_enabled(std::string name); -- ErrorCode instance_disabled(std::string name); -+ ErrorCode query_dependency(const std::string &name, std::string &res); -+ ErrorCode query_all_dependencies(std::string &res); -+ ErrorCode instance_enabled(const std::string &name); -+ ErrorCode instance_disabled(const std::string &name); - ErrorCode add_list(std::string &res); - ErrorCode download(const std::string &name, std::string &res); - std::string instance_dep_check(const std::string &name); -@@ -61,13 +54,9 @@ private: - SafeQueue &handler_msg; - SafeQueue &res_msg; - MemoryStore memory_store; -- DepHandler dep_handler; -- std::unordered_map plugin_types; -- static const std::string COLLECTOR_TEXT; -- static const std::string SCENARIO_TEXT; -- static const std::string TUNE_TEXT; - }; - - bool check_permission(std::string path, int mode); - bool file_exist(const std::string &file_name); -+ - #endif --- -2.33.0 - diff --git a/0004-modify-some-interfaces-and-add-interface-comments.patch b/0004-modify-some-interfaces-and-add-interface-comments.patch deleted file mode 100644 index ecb93dd..0000000 --- a/0004-modify-some-interfaces-and-add-interface-comments.patch +++ /dev/null @@ -1,121 +0,0 @@ -From 0758b61d2e9af546d3c55bc9cb3704cd7a4fe59a Mon Sep 17 00:00:00 2001 -From: fly_1997 -Date: Tue, 28 May 2024 20:00:07 +0800 -Subject: [PATCH 3/4] modify some interfaces and add interface comments - ---- - src/plugin_mgr/instance_run_handler.cpp | 1 + - src/plugin_mgr/instance_run_handler.h | 10 +++------- - src/plugin_mgr/interface.h | 17 ++++++++++------- - src/plugin_mgr/plugin.h | 4 ++-- - 4 files changed, 16 insertions(+), 16 deletions(-) - -diff --git a/src/plugin_mgr/instance_run_handler.cpp b/src/plugin_mgr/instance_run_handler.cpp -index c60207b..fc9dc04 100644 ---- a/src/plugin_mgr/instance_run_handler.cpp -+++ b/src/plugin_mgr/instance_run_handler.cpp -@@ -34,6 +34,7 @@ void InstanceRunHandler::run_instance(std::shared_ptr instance) { - } - - void InstanceRunHandler::insert_instance(std::shared_ptr instance, uint64_t time) { -+ /* To check if an instance is enabled, enable() is called in the PluginManager. */ - instance->set_enabled(true); - schedule_queue.push(ScheduleInstance{instance, time}); - INFO("[PluginManager] " << instance->get_name() << " instance insert into running queue."); -diff --git a/src/plugin_mgr/instance_run_handler.h b/src/plugin_mgr/instance_run_handler.h -index fc45874..f0bf263 100644 ---- a/src/plugin_mgr/instance_run_handler.h -+++ b/src/plugin_mgr/instance_run_handler.h -@@ -42,7 +42,7 @@ private: - class ScheduleInstance { - public: - bool operator < (const ScheduleInstance &rhs) const { -- return time > rhs.time || (time == rhs.time && instance->get_type() > rhs.instance->get_type()); -+ return time > rhs.time || (time == rhs.time && instance->get_priority() > rhs.instance->get_priority()); - } - std::shared_ptr instance; - uint64_t time; -@@ -61,9 +61,6 @@ public: - int get_cycle() { - return cycle; - } -- bool is_instance_exist(const std::string &name) { -- return memory_store.is_instance_exist(name); -- } - void recv_queue_push(InstanceRunMessage &msg) { - this->recv_queue.push(msg); - } -@@ -77,15 +74,14 @@ private: - void run_instance(std::shared_ptr instance); - void delete_instance(std::shared_ptr instance); - void insert_instance(std::shared_ptr instance, uint64_t time); -- void adjust_collector_queue(const std::vector &deps, const std::vector &m_deps, bool flag); -- void check_scenario_dependency(const std::vector &deps, const std::vector &m_deps); - -+ /* Instance execution queue. */ - std::priority_queue schedule_queue; -+ /*Receives messages from the PluginManager. */ - SafeQueue recv_queue; - MemoryStore &memory_store; - int cycle; - static const int DEFAULT_CYCLE_SIZE = 10; -- static const int MAX_DEPENDENCIES_SIZE = 20; - }; - - #endif // !PLUGIN_MGR_INSTANCE_RUN_HANDLER_H -diff --git a/src/plugin_mgr/interface.h b/src/plugin_mgr/interface.h -index 6495b92..8aa6933 100644 ---- a/src/plugin_mgr/interface.h -+++ b/src/plugin_mgr/interface.h -@@ -14,12 +14,6 @@ - #include - #include - --enum PluginType { -- COLLECTOR, -- SCENARIO, -- TUNE, --}; -- - struct DataBuf { - int len; - void *data; -@@ -43,10 +37,19 @@ struct Param { - - struct Interface { - const char* (*get_version)(); -+ /* The instance name is a unique identifier in the system. */ - const char* (*get_name)(); - const char* (*get_description)(); -+ /* Specifies the instance dependencies, which is used as the input information -+ * for instance execution. -+ */ - const char* (*get_dep)(); -- enum PluginType (*get_type)(); -+ /* Instance scheduling priority. In a uniform time period, a instance with a -+ * lower priority is scheduled first. -+ */ -+ int (*get_priority)(); -+ int (*get_type)(); -+ /* Instance execution period. */ - int (*get_period)(); - bool (*enable)(); - void (*disable)(); -diff --git a/src/plugin_mgr/plugin.h b/src/plugin_mgr/plugin.h -index f6b5029..7415b99 100644 ---- a/src/plugin_mgr/plugin.h -+++ b/src/plugin_mgr/plugin.h -@@ -25,8 +25,8 @@ public: - std::string get_name() const { - return this->name; - } -- PluginType get_type() const { -- return interface->get_type(); -+ int get_priority() const { -+ return interface->get_priority(); - } - Interface* get_interface() const { - return this->interface; --- -2.33.0 - diff --git a/0005-add-the-SIGINT-signal-processing-and-singleton-class.patch b/0005-add-the-SIGINT-signal-processing-and-singleton-class.patch deleted file mode 100644 index 551ba6f..0000000 --- a/0005-add-the-SIGINT-signal-processing-and-singleton-class.patch +++ /dev/null @@ -1,401 +0,0 @@ -From 6b8debf93307ee68f2ecd4b0bf5ac2d01ee278b8 Mon Sep 17 00:00:00 2001 -From: fly_1997 -Date: Wed, 29 May 2024 15:12:31 +0800 -Subject: [PATCH 4/4] add the SIGINT signal processing and singleton classes - ---- - src/plugin_mgr/instance_run_handler.cpp | 1 - - src/plugin_mgr/logger.cpp | 2 +- - src/plugin_mgr/logger.h | 3 +- - src/plugin_mgr/main.cpp | 37 +++++++++++++++++++------ - src/plugin_mgr/memory_store.h | 2 +- - src/plugin_mgr/message_manager.cpp | 22 ++++++++++----- - src/plugin_mgr/message_manager.h | 32 +++++++++++---------- - src/plugin_mgr/plugin.h | 2 +- - src/plugin_mgr/plugin_manager.cpp | 26 ++++++++++------- - src/plugin_mgr/plugin_manager.h | 21 ++++++++++---- - 10 files changed, 97 insertions(+), 51 deletions(-) - -diff --git a/src/plugin_mgr/instance_run_handler.cpp b/src/plugin_mgr/instance_run_handler.cpp -index fc9dc04..ecd7778 100644 ---- a/src/plugin_mgr/instance_run_handler.cpp -+++ b/src/plugin_mgr/instance_run_handler.cpp -@@ -35,7 +35,6 @@ void InstanceRunHandler::run_instance(std::shared_ptr instance) { - - void InstanceRunHandler::insert_instance(std::shared_ptr instance, uint64_t time) { - /* To check if an instance is enabled, enable() is called in the PluginManager. */ -- instance->set_enabled(true); - schedule_queue.push(ScheduleInstance{instance, time}); - INFO("[PluginManager] " << instance->get_name() << " instance insert into running queue."); - } -diff --git a/src/plugin_mgr/logger.cpp b/src/plugin_mgr/logger.cpp -index 7a924c2..af39583 100644 ---- a/src/plugin_mgr/logger.cpp -+++ b/src/plugin_mgr/logger.cpp -@@ -26,7 +26,7 @@ Logger::Logger() { - logger.addAppender(appender); - } - --void Logger::init(Config *config) { -+void Logger::init(std::shared_ptr config) { - log4cplus::SharedAppenderPtr appender(new log4cplus::FileAppender(config->get_log_path() + "/server.log")); - appender->setName("file"); - log4cplus::tstring pattern = LOG4CPLUS_TEXT("%D{%m/%d/%y %H:%M:%S} [%t] %-5p %c - %m" -diff --git a/src/plugin_mgr/logger.h b/src/plugin_mgr/logger.h -index e86dd72..a219c86 100644 ---- a/src/plugin_mgr/logger.h -+++ b/src/plugin_mgr/logger.h -@@ -13,6 +13,7 @@ - #define PLUGIN_MGR_LOGGER_H - - #include "config.h" -+#include - #include - - #define INFO(fmt) LOG4CPLUS_INFO(logger.get(), fmt) -@@ -24,7 +25,7 @@ - class Logger { - public: - Logger(); -- void init(Config *config); -+ void init(std::shared_ptr config); - log4cplus::Logger get() { - return logger; - } -diff --git a/src/plugin_mgr/main.cpp b/src/plugin_mgr/main.cpp -index 698ba62..5cfb020 100644 ---- a/src/plugin_mgr/main.cpp -+++ b/src/plugin_mgr/main.cpp -@@ -10,6 +10,7 @@ - * See the Mulan PSL v2 for more details. - ******************************************************************************/ - #include "plugin_manager.h" -+#include - - Logger logger; - -@@ -20,8 +21,26 @@ void print_help() { - " ./oeaware /etc/oeAware/config.yaml\n"); - } - -+void signal_handler(int signum) { -+ auto &plugin_manager = PluginManager::get_instance(); -+ auto memory_store = plugin_manager.get_memory_store(); -+ auto all_plugins = memory_store.get_all_plugins(); -+ for (auto plugin : all_plugins) { -+ for (size_t i = 0; i < plugin->get_instance_len(); ++i) { -+ auto instance = plugin->get_instance(i); -+ if (!instance->get_enabled()) { -+ continue; -+ } -+ instance->get_interface()->disable(); -+ INFO("[PluginManager] " << instance->get_name() << " instance disabled."); -+ } -+ } -+ exit(signum); -+} -+ - int main(int argc, char **argv) { -- Config config; -+ signal(SIGINT, signal_handler); -+ std::shared_ptr config = std::make_shared(); - if (argc < 2) { - ERROR("System need a argument!"); - exit(EXIT_FAILURE); -@@ -39,20 +58,20 @@ int main(int argc, char **argv) { - ERROR("Insufficient permission on " << config_path); - exit(EXIT_FAILURE); - } -- if (!config.load(config_path)) { -+ if (!config->load(config_path)) { - ERROR("Config load error!"); - exit(EXIT_FAILURE); - } -- logger.init(&config); -- SafeQueue handler_msg; -- SafeQueue res_msg; -+ logger.init(config); -+ std::shared_ptr> handler_msg = std::make_shared>(); -+ std::shared_ptr> res_msg = std::make_shared>(); - INFO("[MessageManager] Start message manager!"); -- MessageManager message_manager(&handler_msg, &res_msg); -- message_manager.init(); -+ MessageManager &message_manager = MessageManager::get_instance(); -+ message_manager.init(handler_msg, res_msg); - message_manager.run(); - INFO("[PluginManager] Start plugin manager!"); -- PluginManager plugin_manager(config, handler_msg, res_msg); -- plugin_manager.init(); -+ PluginManager& plugin_manager = PluginManager::get_instance(); -+ plugin_manager.init(config, handler_msg, res_msg); - plugin_manager.run(); - return 0; - } -\ No newline at end of file -diff --git a/src/plugin_mgr/memory_store.h b/src/plugin_mgr/memory_store.h -index 999795a..0e862db 100644 ---- a/src/plugin_mgr/memory_store.h -+++ b/src/plugin_mgr/memory_store.h -@@ -42,7 +42,7 @@ public: - bool is_instance_exist(const std::string &name) { - return dep_handler.is_instance_exist(name); - } -- std::vector> get_all_plugins() { -+ const std::vector> get_all_plugins() { - std::vector> res; - for (auto &p : plugins) { - res.emplace_back(p.second); -diff --git a/src/plugin_mgr/message_manager.cpp b/src/plugin_mgr/message_manager.cpp -index 815122c..a9f862d 100644 ---- a/src/plugin_mgr/message_manager.cpp -+++ b/src/plugin_mgr/message_manager.cpp -@@ -57,7 +57,7 @@ bool TcpSocket::init() { - return true; - - } --static void send_msg(Msg &msg, SafeQueue *handler_msg) { -+static void send_msg(Msg &msg, std::shared_ptr> handler_msg) { - Message message; - message.set_opt(msg.opt()); - message.set_type(MessageType::EXTERNAL); -@@ -66,7 +66,7 @@ static void send_msg(Msg &msg, SafeQueue *handler_msg) { - } - handler_msg->push(message); - } --static void recv_msg(Msg &msg, SafeQueue *res_msg) { -+static void recv_msg(Msg &msg, std::shared_ptr> res_msg) { - Message res; - res_msg->wait_and_pop(res); - msg.set_opt(res.get_opt()); -@@ -75,7 +75,7 @@ static void recv_msg(Msg &msg, SafeQueue *res_msg) { - } - } - --void TcpSocket::serve_accept(SafeQueue *handler_msg, SafeQueue *res_msg){ -+void TcpSocket::serve_accept(std::shared_ptr> handler_msg, std::shared_ptr> res_msg){ - struct epoll_event evs[MAX_EVENT_SIZE]; - int sz = sizeof(evs) / sizeof(struct epoll_event); - while (true) { -@@ -112,12 +112,20 @@ void TcpSocket::serve_accept(SafeQueue *handler_msg, SafeQueue - } - } - --void handler(MessageManager *mgr) { -- TcpSocket* tcp_socket = mgr->tcp_socket; -- if (!tcp_socket->init()) { -+void MessageManager::tcp_start() { -+ if (!tcp_socket.init()) { - return; - } -- tcp_socket->serve_accept(mgr->handler_msg, mgr->res_msg); -+ tcp_socket.serve_accept(handler_msg, res_msg); -+} -+ -+static void handler(MessageManager *mgr) { -+ mgr->tcp_start(); -+} -+ -+void MessageManager::init(std::shared_ptr> handler_msg, std::shared_ptr> res_msg) { -+ this->handler_msg = handler_msg; -+ this->res_msg = res_msg; - } - - void MessageManager::run() { -diff --git a/src/plugin_mgr/message_manager.h b/src/plugin_mgr/message_manager.h -index 95bbd1a..f5240aa 100644 ---- a/src/plugin_mgr/message_manager.h -+++ b/src/plugin_mgr/message_manager.h -@@ -61,34 +61,38 @@ private: - - class TcpSocket { - public: -- TcpSocket() {} -+ TcpSocket() : sock(-1), epfd(-1) { } - ~TcpSocket() { - close(sock); - } - bool init(); -- void serve_accept(SafeQueue *handler_msg, SafeQueue *res_msg); -+ void serve_accept(std::shared_ptr> handler_msg, std::shared_ptr> res_msg); - private: - int domain_listen(const char *name); -- -+private: - int sock; - int epfd; - }; - - class MessageManager { - public: -- MessageManager(SafeQueue *handler_msg, SafeQueue *res_msg) { -- this->handler_msg = handler_msg; -- this->res_msg = res_msg; -- this->tcp_socket = nullptr; -- } -- void init(){ -- this->tcp_socket = new TcpSocket(); -+ MessageManager(const MessageManager&) = delete; -+ MessageManager& operator=(const MessageManager&) = delete; -+ static MessageManager& get_instance() { -+ static MessageManager message_manager; -+ return message_manager; - } -+ void init(std::shared_ptr> handler_msg, std::shared_ptr> res_msg); -+ void tcp_start(); - void run(); -- -- SafeQueue *handler_msg; -- SafeQueue *res_msg; -- TcpSocket *tcp_socket; -+private: -+ MessageManager() { } -+private: -+ /* Message queue stores messages from the client and is consumed by PluginManager. */ -+ std::shared_ptr> handler_msg; -+ /* Message queue stores messages from PluginManager and is consumed by TcpSocket. */ -+ std::shared_ptr> res_msg; -+ TcpSocket tcp_socket; - }; - - #endif // !PLUGIN_MGR_MESSAGE_MANAGER_H -\ No newline at end of file -diff --git a/src/plugin_mgr/plugin.h b/src/plugin_mgr/plugin.h -index 7415b99..a011261 100644 ---- a/src/plugin_mgr/plugin.h -+++ b/src/plugin_mgr/plugin.h -@@ -81,7 +81,7 @@ public: - void add_instance(std::shared_ptr ins) { - instances.emplace_back(ins); - } -- std::shared_ptr get_instance(int i) const { -+ std::shared_ptr get_instance(size_t i) const { - return instances[i]; - } - size_t get_instance_len() const { -diff --git a/src/plugin_mgr/plugin_manager.cpp b/src/plugin_mgr/plugin_manager.cpp -index 7900ecf..4c5f5fc 100644 ---- a/src/plugin_mgr/plugin_manager.cpp -+++ b/src/plugin_mgr/plugin_manager.cpp -@@ -15,7 +15,12 @@ - - const static int ST_MODE_MASK = 0777; - --void PluginManager::init() { -+ -+void PluginManager::init(std::shared_ptr config, std::shared_ptr> handler_msg, -+ std::shared_ptr> res_msg) { -+ this->config = config; -+ this->handler_msg = handler_msg; -+ this->res_msg = res_msg; - instance_run_handler.reset(new InstanceRunHandler(memory_store)); - pre_load(); - } -@@ -220,12 +225,13 @@ ErrorCode PluginManager::instance_enabled(const std::string &name) { - if (instance->get_enabled()) { - continue; - } -+ instance->set_enabled(true); - instance_run_handler->recv_queue_push(InstanceRunMessage(RunType::ENABLED, instance)); - } - return ErrorCode::OK; - } else { -- for (auto instance : new_enabled) { -- instance->get_interface()->disable(); -+ for (auto ins : new_enabled) { -+ ins->get_interface()->disable(); - } - return ErrorCode::ENABLE_INSTANCE_ENV; - } -@@ -275,7 +281,7 @@ std::string PluginManager::get_plugin_in_dir(const std::string &path) { - } - - ErrorCode PluginManager::add_list(std::string &res) { -- auto plugin_list = config.get_plugin_list(); -+ auto plugin_list = config->get_plugin_list(); - res += "Supported Packages:\n"; - for (auto &p : plugin_list) { - res += p.first + "\n"; -@@ -286,16 +292,16 @@ ErrorCode PluginManager::add_list(std::string &res) { - } - - ErrorCode PluginManager::download(const std::string &name, std::string &res) { -- if (!config.is_plugin_info_exist(name)) { -+ if (!config->is_plugin_info_exist(name)) { - return ErrorCode::DOWNLOAD_NOT_FOUND; - } -- res += config.get_plugin_info(name).get_url(); -+ res += config->get_plugin_info(name).get_url(); - return ErrorCode::OK; - } - - void PluginManager::pre_enable() { -- for (size_t i = 0; i < config.get_enable_list_size(); ++i) { -- EnableItem item = config.get_enable_list(i); -+ for (size_t i = 0; i < config->get_enable_list_size(); ++i) { -+ EnableItem item = config->get_enable_list(i); - if (item.get_enabled()) { - std::string name = item.get_name(); - if (!memory_store.is_plugin_exist(name)) { -@@ -394,7 +400,7 @@ int PluginManager::run() { - while (true) { - Message msg; - Message res; -- this->handler_msg.wait_and_pop(msg); -+ this->handler_msg->wait_and_pop(msg); - if (msg.get_opt() == Opt::SHUTDOWN) break; - switch (msg.get_opt()) { - case Opt::LOAD: { -@@ -557,7 +563,7 @@ int PluginManager::run() { - break; - } - if (msg.get_type() == MessageType::EXTERNAL) -- res_msg.push(res); -+ res_msg->push(res); - } - return 0; - } -diff --git a/src/plugin_mgr/plugin_manager.h b/src/plugin_mgr/plugin_manager.h -index 18d3f35..b7c04fe 100644 ---- a/src/plugin_mgr/plugin_manager.h -+++ b/src/plugin_mgr/plugin_manager.h -@@ -20,12 +20,21 @@ - - class PluginManager { - public: -- PluginManager(Config &config, SafeQueue &handler_msg, SafeQueue &res_msg) : -- config(config), handler_msg(handler_msg), res_msg(res_msg) { } -+ PluginManager(const PluginManager&) = delete; -+ PluginManager& operator=(const PluginManager&) = delete; -+ static PluginManager& get_instance() { -+ static PluginManager plugin_manager; -+ return plugin_manager; -+ } - int run(); -- void init(); -+ void init(std::shared_ptr config, std::shared_ptr> handler_msg, -+ std::shared_ptr> res_msg); -+ const MemoryStore& get_memory_store() { -+ return this->memory_store; -+ } - const void* get_data_buffer(const std::string &name); - private: -+ PluginManager() { } - void pre_load(); - void pre_enable(); - void pre_load_plugin(); -@@ -50,9 +59,9 @@ private: - std::string get_plugin_in_dir(const std::string &path); - private: - std::unique_ptr instance_run_handler; -- Config &config; -- SafeQueue &handler_msg; -- SafeQueue &res_msg; -+ std::shared_ptr config; -+ std::shared_ptr> handler_msg; -+ std::shared_ptr> res_msg; - MemoryStore memory_store; - }; - --- -2.33.0 - diff --git a/0006-add-dynamic-dependencncy-adjustment.patch b/0006-add-dynamic-dependencncy-adjustment.patch deleted file mode 100644 index df86a90..0000000 --- a/0006-add-dynamic-dependencncy-adjustment.patch +++ /dev/null @@ -1,682 +0,0 @@ -From 40bb095943d23c0bf271c633fc7ec6379925762a Mon Sep 17 00:00:00 2001 -From: fly_1997 -Date: Wed, 5 Jun 2024 11:08:32 +0800 -Subject: [PATCH] add dynamic dependencncy adjustment - ---- - src/plugin_mgr/dep_handler.cpp | 108 ++++++++-------- - src/plugin_mgr/dep_handler.h | 37 ++++-- - src/plugin_mgr/instance_run_handler.cpp | 156 ++++++++++++++++++++---- - src/plugin_mgr/instance_run_handler.h | 48 +++++--- - src/plugin_mgr/interface.h | 4 +- - src/plugin_mgr/memory_store.h | 10 +- - src/plugin_mgr/plugin_manager.cpp | 41 ++----- - 7 files changed, 270 insertions(+), 134 deletions(-) - -diff --git a/src/plugin_mgr/dep_handler.cpp b/src/plugin_mgr/dep_handler.cpp -index 1006175..227ee2f 100644 ---- a/src/plugin_mgr/dep_handler.cpp -+++ b/src/plugin_mgr/dep_handler.cpp -@@ -29,25 +29,47 @@ void DepHandler::add_arc_node(std::shared_ptr node, const std::vectorcnt = dep_nodes.size(); - int real_cnt = 0; - for (auto name : dep_nodes) { -- std::shared_ptr tmp = std::make_shared(); -- tmp->arc_name = name; -- tmp->node_name = node->instance->get_name(); -+ std::string from = node->instance->get_name(); -+ std::shared_ptr tmp = std::make_shared(from, name); - tmp->next = arc_head->next; - arc_head->next = tmp; - - if (nodes.count(name)) { - tmp->is_exist = true; -- arc_nodes[name].insert(tmp); -+ tmp->init = true; - real_cnt++; -- } else { -- tmp->is_exist = false; -- arc_nodes[name].insert(tmp); - } -+ in_edges[name].insert(from); -+ arc_nodes[std::make_pair(from, name)] = tmp; - } - if (real_cnt == node->cnt) { - node->instance->set_state(true); - } - node->real_cnt = real_cnt; -+} -+ -+void DepHandler::add_edge(const std::string &from, const std::string &to) { -+ if (in_edges[to].find(from) != in_edges[to].end()) { -+ auto arc_node = arc_nodes[std::make_pair(from, to)]; -+ arc_node->is_exist = true; -+ return; -+ } -+ -+ auto arc_node = std::make_shared(from, to); -+ auto node = nodes[from]; -+ arc_node->next = node->head->next; -+ node->head->next = arc_node; -+ arc_node->is_exist = true; -+ arc_nodes[std::make_pair(from, to)] = arc_node; -+ in_edges[to].insert(from); -+} -+ -+void DepHandler::delete_edge(const std::string &from, const std::string &to) { -+ if (in_edges[to].find(from) == in_edges[to].end()) { -+ return; -+ } -+ auto arc_node = arc_nodes[std::make_pair(from, to)]; -+ arc_node->is_exist = false; - } - - void DepHandler::add_node(std::shared_ptr instance) { -@@ -81,10 +103,11 @@ void DepHandler::del_node_and_arc_nodes(std::shared_ptr node) { - while(arc) { - std::shared_ptr tmp = arc->next; - if (arc != node->head){ -- std::string name = arc->arc_name; -- arc_nodes[name].erase(arc); -- if (arc_nodes[name].empty()) { -- arc_nodes.erase(name); -+ std::string name = arc->to; -+ in_edges[name].erase(arc->from); -+ arc_nodes.erase(std::make_pair(arc->from, arc->to)); -+ if (in_edges[name].empty()) { -+ in_edges.erase(name); - } - } - arc = tmp; -@@ -92,15 +115,18 @@ void DepHandler::del_node_and_arc_nodes(std::shared_ptr node) { - } - - void DepHandler::update_instance_state(const std::string &name) { -- if (!nodes[name]->instance->get_state() || !arc_nodes.count(name)) return; -- std::unordered_set> &arcs = arc_nodes[name]; -- for (auto &arc_node : arcs) { -- if (nodes.count(arc_node->node_name)) { -- auto tmp = nodes[arc_node->node_name]; -+ if (!nodes[name]->instance->get_state() || !in_edges.count(name)) return; -+ std::unordered_set &arcs = in_edges[name]; -+ for (auto &from : arcs) { -+ auto arc_node = arc_nodes[std::make_pair(from, name)]; -+ if (nodes.count(from)) { -+ auto tmp = nodes[from]; - tmp->real_cnt++; - if (tmp->real_cnt == tmp->cnt) { - tmp->instance->set_state(true); - } -+ arc_node->is_exist = true; -+ arc_node->init = true; - update_instance_state(tmp->instance->get_name()); - } - } -@@ -113,54 +139,38 @@ void DepHandler::query_all_dependencies(std::vector> &q - } - - void DepHandler::query_node_top(const std::string &name, std::vector> &query) { -- std::shared_ptr p = nodes[name]->head; -- if (p->next == nullptr) { -+ std::shared_ptr arc_node = nodes[name]->head; -+ if (arc_node->next == nullptr) { - query.emplace_back(std::vector{name}); - return; - } -- while (p->next != nullptr) { -- query.emplace_back(std::vector{name, p->next->arc_name}); -- p = p->next; -+ while (arc_node->next != nullptr) { -+ if (arc_node->next->is_exist) { -+ query.emplace_back(std::vector{name, arc_node->next->to}); -+ } -+ arc_node = arc_node->next; - } - } - - void DepHandler::query_node_dependency(const std::string &name, std::vector> &query) { - if (!nodes.count(name)) return; -- std::queue q; -+ std::queue instance_queue; - std::unordered_set vis; - vis.insert(name); -- q.push(name); -- while (!q.empty()) { -- auto node = nodes[q.front()]; -- q.pop(); -+ instance_queue.push(name); -+ while (!instance_queue.empty()) { -+ auto node = nodes[instance_queue.front()]; -+ instance_queue.pop(); - std::string node_name = node->instance->get_name(); - query.emplace_back(std::vector{node_name}); - for (auto cur = node->head->next; cur != nullptr; cur = cur->next) { -- query.emplace_back(std::vector{node_name, cur->arc_name}); -- if (!vis.count(cur->arc_name) && nodes.count(cur->arc_name)) { -- vis.insert(cur->arc_name); -- q.push(cur->arc_name); -+ if (cur->is_exist) { -+ query.emplace_back(std::vector{node_name, cur->to}); - } -- } -- } --} -- --std::vector DepHandler::get_pre_dependencies(const std::string &name) { -- std::vector res; -- std::queue> q; -- std::unordered_set vis; -- vis.insert(name); -- q.push(nodes[name]); -- while (!q.empty()) { -- auto &node = q.front(); -- q.pop(); -- res.emplace_back(node->instance->get_name()); -- for (auto arc_node = node->head->next; arc_node != nullptr; arc_node = arc_node->next) { -- if (!vis.count(arc_node->arc_name)) { -- vis.insert(arc_node->arc_name); -- q.push(nodes[arc_node->arc_name]); -+ if (!vis.count(cur->to) && nodes.count(cur->to)) { -+ vis.insert(cur->to); -+ instance_queue.push(cur->to); - } - } - } -- return res; - } -diff --git a/src/plugin_mgr/dep_handler.h b/src/plugin_mgr/dep_handler.h -index a7a8ef6..322e3b3 100644 ---- a/src/plugin_mgr/dep_handler.h -+++ b/src/plugin_mgr/dep_handler.h -@@ -18,10 +18,12 @@ - - struct ArcNode { - std::shared_ptr next; -- std::string arc_name; -- std::string node_name; -- bool is_exist; -- ArcNode() : next(nullptr), is_exist(false) { } -+ std::string from; -+ std::string to; -+ bool is_exist; /* Whether this edge exists. */ -+ bool init; /* The initial state of the edge. */ -+ ArcNode() { } -+ ArcNode(const std::string &from, const std::string &to) : next(nullptr), from(from), to(to), is_exist(false), init(false) { } - }; - - // a instance node -@@ -29,11 +31,19 @@ struct Node { - std::shared_ptr next; - std::shared_ptr head; - std::shared_ptr instance; -- int cnt; -- int real_cnt; -+ int cnt; /* Number of dependencies required for loading. */ -+ int real_cnt; /* Actual number of dependencies during loading. */ - Node(): next(nullptr), head(nullptr), cnt(0), real_cnt(0) { } - }; - -+struct pair_hash { -+ std::size_t operator() (const std::pair &pair) const { -+ auto h1 = std::hash{}(pair.first); -+ auto h2 = std::hash{}(pair.second); -+ return h1 ^ h2; -+ } -+}; -+ - class DepHandler { - public: - DepHandler() { -@@ -43,19 +53,23 @@ public: - bool get_node_state(const std::string &name) { - return this->nodes[name]->instance->get_state(); - } -+ void delete_edge(const std::string &from, const std::string &to); -+ void add_edge(const std::string &from, const std::string &to); - void add_instance(std::shared_ptr instance); - void delete_instance(const std::string &name); - bool is_instance_exist(const std::string &name); - std::shared_ptr get_instance(const std::string &name) const { -+ if (!nodes.count(name)) { -+ return nullptr; -+ } - return nodes.at(name)->instance; - } - void query_node_dependency(const std::string &name, std::vector> &query); - void query_all_dependencies(std::vector> &query); - /* check whether the instance has dependencies */ - bool have_dep(const std::string &name) { -- return arc_nodes.count(name); -+ return in_edges.count(name); - } -- std::vector get_pre_dependencies(const std::string &name); - private: - void add_node(std::shared_ptr instance); - void del_node(const std::string &name); -@@ -64,8 +78,11 @@ private: - void update_instance_state(const std::string &name); - void del_node_and_arc_nodes(std::shared_ptr node); - std::shared_ptr add_new_node(std::shared_ptr instance); -- /* indegree edges */ -- std::unordered_map>> arc_nodes; -+ /* Indegree edges. */ -+ std::unordered_map> in_edges; -+ /* Store all edges. */ -+ std::unordered_map, std::shared_ptr, pair_hash> arc_nodes; -+ /* Store all points. */ - std::unordered_map> nodes; - std::shared_ptr head; - }; -diff --git a/src/plugin_mgr/instance_run_handler.cpp b/src/plugin_mgr/instance_run_handler.cpp -index ecd7778..496166b 100644 ---- a/src/plugin_mgr/instance_run_handler.cpp -+++ b/src/plugin_mgr/instance_run_handler.cpp -@@ -20,9 +20,8 @@ static const DataRingBuf* get_ring_buf(std::shared_ptr instance) { - return instance->get_interface()->get_ring_buf(); - } - --void InstanceRunHandler::run_instance(std::shared_ptr instance) { -+void InstanceRunHandler::run_instance(std::vector &deps, InstanceRun run) { - std::vector input_data; -- std::vector deps = instance->get_deps(); - for (size_t i = 0; i < deps.size(); ++i) { - std::shared_ptr ins = memory_store.get_instance(deps[i]); - input_data.emplace_back(get_ring_buf(ins)); -@@ -30,62 +29,167 @@ void InstanceRunHandler::run_instance(std::shared_ptr instance) { - Param param; - param.ring_bufs = input_data.data(); - param.len = input_data.size(); -- instance->get_interface()->run(¶m); -+ run(¶m); - } - --void InstanceRunHandler::insert_instance(std::shared_ptr instance, uint64_t time) { -- /* To check if an instance is enabled, enable() is called in the PluginManager. */ -- schedule_queue.push(ScheduleInstance{instance, time}); -- INFO("[PluginManager] " << instance->get_name() << " instance insert into running queue."); -+void InstanceRunHandler::enable_instance(const std::string &name) { -+ std::queue> instance_node_queue; -+ auto dep_handler = memory_store.get_dep_handler(); -+ instance_node_queue.push(dep_handler.get_node(name)); -+ std::vector new_enabled; -+ bool enabled = true; -+ while (!instance_node_queue.empty()) { -+ auto node = instance_node_queue.front(); -+ instance_node_queue.pop(); -+ if (node->instance->get_enabled()) { -+ continue; -+ } -+ auto cur_name = node->instance->get_name(); -+ node->instance->set_enabled(true); -+ new_enabled.emplace_back(cur_name); -+ if (!node->instance->get_interface()->enable()) { -+ enabled = false; -+ break; -+ } -+ for (auto arc = node->head->next; arc != nullptr; arc = arc->next) { -+ if (!arc->is_exist) { -+ continue; -+ } -+ auto cur_node = dep_handler.get_node(arc->to); -+ in_degree[arc->to]++; -+ instance_node_queue.push(cur_node); -+ } -+ } -+ if (!enabled) { -+ for (auto &enabled_name : new_enabled) { -+ auto instance = dep_handler.get_instance(enabled_name); -+ instance->get_interface()->disable(); -+ instance->set_enabled(false); -+ if (enabled_name == name) { -+ continue; -+ } -+ in_degree[enabled_name]--; -+ } -+ } else { -+ for (auto &enabled_name : new_enabled) { -+ auto instance = dep_handler.get_instance(enabled_name); -+ schedule_queue.push(ScheduleInstance{instance, time}); -+ INFO("[InstanceRunHandler] " << enabled_name << " instance insert into schedule queue at time " << time); -+ } -+ } - } - --void InstanceRunHandler::delete_instance(std::shared_ptr instance) { -- instance->get_interface()->disable(); -- instance->set_enabled(false); -- INFO("[PluginManager] " << instance->get_name() << " instance delete from running queue."); -+void InstanceRunHandler::disable_instance(const std::string &name) { -+ if (in_degree[name] != 0) { -+ return; -+ } -+ std::queue> instance_node_queue; -+ auto dep_handler = memory_store.get_dep_handler(); -+ instance_node_queue.push(dep_handler.get_node(name)); -+ while (!instance_node_queue.empty()) { -+ auto node = instance_node_queue.front(); -+ auto &instance = node->instance; -+ instance_node_queue.pop(); -+ auto cur_name = instance->get_name(); -+ instance->set_enabled(false); -+ instance->get_interface()->disable(); -+ INFO("[InstanceRunHandler] " << cur_name << " instance disabled at time " << time); -+ for (auto arc = node->head->next; arc != nullptr; arc = arc->next) { -+ auto cur_node = dep_handler.get_node(arc->to); -+ arc->is_exist = arc->init; -+ /* The instance can be closed only when the indegree is 0. */ -+ if (in_degree[arc->to] <= 0 || --in_degree[arc->to] != 0) { -+ continue; -+ } -+ instance_node_queue.push(cur_node); -+ } -+ } - } - --void InstanceRunHandler::handle_instance(uint64_t time) { -- InstanceRunMessage msg; -+void InstanceRunHandler::handle_instance() { -+ std::shared_ptr msg; - while(this->recv_queue_try_pop(msg)){ -- std::shared_ptr instance = msg.get_instance(); -- switch (msg.get_type()){ -+ std::shared_ptr instance = msg->get_instance(); -+ switch (msg->get_type()){ - case RunType::ENABLED: { -- insert_instance(std::move(instance), time); -+ enable_instance(instance->get_name()); - break; - } - case RunType::DISABLED: { -- delete_instance(std::move(instance)); -+ disable_instance(instance->get_name()); - break; - } - } -+ msg->notify_one(); - } - } - --void InstanceRunHandler::schedule(uint64_t time) { -+void InstanceRunHandler::change_instance_state(const std::string &name, std::vector &deps, -+ std::vector &after_deps) { -+ for (auto &dep : deps) { -+ if (std::find(after_deps.begin(), after_deps.end(), dep) != after_deps.end()) { -+ continue; -+ } -+ auto instance = memory_store.get_instance(dep); -+ if (instance == nullptr) { -+ ERROR("[InstanceRunHandler] ilegal dependency: " << dep); -+ continue; -+ } -+ /* Disable the instance that is not required. */ -+ if (instance->get_enabled()) { -+ memory_store.delete_edge(name, instance->get_name()); -+ in_degree[instance->get_name()]--; -+ auto msg = std::make_shared(RunType::DISABLED, instance); -+ recv_queue_push(std::move(msg)); -+ } -+ } -+ for (auto &after_dep : after_deps) { -+ if (std::find(deps.begin(), deps.end(), after_dep) != deps.end()) { -+ continue; -+ } -+ auto instance = memory_store.get_instance(after_dep); -+ if (instance == nullptr) { -+ ERROR("[InstanceRunHandler] ilegal dependency: " << after_dep); -+ continue; -+ } -+ /* Enable the instance that is required. */ -+ if (!instance->get_enabled()) { -+ in_degree[instance->get_name()]++; -+ memory_store.add_edge(name, instance->get_name()); -+ auto msg = std::make_shared(RunType::ENABLED, instance); -+ recv_queue_push(std::move(msg)); -+ } -+ } -+} -+ -+void InstanceRunHandler::schedule() { - while (!schedule_queue.empty()) { - auto schedule_instance = schedule_queue.top(); -+ auto &instance = schedule_instance.instance; - if (schedule_instance.time != time) { - break; - } - schedule_queue.pop(); -- if (!schedule_instance.instance->get_enabled()) { -- break; -+ if (!instance->get_enabled()) { -+ continue; - } -- run_instance(schedule_instance.instance); -- schedule_instance.time += schedule_instance.instance->get_interface()->get_period(); -+ std::vector deps = instance->get_deps(); -+ run_instance(deps, instance->get_interface()->run); -+ schedule_instance.time += instance->get_interface()->get_period(); - schedule_queue.push(schedule_instance); -+ /* Dynamically change dependencies. */ -+ std::vector after_deps = instance->get_deps(); -+ change_instance_state(instance->get_name(), deps, after_deps); - } - } - - void start(InstanceRunHandler *instance_run_handler) { -- unsigned long long time = 0; - INFO("[PluginManager] instance schedule started!"); - while(true) { -- instance_run_handler->handle_instance(time); -- instance_run_handler->schedule(time); -+ instance_run_handler->handle_instance(); -+ instance_run_handler->schedule(); - usleep(instance_run_handler->get_cycle() * 1000); -- time += instance_run_handler->get_cycle(); -+ instance_run_handler->add_time(instance_run_handler->get_cycle()); - } - } - -diff --git a/src/plugin_mgr/instance_run_handler.h b/src/plugin_mgr/instance_run_handler.h -index f0bf263..980fd98 100644 ---- a/src/plugin_mgr/instance_run_handler.h -+++ b/src/plugin_mgr/instance_run_handler.h -@@ -27,16 +27,30 @@ enum class RunType { - class InstanceRunMessage { - public: - InstanceRunMessage() {} -- InstanceRunMessage(RunType type, std::shared_ptr instance) : type(type), instance(instance) {} -+ InstanceRunMessage(RunType type, std::shared_ptr instance) : type(type), instance(instance), finish(false) { } - RunType get_type() { - return type; - } - std::shared_ptr get_instance() { - return instance; - } -+ void wait() { -+ std::unique_lock lock(mutex); -+ cond.wait(lock, [this]() { -+ return finish; -+ }); -+ } -+ void notify_one() { -+ std::unique_lock lock(mutex); -+ finish = true; -+ cond.notify_one(); -+ } - private: - RunType type; - std::shared_ptr instance; -+ std::mutex mutex; -+ std::condition_variable cond; -+ bool finish; - }; - - class ScheduleInstance { -@@ -51,35 +65,39 @@ public: - /* A handler to schedule instances. */ - class InstanceRunHandler { - public: -- explicit InstanceRunHandler(MemoryStore &memory_store) : memory_store(memory_store), cycle(DEFAULT_CYCLE_SIZE) {} -+ using InstanceRun = void (*)(const struct Param*); -+ explicit InstanceRunHandler(MemoryStore &memory_store) : memory_store(memory_store), time(0), cycle(DEFAULT_CYCLE_SIZE) { } - void run(); -- void schedule(uint64_t time); -- void handle_instance(uint64_t time); -+ void schedule(); -+ void handle_instance(); - void set_cycle(int cycle) { - this->cycle = cycle; - } - int get_cycle() { - return cycle; - } -- void recv_queue_push(InstanceRunMessage &msg) { -- this->recv_queue.push(msg); -- } -- void recv_queue_push(InstanceRunMessage &&msg) { -+ void recv_queue_push(std::shared_ptr msg) { - this->recv_queue.push(msg); - } -- bool recv_queue_try_pop(InstanceRunMessage &msg) { -+ bool recv_queue_try_pop(std::shared_ptr &msg) { - return this->recv_queue.try_pop(msg); - } -+ void add_time(uint64_t period) { -+ time += period; -+ } -+private: -+ void run_instance(std::vector &deps, InstanceRun run); -+ void change_instance_state(const std::string &name, std::vector &deps, std::vector &after_deps); -+ void enable_instance(const std::string &name); -+ void disable_instance(const std::string &name); - private: -- void run_instance(std::shared_ptr instance); -- void delete_instance(std::shared_ptr instance); -- void insert_instance(std::shared_ptr instance, uint64_t time); -- - /* Instance execution queue. */ - std::priority_queue schedule_queue; -- /*Receives messages from the PluginManager. */ -- SafeQueue recv_queue; -+ /* Receives messages from the PluginManager. */ -+ SafeQueue> recv_queue; -+ std::unordered_map in_degree; - MemoryStore &memory_store; -+ uint64_t time; - int cycle; - static const int DEFAULT_CYCLE_SIZE = 10; - }; -diff --git a/src/plugin_mgr/interface.h b/src/plugin_mgr/interface.h -index 8aa6933..9dad5b8 100644 ---- a/src/plugin_mgr/interface.h -+++ b/src/plugin_mgr/interface.h -@@ -21,11 +21,11 @@ struct DataBuf { - - struct DataRingBuf { - /* instance name */ -- const char *instance_name; -+ const char *instance_name; - /* buf write index, initial value is -1 */ - int index; - /* instance run times */ -- uint64_t count; -+ uint64_t count; - struct DataBuf *buf; - int buf_len; - }; -diff --git a/src/plugin_mgr/memory_store.h b/src/plugin_mgr/memory_store.h -index 0e862db..a43c461 100644 ---- a/src/plugin_mgr/memory_store.h -+++ b/src/plugin_mgr/memory_store.h -@@ -58,8 +58,14 @@ public: - bool have_dep(const std::string &name) { - return dep_handler.have_dep(name); - } -- std::vector get_pre_dependencies(const std::string &name) { -- return dep_handler.get_pre_dependencies(name); -+ const DepHandler& get_dep_handler() const { -+ return dep_handler; -+ } -+ void add_edge(const std::string &from, const std::string &to) { -+ dep_handler.add_edge(from, to); -+ } -+ void delete_edge(const std::string &from, const std::string &to) { -+ dep_handler.delete_edge(from, to); - } - private: - /* instance are stored in the form of DAG. -diff --git a/src/plugin_mgr/plugin_manager.cpp b/src/plugin_mgr/plugin_manager.cpp -index 4c5f5fc..9ecaa6d 100644 ---- a/src/plugin_mgr/plugin_manager.cpp -+++ b/src/plugin_mgr/plugin_manager.cpp -@@ -22,7 +22,6 @@ void PluginManager::init(std::shared_ptr config, std::shared_ptrhandler_msg = handler_msg; - this->res_msg = res_msg; - instance_run_handler.reset(new InstanceRunHandler(memory_store)); -- pre_load(); - } - - ErrorCode PluginManager::remove(const std::string &name) { -@@ -204,35 +203,14 @@ ErrorCode PluginManager::instance_enabled(const std::string &name) { - if (instance->get_enabled()) { - return ErrorCode::ENABLE_INSTANCE_ALREADY_ENABLED; - } -- std::vector pre_dependencies = memory_store.get_pre_dependencies(name); -- std::vector> new_enabled; -- bool enabled = true; -- for (int i = pre_dependencies.size() - 1; i >= 0; --i) { -- instance = memory_store.get_instance(pre_dependencies[i]); -- if (instance->get_enabled()) { -- continue; -- } -- new_enabled.emplace_back(instance); -- if (!instance->get_interface()->enable()) { -- enabled = false; -- WARN("[PluginManager] " << instance->get_name() << " instance enabled failed, because instance init environment failed."); -- break; -- } -- } -- if (enabled) { -- for (int i = pre_dependencies.size() - 1; i >= 0; --i) { -- instance = memory_store.get_instance(pre_dependencies[i]); -- if (instance->get_enabled()) { -- continue; -- } -- instance->set_enabled(true); -- instance_run_handler->recv_queue_push(InstanceRunMessage(RunType::ENABLED, instance)); -- } -- return ErrorCode::OK; -+ std::shared_ptr msg = std::make_shared(RunType::ENABLED, instance); -+ /* Send message to InstanceRunHandler. */ -+ instance_run_handler->recv_queue_push(msg); -+ /* Wait for InstanceRunHandler to finsh this task. */ -+ msg->wait(); -+ if (msg->get_instance()->get_enabled()) { -+ return ErrorCode::OK; - } else { -- for (auto ins : new_enabled) { -- ins->get_interface()->disable(); -- } - return ErrorCode::ENABLE_INSTANCE_ENV; - } - } -@@ -248,7 +226,9 @@ ErrorCode PluginManager::instance_disabled(const std::string &name) { - if (!instance->get_enabled()) { - return ErrorCode::DISABLE_INSTANCE_ALREADY_DISABLED; - } -- instance_run_handler->recv_queue_push(InstanceRunMessage(RunType::DISABLED, instance)); -+ auto msg = std::make_shared(RunType::DISABLED, instance); -+ instance_run_handler->recv_queue_push(msg); -+ msg->wait(); - return ErrorCode::OK; - } - -@@ -397,6 +377,7 @@ bool file_exist(const std::string &file_name) { - - int PluginManager::run() { - instance_run_handler->run(); -+ pre_load(); - while (true) { - Message msg; - Message res; --- -2.33.0 - diff --git a/0007-fix-dependency-disabled-failed-and-pre-enable-illega.patch b/0007-fix-dependency-disabled-failed-and-pre-enable-illega.patch deleted file mode 100644 index 2130329..0000000 --- a/0007-fix-dependency-disabled-failed-and-pre-enable-illega.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 2a6837386db74d59e35f2ff54499d79904ae1501 Mon Sep 17 00:00:00 2001 -From: fly_1997 -Date: Thu, 13 Jun 2024 10:06:04 +0800 -Subject: [PATCH 1/2] fix dependency disabled failed and pre-enable illegal - plugin - ---- - src/plugin_mgr/instance_run_handler.cpp | 17 ++++++++++------- - src/plugin_mgr/instance_run_handler.h | 4 +++- - src/plugin_mgr/plugin_manager.cpp | 12 ++++++------ - 3 files changed, 19 insertions(+), 14 deletions(-) - -diff --git a/src/plugin_mgr/instance_run_handler.cpp b/src/plugin_mgr/instance_run_handler.cpp -index 496166b..928b555 100644 ---- a/src/plugin_mgr/instance_run_handler.cpp -+++ b/src/plugin_mgr/instance_run_handler.cpp -@@ -79,10 +79,11 @@ void InstanceRunHandler::enable_instance(const std::string &name) { - } - } - --void InstanceRunHandler::disable_instance(const std::string &name) { -- if (in_degree[name] != 0) { -+void InstanceRunHandler::disable_instance(const std::string &name, RunType type) { -+ if (type == RunType::INTERNAL_DISABLED && in_degree[name] != 0) { - return; - } -+ in_degree[name] = 0; - std::queue> instance_node_queue; - auto dep_handler = memory_store.get_dep_handler(); - instance_node_queue.push(dep_handler.get_node(name)); -@@ -111,12 +112,14 @@ void InstanceRunHandler::handle_instance() { - while(this->recv_queue_try_pop(msg)){ - std::shared_ptr instance = msg->get_instance(); - switch (msg->get_type()){ -- case RunType::ENABLED: { -+ case RunType::ENABLED: -+ case RunType::INTERNAL_ENABLED: { - enable_instance(instance->get_name()); - break; - } -- case RunType::DISABLED: { -- disable_instance(instance->get_name()); -+ case RunType::DISABLED: -+ case RunType::INTERNAL_DISABLED: { -+ disable_instance(instance->get_name(), msg->get_type()); - break; - } - } -@@ -139,7 +142,7 @@ void InstanceRunHandler::change_instance_state(const std::string &name, std::vec - if (instance->get_enabled()) { - memory_store.delete_edge(name, instance->get_name()); - in_degree[instance->get_name()]--; -- auto msg = std::make_shared(RunType::DISABLED, instance); -+ auto msg = std::make_shared(RunType::INTERNAL_DISABLED, instance); - recv_queue_push(std::move(msg)); - } - } -@@ -156,7 +159,7 @@ void InstanceRunHandler::change_instance_state(const std::string &name, std::vec - if (!instance->get_enabled()) { - in_degree[instance->get_name()]++; - memory_store.add_edge(name, instance->get_name()); -- auto msg = std::make_shared(RunType::ENABLED, instance); -+ auto msg = std::make_shared(RunType::INTERNAL_ENABLED, instance); - recv_queue_push(std::move(msg)); - } - } -diff --git a/src/plugin_mgr/instance_run_handler.h b/src/plugin_mgr/instance_run_handler.h -index 980fd98..682510b 100644 ---- a/src/plugin_mgr/instance_run_handler.h -+++ b/src/plugin_mgr/instance_run_handler.h -@@ -21,6 +21,8 @@ - enum class RunType { - ENABLED, - DISABLED, -+ INTERNAL_ENABLED, -+ INTERNAL_DISABLED, - }; - - /* Message for communication between plugin manager and instance scheduling */ -@@ -89,7 +91,7 @@ private: - void run_instance(std::vector &deps, InstanceRun run); - void change_instance_state(const std::string &name, std::vector &deps, std::vector &after_deps); - void enable_instance(const std::string &name); -- void disable_instance(const std::string &name); -+ void disable_instance(const std::string &name, RunType type); - private: - /* Instance execution queue. */ - std::priority_queue schedule_queue; -diff --git a/src/plugin_mgr/plugin_manager.cpp b/src/plugin_mgr/plugin_manager.cpp -index 9ecaa6d..7220f48 100644 ---- a/src/plugin_mgr/plugin_manager.cpp -+++ b/src/plugin_mgr/plugin_manager.cpp -@@ -282,13 +282,13 @@ ErrorCode PluginManager::download(const std::string &name, std::string &res) { - void PluginManager::pre_enable() { - for (size_t i = 0; i < config->get_enable_list_size(); ++i) { - EnableItem item = config->get_enable_list(i); -+ std::string plugin_name = item.get_name(); -+ if (!memory_store.is_plugin_exist(plugin_name)) { -+ WARN("[PluginManager] plugin " << plugin_name << " cannot be enabled, because it does not exist."); -+ continue; -+ } - if (item.get_enabled()) { -- std::string name = item.get_name(); -- if (!memory_store.is_plugin_exist(name)) { -- WARN("[PluginManager] plugin " << name << " cannot be enabled, because it does not exist."); -- continue; -- } -- std::shared_ptr plugin = memory_store.get_plugin(name); -+ std::shared_ptr plugin = memory_store.get_plugin(plugin_name); - for (size_t j = 0; j < plugin->get_instance_len(); ++j) { - instance_enabled(plugin->get_instance(j)->get_name()); - } --- -2.33.0 - diff --git a/0008-fix-dependency-error-and-add-enable-failed-logs.patch b/0008-fix-dependency-error-and-add-enable-failed-logs.patch deleted file mode 100644 index 5104769..0000000 --- a/0008-fix-dependency-error-and-add-enable-failed-logs.patch +++ /dev/null @@ -1,138 +0,0 @@ -From 918ef95a2e5f9de71efa55beee35eaa083c31b7d Mon Sep 17 00:00:00 2001 -From: fly_1997 -Date: Thu, 13 Jun 2024 16:28:19 +0800 -Subject: [PATCH 2/2] fix dependency error and add enable failed logs - ---- - src/plugin_mgr/dep_handler.cpp | 22 +++++++++++++--------- - src/plugin_mgr/instance_run_handler.h | 2 ++ - src/plugin_mgr/plugin_manager.cpp | 17 ++++++++++++----- - 3 files changed, 27 insertions(+), 14 deletions(-) - -diff --git a/src/plugin_mgr/dep_handler.cpp b/src/plugin_mgr/dep_handler.cpp -index 227ee2f..2b20e7e 100644 ---- a/src/plugin_mgr/dep_handler.cpp -+++ b/src/plugin_mgr/dep_handler.cpp -@@ -28,22 +28,26 @@ void DepHandler::add_arc_node(std::shared_ptr node, const std::vector arc_head = node->head; - node->cnt = dep_nodes.size(); - int real_cnt = 0; -+ bool state = true; - for (auto name : dep_nodes) { - std::string from = node->instance->get_name(); - std::shared_ptr tmp = std::make_shared(from, name); - tmp->next = arc_head->next; - arc_head->next = tmp; -- -+ tmp->init = true; - if (nodes.count(name)) { - tmp->is_exist = true; -- tmp->init = true; - real_cnt++; -+ if (!nodes[name]->instance->get_state()) { -+ state = false; -+ } - } - in_edges[name].insert(from); - arc_nodes[std::make_pair(from, name)] = tmp; - } -+ /* node->instance->state = true, only all dependencies meet the conditions. */ - if (real_cnt == node->cnt) { -- node->instance->set_state(true); -+ node->instance->set_state(state); - } - node->real_cnt = real_cnt; - } -@@ -115,18 +119,17 @@ void DepHandler::del_node_and_arc_nodes(std::shared_ptr node) { - } - - void DepHandler::update_instance_state(const std::string &name) { -- if (!nodes[name]->instance->get_state() || !in_edges.count(name)) return; -+ if (!in_edges.count(name)) return; - std::unordered_set &arcs = in_edges[name]; - for (auto &from : arcs) { - auto arc_node = arc_nodes[std::make_pair(from, name)]; - if (nodes.count(from)) { - auto tmp = nodes[from]; - tmp->real_cnt++; -- if (tmp->real_cnt == tmp->cnt) { -+ if (tmp->real_cnt == tmp->cnt && nodes[name]->instance->get_state()) { - tmp->instance->set_state(true); - } - arc_node->is_exist = true; -- arc_node->init = true; - update_instance_state(tmp->instance->get_name()); - } - } -@@ -144,8 +147,9 @@ void DepHandler::query_node_top(const std::string &name, std::vector{name}); - return; - } -- while (arc_node->next != nullptr) { -- if (arc_node->next->is_exist) { -+ while (arc_node->next != nullptr) { -+ /* Display the edges that exist and the points that do not. */ -+ if (arc_node->next->is_exist || !nodes.count(arc_node->next->to)) { - query.emplace_back(std::vector{name, arc_node->next->to}); - } - arc_node = arc_node->next; -@@ -164,7 +168,7 @@ void DepHandler::query_node_dependency(const std::string &name, std::vectorinstance->get_name(); - query.emplace_back(std::vector{node_name}); - for (auto cur = node->head->next; cur != nullptr; cur = cur->next) { -- if (cur->is_exist) { -+ if (cur->is_exist || !nodes.count(cur->to)) { - query.emplace_back(std::vector{node_name, cur->to}); - } - if (!vis.count(cur->to) && nodes.count(cur->to)) { -diff --git a/src/plugin_mgr/instance_run_handler.h b/src/plugin_mgr/instance_run_handler.h -index 682510b..3804a49 100644 ---- a/src/plugin_mgr/instance_run_handler.h -+++ b/src/plugin_mgr/instance_run_handler.h -@@ -19,8 +19,10 @@ - #include - - enum class RunType { -+ /* Message from PluginManager. */ - ENABLED, - DISABLED, -+ /* Message from internal. */ - INTERNAL_ENABLED, - INTERNAL_DISABLED, - }; -diff --git a/src/plugin_mgr/plugin_manager.cpp b/src/plugin_mgr/plugin_manager.cpp -index 7220f48..c3ff8bf 100644 ---- a/src/plugin_mgr/plugin_manager.cpp -+++ b/src/plugin_mgr/plugin_manager.cpp -@@ -290,16 +290,23 @@ void PluginManager::pre_enable() { - if (item.get_enabled()) { - std::shared_ptr plugin = memory_store.get_plugin(plugin_name); - for (size_t j = 0; j < plugin->get_instance_len(); ++j) { -- instance_enabled(plugin->get_instance(j)->get_name()); -+ std::string name = plugin->get_instance(j)->get_name(); -+ auto ret = instance_enabled(name); -+ if (ret != ErrorCode::OK) { -+ WARN("[PluginManager] " << name << " instance pre-enabled failed, because " << ErrorText::get_error_text(ret) << "."); -+ } else { -+ INFO("[PluginManager] " << name << " instance pre-enabled."); -+ } - } - } else { - for (size_t j = 0; j < item.get_instance_size(); ++j) { - std::string name = item.get_instance_name(j); -- if (!memory_store.is_instance_exist(name)) { -- WARN("[PluginManager] instance " << name << " cannot be enabled, because it does not exist."); -- continue; -+ auto ret = instance_enabled(name); -+ if (ret != ErrorCode::OK) { -+ WARN("[PluginManager] " << name << " instance pre-enabled failed, because " << ErrorText::get_error_text(ret) << "."); -+ } else { -+ INFO("[PluginManager] " << name << " instance pre-enabled."); - } -- instance_enabled(name); - } - } - } --- -2.33.0 - diff --git a/oeAware-manager-v1.0.1.tar.gz b/oeAware-manager-v1.0.1.tar.gz deleted file mode 100644 index f66e036e87a40e0edf8cc9e8d7ce87c85dfd6b08..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26719 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 c4PDJ_7i0aAzZ|~dR+DLXp_h6* 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 -v1.0.2-1 +- update version to v1.0.2-1 + * Fri Jun 14 2024 fly_1997 -v1.0.1-6 - fix dependency error and add enable failed logs - fix dependency disabled failed and pre-enable illegal plugin