Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pull in mikezackles' daemonize changes from upstream dev branch #243

Merged
merged 10 commits into from
Mar 24, 2015
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -238,12 +238,18 @@ if (BOOST_IGNORE_SYSTEM_PATHS)
set(Boost_NO_SYSTEM_PATHS TRUE)
endif()

set(OLD_LIB_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
if(STATIC)
if(MINGW)
set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
endif()

set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_STATIC_RUNTIME ON)
endif()
find_package(Boost 1.53 QUIET REQUIRED COMPONENTS system filesystem thread date_time chrono regex serialization program_options)

set(CMAKE_FIND_LIBRARY_SUFFIXES ${OLD_LIB_SUFFIXES})
if(NOT Boost_FOUND)
die("Could not find Boost libraries, please make sure you have installed Boost or libboost-all-dev (1.53 or 1.55+) or the equivalent")
endif()
Expand Down
105 changes: 51 additions & 54 deletions contrib/epee/include/console_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@

#pragma once

#include "misc_log_ex.h"
#include <atomic>
#include <condition_variable>
#include <functional>
#include <mutex>
#include <thread>
#include <iostream>

namespace epee
{
Expand Down Expand Up @@ -290,7 +292,7 @@ namespace epee

private:
async_stdin_reader m_stdin_reader;
bool m_running = true;
std::atomic<bool> m_running = {true};
};


Expand Down Expand Up @@ -350,17 +352,11 @@ namespace epee
return true;
}*/

/************************************************************************/
/* */
/************************************************************************/
class console_handlers_binder
{
typedef boost::function<bool (const std::vector<std::string> &)> console_command_handler;
typedef std::map<std::string, std::pair<console_command_handler, std::string> > command_handlers_map;
std::unique_ptr<boost::thread> m_console_thread;
command_handlers_map m_command_handlers;
async_console_handler m_console_handler;
class command_handler {
public:
typedef boost::function<bool (const std::vector<std::string> &)> callback;
typedef std::map<std::string, std::pair<callback, std::string> > lookup;

std::string get_usage()
{
std::stringstream ss;
Expand All @@ -376,12 +372,14 @@ namespace epee
}
return ss.str();
}
void set_handler(const std::string& cmd, const console_command_handler& hndlr, const std::string& usage = "")

void set_handler(const std::string& cmd, const callback& hndlr, const std::string& usage = "")
{
command_handlers_map::mapped_type & vt = m_command_handlers[cmd];
lookup::mapped_type & vt = m_command_handlers[cmd];
vt.first = hndlr;
vt.second = usage;
}

bool process_command_vec(const std::vector<std::string>& cmd)
{
if(!cmd.size())
Expand All @@ -399,14 +397,20 @@ namespace epee
boost::split(cmd_v,cmd,boost::is_any_of(" "), boost::token_compress_on);
return process_command_vec(cmd_v);
}
private:
lookup m_command_handlers;
};

/*template<class t_srv>
bool start_handling(t_srv& srv, const std::string& usage_string = "")
{
start_default_console_handler_no_srv_param(&srv, boost::bind(&console_handlers_binder::process_command_str, this, _1));
return true;
}*/

/************************************************************************/
/* */
/************************************************************************/
class console_handlers_binder : public command_handler
{
typedef command_handler::callback console_command_handler;
typedef command_handler::lookup command_handlers_map;
std::unique_ptr<boost::thread> m_console_thread;
async_console_handler m_console_handler;
public:
bool start_handling(const std::string& prompt, const std::string& usage_string = "")
{
m_console_thread.reset(new boost::thread(boost::bind(&console_handlers_binder::run_handling, this, prompt, usage_string)));
Expand All @@ -423,40 +427,33 @@ namespace epee
{
return m_console_handler.run(boost::bind(&console_handlers_binder::process_command_str, this, _1), prompt, usage_string);
}

/*template<class t_srv>
bool run_handling(t_srv& srv, const std::string& usage_string)
{
return run_default_console_handler_no_srv_param(&srv, boost::bind<bool>(&console_handlers_binder::process_command_str, this, _1), usage_string);
}*/
};

/* work around because of broken boost bind */
template<class t_server>
class srv_console_handlers_binder: public console_handlers_binder
{
bool process_command_str(t_server* /*psrv*/, const std::string& cmd)
{
return console_handlers_binder::process_command_str(cmd);
}
public:
bool start_handling(t_server* psrv, const std::string& prompt, const std::string& usage_string = "")
{
boost::thread(boost::bind(&srv_console_handlers_binder<t_server>::run_handling, this, psrv, prompt, usage_string)).detach();
return true;
}

bool run_handling(t_server* psrv, const std::string& prompt, const std::string& usage_string)
{
return m_console_handler.run(psrv, boost::bind(&srv_console_handlers_binder<t_server>::process_command_str, this, _1, _2), prompt, usage_string);
}

void stop_handling()
{
m_console_handler.stop();
}

private:
async_console_handler m_console_handler;
};
///* work around because of broken boost bind */
//template<class t_server>
//class srv_console_handlers_binder: public command_handler
//{
// async_console_handler m_console_handler;
//public:
// bool start_handling(t_server* psrv, const std::string& prompt, const std::string& usage_string = "")
// {
// boost::thread(boost::bind(&srv_console_handlers_binder<t_server>::run_handling, this, psrv, prompt, usage_string)).detach();
// return true;
// }

// bool run_handling(t_server* psrv, const std::string& prompt, const std::string& usage_string)
// {
// return m_console_handler.run(psrv, boost::bind(&srv_console_handlers_binder<t_server>::process_command_str, this, _1, _2), prompt, usage_string);
// }

// void stop_handling()
// {
// m_console_handler.stop();
// }
//private:
// bool process_command_str(t_server* /*psrv*/, const std::string& cmd)
// {
// return console_handlers_binder::process_command_str(cmd);
// }
//};
}
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,5 @@ add_subdirectory(wallet)
add_subdirectory(connectivity_tool)
add_subdirectory(miner)
add_subdirectory(simplewallet)
add_subdirectory(daemonizer)
add_subdirectory(daemon)
3 changes: 3 additions & 0 deletions src/common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,11 @@ set(common_private_headers
boost_serialization_helper.h
command_line.h
dns_utils.h
http_connection.h
int-util.h
pod-class.h
rpc_client.h
scoped_message_writer.h
unordered_containers_boost_serialization.h
util.h
varint.h)
Expand Down
42 changes: 42 additions & 0 deletions src/common/http_connection.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#pragma once

