Skip to content

Commit

Permalink
add class process to common
Browse files Browse the repository at this point in the history
  • Loading branch information
jean-christophe81 committed May 21, 2024
1 parent 4ebd948 commit 85c8130
Show file tree
Hide file tree
Showing 15 changed files with 693 additions and 32 deletions.
1 change: 1 addition & 0 deletions common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ add_custom_command(
set(SOURCES
${SRC_DIR}/hex_dump.cc
${SRC_DIR}/pool.cc
${SRC_DIR}/process.cc
${SRC_DIR}/process_stat.cc
${SRC_DIR}/process_stat.pb.cc
${SRC_DIR}/process_stat.grpc.pb.cc
Expand Down
6 changes: 3 additions & 3 deletions common/http/inc/com/centreon/common/http/http_client.hh
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,9 @@ class client : public std::enable_shared_from_this<client> {

protected:
client(const std::shared_ptr<asio::io_context>& io_context,
const std::shared_ptr<spdlog::logger>& logger,
const http_config::pointer& conf,
connection_creator conn_creator);
const std::shared_ptr<spdlog::logger>& logger,
const http_config::pointer& conf,
connection_creator conn_creator);

public:
using pointer = std::shared_ptr<client>;
Expand Down
6 changes: 3 additions & 3 deletions common/http/inc/com/centreon/common/http/http_server.hh
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ class server : public std::enable_shared_from_this<server> {
using pointer = std::shared_ptr<server>;

server(const std::shared_ptr<asio::io_context>& io_context,
const std::shared_ptr<spdlog::logger>& logger,
const http_config::pointer& conf,
connection_creator&& conn_creator);
const std::shared_ptr<spdlog::logger>& logger,
const http_config::pointer& conf,
connection_creator&& conn_creator);

~server();

Expand Down
30 changes: 15 additions & 15 deletions common/http/src/http_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ using lock_guard = std::lock_guard<std::mutex>;
* server, it can be a http_connection::load, https_connection::load....
*/
client::client(const std::shared_ptr<asio::io_context>& io_context,
const std::shared_ptr<spdlog::logger>& logger,
const http_config::pointer& conf,
connection_creator conn_creator)
const std::shared_ptr<spdlog::logger>& logger,
const http_config::pointer& conf,
connection_creator conn_creator)
: _io_context(io_context),
_logger(logger),
_conf(conf),
Expand Down Expand Up @@ -84,7 +84,7 @@ client::pointer client::load(
* @return false if enqueue
*/
bool client::_send_or_push(const cb_request::pointer request,
bool push_to_front) {
bool push_to_front) {
if (_halt) {
return false;
}
Expand Down Expand Up @@ -199,7 +199,7 @@ void client::_send_first_queue_request() {
* @param conn
*/
void client::_send(const cb_request::pointer& request,
connection_base::pointer conn) {
connection_base::pointer conn) {
if (_logger->level() == spdlog::level::trace) {
SPDLOG_LOGGER_TRACE(_logger, "send {} on {:p}", *request->request,
static_cast<void*>(conn.get()));
Expand All @@ -226,9 +226,9 @@ void client::_send(const cb_request::pointer& request,
* @param conn
*/
void client::_on_connect(const boost::beast::error_code& error,
const std::string& detail,
const cb_request::pointer& request,
connection_base::pointer conn) {
const std::string& detail,
const cb_request::pointer& request,
connection_base::pointer conn) {
if (error) { // error => shutdown and retry
SPDLOG_LOGGER_ERROR(_logger, "{:p} fail to connect {}: {}",
static_cast<void*>(conn.get()), error.message(),
Expand Down Expand Up @@ -264,10 +264,10 @@ void client::_on_connect(const boost::beast::error_code& error,
* @param conn
*/
void client::_on_sent(const boost::beast::error_code& error,
const std::string& detail,
const cb_request::pointer& request,
const response_ptr& response,
connection_base::pointer conn) {
const std::string& detail,
const cb_request::pointer& request,
const response_ptr& response,
connection_base::pointer conn) {
cb_request::pointer to_call;
if (error) { // error => shutdown and _retry
SPDLOG_LOGGER_ERROR(_logger, "{:p} fail to send request",
Expand Down Expand Up @@ -363,9 +363,9 @@ void client::shutdown() {
* @param response
*/
void client::_retry(const boost::beast::error_code& error,
const std::string& detail,
const cb_request::pointer& request,
const response_ptr& response) {
const std::string& detail,
const cb_request::pointer& request,
const response_ptr& response) {
cb_request::pointer to_call;

if (_halt) { // object halted => callback without _retry
Expand Down
8 changes: 4 additions & 4 deletions common/http/src/http_server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
using namespace com::centreon::common::http;

server::server(const std::shared_ptr<asio::io_context>& io_context,
const std::shared_ptr<spdlog::logger>& logger,
const http_config::pointer& conf,
connection_creator&& conn_creator)
const std::shared_ptr<spdlog::logger>& logger,
const http_config::pointer& conf,
connection_creator&& conn_creator)
: _io_context(io_context),
_logger(logger),
_conf(conf),
Expand Down Expand Up @@ -78,7 +78,7 @@ void server::start_accept() {
}

void server::on_accept(const boost::beast::error_code& err,
const connection_base::pointer& conn) {
const connection_base::pointer& conn) {
if (err) {
if (err != boost::asio::error::operation_aborted) {
SPDLOG_LOGGER_ERROR(_logger, "fail accept connection on {}: {}",
Expand Down
151 changes: 151 additions & 0 deletions common/inc/com/centreon/common/process.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/*
** Copyright 2024 Centreon
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
**
** For more information : [email protected]
*/
#ifndef CENTREON_AGENT_CHECK_PROCESS_HH
#define CENTREON_AGENT_CHECK_PROCESS_HH

namespace com::centreon::common {

namespace detail {
// here to limit included files
struct boost_process;
} // namespace detail

/**
* @brief This class allow to exec a process asynchronously.
* It's a base class. If you want to get stdin and stdout returned data, you
* must inherit from this and override on_stdout_read and on_stderr_read
* You can call start_process at any moment, if a process is already running,
* it's killed
* As we can start a process at any moment, all handlers take a caller in
* parameter, if this caller is not equal to current _proc, we do nothing.
* When handler like on_stdout_read are called, _protect is already locked
*/
class process : public std::enable_shared_from_this<process> {
std::shared_ptr<asio::io_context> _io_context;
std::shared_ptr<spdlog::logger> _logger;

std::string _exe_path;
std::vector<std::string> _args;

std::deque<std::shared_ptr<std::string>> _stdin_write_queue;
bool _write_pending = false;

// it would be better to user an unique_ptr but gcc complains because he
// doesn't know boost_process size
detail::boost_process* _proc = nullptr;

int _exit_status = 0;

std::mutex _protect;

void stdin_write_no_lock(const std::shared_ptr<std::string>& data);
void stdin_write(const std::shared_ptr<std::string>& data);

void stdout_read();
void stderr_read();

protected:
char _stdout_read_buffer[0x1000];
char _stderr_read_buffer[0x1000];

virtual void on_stdout_read(const boost::system::error_code& err,
size_t nb_read);
virtual void on_stderr_read(const boost::system::error_code& err,
size_t nb_read);

virtual void on_process_end(const boost::system::error_code& err,
int raw_exit_status);

virtual void on_stdin_write(const boost::system::error_code& err);

public:
template <typename string_iterator>
process(const std::shared_ptr<boost::asio::io_context>& io_context,
const std::shared_ptr<spdlog::logger>& logger,
const std::string& exe_path,
string_iterator arg_begin,
string_iterator arg_end);

template <typename args_container>
process(const std::shared_ptr<boost::asio::io_context>& io_context,
const std::shared_ptr<spdlog::logger>& logger,
const std::string& exe_path,
const args_container& args);

template <typename string_type>
process(const std::shared_ptr<boost::asio::io_context>& io_context,
const std::shared_ptr<spdlog::logger>& logger,
const std::string& exe_path,
const std::initializer_list<string_type>& args);

process(const std::shared_ptr<boost::asio::io_context>& io_context,
const std::shared_ptr<spdlog::logger>& logger,
const std::string& cmd_line);

virtual ~process();

template <typename string_class>
void write_to_stdin(const string_class& content);

void start_process();

void kill();

int get_exit_status() const { return _exit_status; }
};

template <typename string_iterator>
process::process(const std::shared_ptr<asio::io_context>& io_context,
const std::shared_ptr<spdlog::logger>& logger,
const std::string& exe_path,
string_iterator arg_begin,
string_iterator arg_end)
: _io_context(io_context),
_logger(logger),
_exe_path(exe_path),
_args(arg_begin, arg_end) {}

template <typename args_container>
process::process(const std::shared_ptr<boost::asio::io_context>& io_context,
const std::shared_ptr<spdlog::logger>& logger,
const std::string& exe_path,
const args_container& args)
: _io_context(io_context),
_logger(logger),
_exe_path(exe_path),
_args(args) {}

template <typename string_type>
process::process(const std::shared_ptr<boost::asio::io_context>& io_context,
const std::shared_ptr<spdlog::logger>& logger,
const std::string& exe_path,
const std::initializer_list<string_type>& args)
: _io_context(io_context), _logger(logger), _exe_path(exe_path) {
_args.reserve(args.size());
for (const auto& str : args) {
_args.emplace_back(str);
}
}

template <typename string_class>
void process::write_to_stdin(const string_class& content) {
stdin_write(std::make_shared<std::string>(content));
}

} // namespace com::centreon::common
#endif
1 change: 1 addition & 0 deletions common/inc/com/centreon/common/rapidjson_helper.hh
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ class rapidjson_helper {
// as overriding can't be done with returned type, we use a templated method
template <typename value_type>
value_type get(const char* field_name);

const rapidjson::Value& get_member(const char* field_name) const;

/**
Expand Down
2 changes: 2 additions & 0 deletions common/precomp_inc/precomp.hh
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@
#include <deque>
#include <forward_list>
#include <fstream>
#include <functional>
#include <map>
#include <mutex>
#include <queue>
#include <regex>
#include <set>
#include <string>
Expand Down
Loading

0 comments on commit 85c8130

Please sign in to comment.