JayBeams  0.1
Another project to have fun coding.
moldheartbeat.cpp
Go to the documentation of this file.
2 #include <jb/as_hhmmss.hpp>
3 #include <jb/log.hpp>
4 
5 #include <boost/asio/io_service.hpp>
6 #include <boost/asio/ip/multicast.hpp>
7 #include <boost/asio/ip/udp.hpp>
8 
9 #include <chrono>
10 #include <iostream>
11 #include <stdexcept>
12 #include <thread>
13 
14 #include <net/if.h>
15 
16 namespace {
17 
18 class config : public jb::config_object {
19 public:
20  config();
22 
23  void validate() const override;
24 
29 };
30 
31 } // anonymous namespace
32 
33 int main(int argc, char* argv[]) try {
34  config cfg;
35  cfg.load_overrides(argc, argv, std::string("moldheartbeat.yaml"), "JB_ROOT");
36  jb::log::init(cfg.log());
37 
38  boost::asio::io_service io_service;
39  boost::asio::ip::udp::resolver resolver(io_service);
40  boost::asio::ip::udp::resolver::query query(cfg.destination(), cfg.port());
41 
42  boost::asio::ip::udp::endpoint endpoint;
43  auto i = resolver.resolve(query);
44  if (i == boost::asio::ip::udp::resolver::iterator()) {
45  JB_LOG(error) << "Cannot resolve destination address or port"
46  << ", address=" << cfg.destination()
47  << ", port=" << cfg.port();
48  throw std::runtime_error("cannot resolve destination address or port");
49  }
50  endpoint = *i;
51 
52  JB_LOG(info) << "Sending to endpoint=" << endpoint;
53  boost::asio::ip::udp::socket socket(io_service, endpoint.protocol());
54  socket.set_option(boost::asio::ip::multicast::enable_loopback(true));
55 
56  jb::itch5::mold_udp_pacer<> pacer(cfg.pacer());
57  auto sink = [&socket, &endpoint](auto buffers) {
58  socket.send_to(buffers, endpoint);
59  };
60  for (int i = 0; i != 10000; ++i) {
61  if (i % 100 == 0) {
62  JB_LOG(info) << "Sending hearbeat # " << i;
63  }
64  pacer.heartbeat(sink);
65  std::this_thread::sleep_for(std::chrono::seconds(1));
66  }
67 
68  return 0;
69 } catch (jb::usage const& u) {
70  std::cout << u.what() << std::endl;
71  return u.exit_status();
72 } catch (std::exception const& ex) {
73  std::cerr << "Standard exception raised: " << ex.what() << std::endl;
74  return 1;
75 } catch (...) {
76  std::cerr << "Unknown exception raised" << std::endl;
77  return 1;
78 }
79 
80 namespace {
81 
82 std::string default_udp_port() {
83  return "50000";
84 }
85 
86 std::string default_destination() {
87  return "::1";
88 }
89 
90 config::config()
91  : destination(
92  desc("destination")
93  .help("The destination for the UDP messages. "
94  "The destination can be a unicast or multicast address."),
95  this, default_destination())
96  , port(
97  desc("port").help("The destination port for the UDP messages. "),
98  this, default_udp_port())
99  , log(desc("log", "logging"), this)
100  , pacer(desc("pacer", "mold-udp-pacer"), this) {
101 }
102 
103 void config::validate() const {
104  log().validate();
105  pacer().validate();
106 }
107 
108 } // anonymous namespace
Base class for all configuration objects.
virtual void validate() const
Validate the settings.
Send a sequence of raw ITCH-5.x messages as MoldUDP64 packets, trying to match the original time inte...
int exit_status() const
Definition: usage.hpp:21
void init(config const &cfg)
Initialize the logging functions using the configuration provided.
Definition: log.cpp:190
#define config_object_constructors(NAME)
Helper class to easily define configuration attributes.
A simple class to communicate the result of parsing the options.
Definition: usage.hpp:11
static attribute_descriptor desc(std::string const &name)
Convenience function to create attribute descriptors with less typing.
int main(int argc, char *argv[])
#define JB_LOG(lvl)
Definition: log.hpp:70