#include "string_tools.h"
#include "net/http_client.h"

namespace tools {

class t_http_connection {
private:
epee::net_utils::http::http_simple_client * mp_http_client;
bool m_ok;
public:
static unsigned int const TIMEOUT = 200000;

t_http_connection(
epee::net_utils::http::http_simple_client * p_http_client
, uint32_t ip
, uint16_t port
)
: mp_http_client(p_http_client)
{
// TODO fix http client so that it accepts properly typed arguments
std::string ip_str = epee::string_tools::get_ip_string_from_int32(ip);
std::string port_str = boost::lexical_cast<std::string>(port);
m_ok = mp_http_client->connect(ip_str, port_str, TIMEOUT);
}

~t_http_connection()
{
if (m_ok)
{
mp_http_client->disconnect();
}
}

bool is_open()
{
return m_ok;
}
}; // class t_http_connection

} // namespace tools
132 changes: 132 additions & 0 deletions src/common/rpc_client.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#pragma once

#include "common/http_connection.h"
#include "common/scoped_message_writer.h"
#include "rpc/core_rpc_server_commands_defs.h"
#include "storages/http_abstract_invoke.h"
#include "net/http_client.h"
#include "string_tools.h"
#include <boost/lexical_cast.hpp>

namespace tools
{
class t_rpc_client final
{
private:
epee::net_utils::http::http_simple_client m_http_client;
uint32_t m_ip;
uint16_t m_port;
public:
t_rpc_client(
uint32_t ip
, uint16_t port
)
: m_http_client{}
, m_ip{ip}
, m_port{port}
{}

std::string build_url(std::string const & relative_url)
{
std::string result =
"http://"
+ epee::string_tools::get_ip_string_from_int32(m_ip)
+ ":"
+ boost::lexical_cast<std::string>(m_port)
+ relative_url;
return result;
}

template <typename T_req, typename T_res>
bool basic_json_rpc_request(
T_req & req
, T_res & res
, std::string const & method_name
)
{
std::string rpc_url = build_url("/json_rpc");
t_http_connection connection(&m_http_client, m_ip, m_port);

bool ok = connection.is_open();
if (!ok)
{
fail_msg_writer() << "Couldn't connect to daemon";
return false;
}
ok = ok && epee::net_utils::invoke_http_json_rpc(rpc_url, method_name, req, res, m_http_client);
if (!ok)
{
fail_msg_writer() << "Daemon request failed";
return false;
}
else
{
return true;
}
}

template <typename T_req, typename T_res>
bool json_rpc_request(
T_req & req
, T_res & res
, std::string const & method_name
, std::string const & fail_msg
)
{
std::string rpc_url = build_url("/json_rpc");
t_http_connection connection(&m_http_client, m_ip, m_port);

bool ok = connection.is_open();
ok = ok && epee::net_utils::invoke_http_json_rpc(rpc_url, method_name, req, res, m_http_client);
if (!ok)
{
fail_msg_writer() << "Couldn't connect to daemon";
return false;
}
else if (res.status != CORE_RPC_STATUS_OK) // TODO - handle CORE_RPC_STATUS_BUSY ?
{
fail_msg_writer() << fail_msg << " -- " << res.status;
return false;
}
else
{
return true;
}
}

template <typename T_req, typename T_res>
bool rpc_request(
T_req & req
, T_res & res
, std::string const & relative_url
, std::string const & fail_msg
)
{
std::string rpc_url = build_url(relative_url);
t_http_connection connection(&m_http_client, m_ip, m_port);

bool ok = connection.is_open();
ok = ok && epee::net_utils::invoke_http_json_remote_command2(rpc_url, req, res, m_http_client);
if (!ok)
{
fail_msg_writer() << "Couldn't connect to daemon";
return false;
}
else if (res.status != CORE_RPC_STATUS_OK) // TODO - handle CORE_RPC_STATUS_BUSY ?
{
fail_msg_writer() << fail_msg << " -- " << res.status;
return false;
}
else
{
return true;
}
}

bool check_connection()
{
t_http_connection connection(&m_http_client, m_ip, m_port);
return connection.is_open();
}
};
}
Loading