ReCodEx - Task Broker
ReCodEx is complex programmer testing solution, primary targeted to technical universities. It's highly customizable and based on modern technologies.
broker_core.cpp
1 #include "broker_core.h"
2 
3 broker_core::broker_core(std::vector<std::string> args)
4  : args_(args), config_filename_("config.yml"), logger_(nullptr), broker_(nullptr)
5 {
6  // parse cmd parameters
7  parse_params();
8  // load configuration from yaml file
9  load_config();
10  // initialize logger
11  log_init();
12  // initialize curl
13  curl_init();
14  // construct and setup broker connection
15  broker_init();
16 }
17 
19 {
20  // curl finalize
21  curl_fini();
22 }
23 
25 {
26  logger_->info() << "Broker will now start brokering.";
27  broker_->start_brokering();
28  logger_->info() << "Broker will now end.";
29 }
30 
31 void broker_core::parse_params()
32 {
33  using namespace boost::program_options;
34 
35  // Declare the supported options.
36  options_description desc("Allowed options for broker");
37  desc.add_options()("help,h", "Writes this help message to stderr")(
38  "config,c", value<std::string>(), "Set default configuration of this program");
39 
40  variables_map vm;
41  try {
42  store(command_line_parser(args_).options(desc).run(), vm);
43  notify(vm);
44  } catch (std::exception &e) {
45  force_exit("Error in loading a parameter: " + std::string(e.what()));
46  }
47 
48 
49  // Evaluate all information from command line
50  if (vm.count("help")) {
51  std::cerr << desc << std::endl;
52  force_exit();
53  }
54 
55  if (vm.count("config")) {
56  config_filename_ = vm["config"].as<std::string>();
57  }
58 }
59 
60 void broker_core::load_config()
61 {
62  try {
63  YAML::Node config_yaml = YAML::LoadFile(config_filename_);
64  config_ = std::make_shared<broker_config>(config_yaml);
65  } catch (std::exception &e) {
66  force_exit("Error loading config file: " + std::string(e.what()));
67  }
68 }
69 
70 void broker_core::force_exit(std::string msg)
71 {
72  // write to log
73  if (msg != "") {
74  if (logger_ != nullptr) {
75  logger_->emerg() << msg;
76  }
77  std::cerr << msg << std::endl;
78  }
79 
80  exit(1);
81 }
82 
83 void broker_core::log_init()
84 {
85  auto log_conf = config_->get_log_config();
86 
87  // Set up logger
88  // Try to create target directory for logs
89  auto path = fs::path(log_conf.log_path);
90  try {
91  if (!fs::is_directory(path)) {
92  fs::create_directories(path);
93  }
94  } catch (fs::filesystem_error &e) {
95  std::cerr << "Logger: " << e.what() << std::endl;
96  throw;
97  }
98 
99  // Create and register logger
100  try {
101  // Create multithreaded rotating file sink. Max filesize is 1024 * 1024 and we save 5 newest files.
102  auto rotating_sink =
103  std::make_shared<spdlog::sinks::rotating_file_sink_mt>((path / log_conf.log_basename).string(),
104  log_conf.log_suffix,
105  log_conf.log_file_size,
106  log_conf.log_files_count,
107  true);
108  // Set queue size for asynchronous logging. It must be a power of 2.
109  spdlog::set_async_mode(1048576);
110  // Make log with name "logger"
111  logger_ = std::make_shared<spdlog::logger>("logger", rotating_sink);
112  // Set logging level to debug
113  logger_->set_level(helpers::get_log_level(log_conf.log_level));
114  // Print header to log
115  if (helpers::compare_log_levels(spdlog::level::notice, logger_->level()) > 0) {
116  logger_->emerg() << "--- Started ReCodEx broker ---";
117  } else {
118  logger_->notice() << "------------------------------";
119  logger_->notice() << " Started ReCodEx broker";
120  logger_->notice() << "------------------------------";
121  }
122  } catch (spdlog::spdlog_ex &e) {
123  std::cerr << "Logger: " << e.what() << std::endl;
124  throw;
125  }
126 }
127 
128 void broker_core::broker_init()
129 {
130  logger_->info() << "Initializing broker connection...";
131  workers_ = std::make_shared<worker_registry>();
132  context_ = std::make_shared<zmq::context_t>(1);
133  broker_ = std::make_shared<broker_connect>(config_, context_, workers_, logger_);
134  logger_->info() << "Broker connection initialized.";
135 }
136 
137 void broker_core::curl_init()
138 {
139  // Globally init curl library
140 
141  logger_->info() << "Initializing CURL...";
142  curl_global_init(CURL_GLOBAL_DEFAULT);
143  logger_->info() << "CURL initialized.";
144 }
145 
146 void broker_core::curl_fini()
147 {
148  // Clean after curl library
149  logger_->info() << "Cleanup after CURL...";
150  curl_global_cleanup();
151  logger_->info() << "CURL cleaned.";
152 }
broker_core()=delete