2020-05-05 13:39:59 +00:00
|
|
|
#include "events/send.hh"
|
|
|
|
#include "events/receive.hh"
|
|
|
|
#include "events/register.hh"
|
|
|
|
#include "error/connection-closed.hh"
|
|
|
|
#include "error/parsing-error.hh"
|
2020-05-05 18:43:35 +00:00
|
|
|
#include "misc/logger.hh"
|
|
|
|
#include "misc/addrinfo/addrinfo.hh"
|
|
|
|
#include "error/connection-failed.hh"
|
2020-05-05 13:39:59 +00:00
|
|
|
|
|
|
|
namespace paxos
|
|
|
|
{
|
|
|
|
SendEW::SendEW(shared_connection connection)
|
|
|
|
: EventWatcher(connection->get_socket_fd()->fd_, EV_WRITE)
|
|
|
|
, connection_(connection)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
SendEW::~SendEW()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void SendEW::operator()()
|
|
|
|
{
|
2020-05-05 18:50:55 +00:00
|
|
|
shared_socket sock = connection_->get_socket();
|
2020-05-05 13:39:59 +00:00
|
|
|
|
2020-05-05 18:50:55 +00:00
|
|
|
auto buffer = connection_->get_buffer_out();
|
|
|
|
std::string response = buffer.to_string();
|
|
|
|
|
|
|
|
log(response, white);
|
|
|
|
ssize_t write = 0;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
write = sock->send(response.c_str(), response.size());
|
|
|
|
}
|
|
|
|
catch (const std::system_error& e)
|
|
|
|
{
|
|
|
|
std::cerr << "Connection closed while sending\n";
|
|
|
|
event_register.unregister_ew(this);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (write == -1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
buffer.pop_front(write);
|
|
|
|
if (!buffer.empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
event_register.unregister_ew(this);
|
2020-05-05 13:39:59 +00:00
|
|
|
}
|
2020-05-05 18:43:35 +00:00
|
|
|
|
|
|
|
static shared_socket connect_to_ip_port(std::string ip, std::string port)
|
|
|
|
{
|
|
|
|
/* prepare hints structure */
|
|
|
|
misc::AddrInfoHint hints;
|
|
|
|
hints.family(AF_UNSPEC);
|
|
|
|
hints.socktype(SOCK_STREAM);
|
|
|
|
misc::AddrInfo result = misc::getaddrinfo(ip.c_str(), port.c_str(), hints);
|
|
|
|
|
|
|
|
for (auto it : result)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
auto vhost_socket = std::make_shared<DefaultSocket>
|
|
|
|
(it.ai_family, it.ai_socktype, it.ai_protocol);
|
|
|
|
vhost_socket->connect(it.ai_addr, it.ai_addrlen);
|
|
|
|
vhost_socket->fcntl_set_O_NONBLOCK();
|
|
|
|
return vhost_socket;
|
|
|
|
}
|
|
|
|
catch (const std::exception& e)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
throw ConnectionFailed();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SendEW::send_message(Message message, shared_legislator legislator)
|
|
|
|
{
|
|
|
|
std::string ip = legislator->config_.ip;
|
|
|
|
std::string port = legislator->config_.port;
|
2020-05-05 22:46:42 +00:00
|
|
|
std::string name = legislator->config_.name;
|
2020-05-05 18:43:35 +00:00
|
|
|
shared_socket socket;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
socket = connect_to_ip_port(ip, port);
|
|
|
|
}
|
|
|
|
catch (const ConnectionFailed& e)
|
|
|
|
{
|
2020-05-05 22:46:42 +00:00
|
|
|
log("Could not connect to " + name, red);
|
2020-05-05 18:50:55 +00:00
|
|
|
return;
|
2020-05-05 18:43:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
shared_connection connection = std::make_shared<Connection>(socket);
|
|
|
|
message.fill_buffer(connection->get_buffer_out());
|
|
|
|
|
|
|
|
event_register.register_event<SendEW>(connection);
|
2020-05-05 22:46:42 +00:00
|
|
|
log("Sending a message to " + name + ": ", blue);
|
2020-05-05 18:43:35 +00:00
|
|
|
}
|
2020-05-05 13:39:59 +00:00
|
|
|
}
|