Files
spark/src/lib/jetfix/connection/SocketConnection.cpp
T

131 lines
3.8 KiB
C++

#include "SocketConnection.h"
#include "lib/jetfix/store/session_name.h"
#include "lib/logging/logging.h"
#include "lib/tracing/bts_trace.h"
#include "lib/utils/TimeStamp.h"
#include "lib/utils/bts_assert.h"
#include "lib/utils/helper_macros.h"
#include "lib/tracing/PerfLog.h"
#include <arpa/inet.h>
#include <fstream>
#include <netinet/tcp.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
namespace bts {
namespace jetfix {
SocketConnection::SocketConnection(bts::config::JetFIX::Connection const &cfg,
trace::PerfLog &perf_log)
: _fd(-1), _cfg(cfg), _log(cfg.log_fix_stream()), _in_log(), _out_log(),
_perf_log(perf_log) {
if (_log) {
_in_log.open(std::string("/tmp/fix_raw_read_log_") + session_name(cfg),
std::ios_base::app);
_out_log.open(std::string("/tmp/fix_raw_write_log_") + session_name(cfg),
std::ios_base::app);
}
}
SocketConnection::~SocketConnection() {
if (_fd > 0)
close(_fd);
}
bool SocketConnection::connect() {
bts_assert(_fd == -1);
_fd = socket(AF_INET, SOCK_STREAM, 0);
if (_fd < 0) {
auto er = errno;
char msg[256];
LOG(Jetfix, Error,
"Failed to allocate socket when connecting to {}:{} errno:{} msg: {}",
_cfg.socket_connect_host_ip(), _cfg.socket_connect_port(), er,
std::string(strerror_r(er, msg, sizeof(msg))));
_fd = -1;
return false;
}
struct sockaddr_in serv_addr;
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(_cfg.socket_connect_port());
auto result = inet_pton(AF_INET, _cfg.socket_connect_host_ip().c_str(),
&serv_addr.sin_addr);
bts_assert(result > 0);
result = ::connect(_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
if (result < 0) {
LOG(Jetfix, Info, "Failed to connect to {}:{}",
_cfg.socket_connect_host_ip(), _cfg.socket_connect_port());
return false;
} else {
LOG(Jetfix, Info, "Connected to {}:{}", _cfg.socket_connect_host_ip(),
_cfg.socket_connect_port());
int flag = 1;
result = ::setsockopt(_fd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag,
sizeof(int));
bts_assert(result == 0);
return true;
}
}
void SocketConnection::shutdown() {
bts_assert(_fd >= 0);
::shutdown(_fd, SHUT_RDWR);
}
int SocketConnection::read(char *to_buffer, size_t read_count) {
bts_assert(_fd >= 0);
auto result = ::read(_fd, to_buffer, read_count);
if (_log && result > 0) {
_in_log.write(to_buffer, result);
_in_log.flush();
}
if (result < 0) {
auto er = errno;
char msg[256];
LOG(Jetfix, Warn, "Could not read from jetfix connection. {}",
std::string(strerror_r(er, msg, sizeof(msg))));
}
return result;
}
int SocketConnection::write(WriteVec const &vec, size_t vec_size,
trace::CorID trace) {
bts_assert(_fd >= 0);
struct iovec iv[MaxWriteVecSz];
for (size_t i = 0; i < vec_size; i++) {
iv[i].iov_base = (void *)vec[i].first;
iv[i].iov_len = vec[i].second;
}
_perf_log.log(trace,"before_fix_socket_w");
auto result = ::writev(_fd, iv, (int)vec_size);
_perf_log.log(trace,"after_fix_socket_w");
if (trace.sn)
_perf_log.flush();
if (_log && result > 0) {
for (size_t i = 0; i < vec_size; i++)
_out_log.write(vec[i].first, vec[i].second);
_out_log.flush();
}
if (result < 0) {
auto er = errno;
char msg[256];
LOG(Jetfix, Warn, "Could not write to jetfix connection. ",
std::string(strerror_r(er, msg, sizeof(msg))));
}
return result;
}
} // namespace jetfix
} // namespace bts