SRS-control 0.1.4
 
Loading...
Searching...
No Matches
Application.cpp
Go to the documentation of this file.
1#include <string_view>
2
3#include <fmt/ranges.h>
4#include <spdlog/spdlog.h>
5
6#include <srs/Application.hpp>
9
10namespace srs
11{
13 : io_work_guard_{ asio::make_work_guard(io_context_) }
14 {
15 spdlog::set_pattern("[%H:%M:%S] [%^%=7l%$] [thread %t] %v");
16 spdlog::info("Welcome to SRS Application");
17 workflow_handler_ = std::make_unique<workflow::Handler>(this);
18 }
19
20 AppExitHelper::~AppExitHelper() noexcept { app_->end_of_work(); }
21
23 {
24 spdlog::trace("Application: Resetting io context workguard ... ");
25 io_work_guard_.reset();
26 if (not status_.is_acq_off.load())
27 {
28 spdlog::critical(
29 "Failed to close srs system! Please manually close the system with\n\nsrs_control --acq-off\n");
30 }
31 // TODO: set a timer
32 //
33 if (working_thread_.joinable())
34 {
35 spdlog::debug("Application: Wait until working thread finishes ...");
36 // io_context_.stop();
37 working_thread_.join();
38 spdlog::debug("io context is stoped");
39 }
40 spdlog::debug("Application: working thread is finished");
41 spdlog::debug("Application has exited.");
42 }
43
44 App::~App() noexcept
45 {
46 spdlog::debug("Calling the destructor of App ... ");
47 signal_set_.cancel();
48
49 // Turn off SRS data acquisition
51
52 if (status_.is_acq_on.load())
53 {
54 spdlog::debug("Turning srs system off ...");
55 switch_off();
56 }
57 else
58 {
60 }
61 set_status_acq_on(false);
62 }
63
64 void App::init()
65 {
66 signal_set_.async_wait(
67 [this](const boost::system::error_code& error, auto)
68 {
69 if (error == asio::error::operation_aborted)
70 {
71 return;
72 }
73 exit();
74 spdlog::info("calling SIGINT from monitoring thread");
75 });
76 auto monitoring_action = [this]()
77 {
78 try
79 {
80 io_context_.join();
81 }
82 catch (const std::exception& ex)
83 {
84 spdlog::critical("Exception on working thread occured: {}", ex.what());
85 }
86 };
87 working_thread_ = std::jthread{ monitoring_action };
88 }
89
91 {
92
93 auto res = status_.wait_for_status(
94 [](const auto& status)
95 {
96 spdlog::debug("Waiting for reading status false");
97 return not status.is_reading.load();
98 });
99
100 if (not res)
101 {
102 spdlog::critical("TIMEOUT during waiting for status is_reading false.");
103 }
104 }
105
106 // This will be called by Ctrl-C interrupt
108 {
109 spdlog::debug("App::exit is called");
110 status_.is_on_exit.store(true);
112 workflow_handler_->stop();
113 }
114
115 void App::set_print_mode(common::DataPrintMode mode) { workflow_handler_->set_print_mode(mode); }
116 void App::set_output_filenames(const std::vector<std::string>& filenames)
117 {
118 workflow_handler_->set_output_filenames(filenames);
119 }
120
121 void App::set_remote_endpoint(std::string_view remote_ip, int port_number)
122 {
123 auto resolver = udp::resolver{ io_context_ };
124 spdlog::debug("Set the remote socket with ip: {} and port: {}", remote_ip, port_number);
125 auto udp_endpoints = resolver.resolve(udp::v4(), remote_ip, fmt::format("{}", port_number));
126 remote_endpoint_ = *udp_endpoints.begin();
127 }
128
130 {
131 auto connection_info = connection::Info{ this };
132 connection_info.local_port_number = configurations_.fec_control_local_port;
133 auto connection = std::make_shared<connection::Starter>(connection_info);
134 connection->set_remote_endpoint(remote_endpoint_);
135 connection->acq_on();
136 }
137
139 {
140 auto connection_info = connection::Info{ this };
141 connection_info.local_port_number = configurations_.fec_control_local_port;
142 auto connection = std::make_shared<connection::Stopper>(connection_info);
143 connection->set_remote_endpoint(remote_endpoint_);
144 connection->acq_off();
145 }
146
147 void App::read_data(bool is_non_stop)
148 {
149 auto connection_info = connection::Info{ this };
150 connection_info.local_port_number = configurations_.fec_data_receive_port;
151 data_reader_ = std::make_shared<connection::DataReader>(connection_info, workflow_handler_.get());
152 data_reader_->start(is_non_stop);
153 }
154
155 void App::start_workflow(bool is_blocking) { workflow_handler_->start(is_blocking); }
157} // namespace srs
~AppExitHelper() noexcept
~App() noexcept
asio::executor_work_guard< io_context_type::executor_type > io_work_guard_
void init()
void wait_for_finish()
void read_data(bool is_non_stop=true)
void set_remote_endpoint(std::string_view remote_ip, int port_number)
Config configurations_
void exit()
void set_status_acq_on(bool val=true)
std::shared_ptr< connection::DataReader > data_reader_
void end_of_work()
Status status_
asio::signal_set signal_set_
std::jthread working_thread_
void set_print_mode(common::DataPrintMode mode)
void switch_off()
void set_output_filenames(const std::vector< std::string > &filenames)
std::unique_ptr< workflow::Handler > workflow_handler_
void start_workflow(bool is_blocking=true)
udp::endpoint remote_endpoint_
io_context_type io_context_
void switch_on()
void wait_for_reading_finish()
void set_status_acq_off(bool val=true)