10 #ifndef DAQ_ASYNC_PROCESS_HPP
11 #define DAQ_ASYNC_PROCESS_HPP
19 #include <boost/circular_buffer.hpp>
20 #include <boost/process.hpp>
21 #include <boost/signals2/signal.hpp>
22 #include <boost/thread/future.hpp>
23 #include <log4cplus/logger.h>
39 [[nodiscard]]
virtual boost::future<int>
Initiate() = 0;
46 virtual std::optional<pid_t>
GetPid() const noexcept = 0;
55 virtual std::error_code
Abort() noexcept = 0;
65 virtual std::error_code
Signal(
int sig) noexcept = 0;
70 virtual std::vector<std::
string> const&
GetArguments() const noexcept = 0;
85 using
SigOutStream = boost::signals2::signal<
void(pid_t, std::
string const&)>;
113 std::ostream& operator<<(std::ostream& os,
AsyncProcessIf const& proc);
146 explicit AsyncProcess(boost::asio::io_context& ctx, std::vector<std::string> args);
159 [[nodiscard]] boost::future<int>
Initiate()
override;
160 std::optional<pid_t>
GetPid()
const noexcept
override;
169 std::error_code
Abort() noexcept
override;
179 std::error_code
Signal(
int sig) noexcept
override;
185 bool IsRunning()
const noexcept
override;
187 std::vector<std::string>
const&
GetArguments() const noexcept
override {
196 boost::signals2::connection
ConnectStdout(SigOutStream::slot_type
const& slot)
override {
197 return m_stdout.signal.connect(slot);
199 boost::signals2::connection
ConnectStderr(SigOutStream::slot_type
const& slot)
override {
200 return m_stderr.signal.connect(slot);
220 boost::process::async_pipe pipe;
221 boost::asio::streambuf buffer = boost::asio::streambuf();
237 void CheckCompleted();
240 void AsyncReadStream(Pipe&);
242 boost::asio::io_context& m_io_ctx;
243 std::vector<std::string> m_args;
251 boost::process::child m_proc;
253 std::optional<Result> m_result;
254 boost::promise<int> m_promise;
263 void operator()(pid_t pid, std::string
const& line) noexcept;
265 auto Lines() const -> boost::circular_buffer<std::
string> {
271 log4cplus::Logger m_logger;
272 boost::circular_buffer<std::string> m_buffer;
275 std::ostream&
operator<<(std::ostream& os, LogCaptureLast
const& lines);
Interface to asynchronous process.
virtual boost::future< int > Initiate()=0
Initiates async operation by executing the specified process.
virtual std::error_code Abort() noexcept=0
Aborts the operation by terminating process which completes the operation.
virtual std::vector< std::string > const & GetArguments() const noexcept=0
virtual boost::signals2::connection ConnectStdout(SigOutStream::slot_type const &slot)=0
Connect slot to line-buffered stdout signal.
virtual ~AsyncProcessIf()
boost::signals2::signal< void(pid_t, std::string const &)> SigOutStream
Signal type for stdout/stderr signals.
virtual std::error_code Signal(int sig) noexcept=0
Send signal to process.
virtual boost::signals2::connection ConnectStderr(SigOutStream::slot_type const &slot)=0
Connect slot to line-buffered stderr signal.
virtual bool IsRunning() const noexcept=0
virtual std::optional< pid_t > GetPid() const noexcept=0
Get PID.
Represents a subprocess as an asynchronous operation.
boost::signals2::connection ConnectStdout(SigOutStream::slot_type const &slot) override
Signal type for stdout/stderr signals.
std::vector< std::string > const & GetArguments() const noexcept override
boost::signals2::connection ConnectStderr(SigOutStream::slot_type const &slot) override
Signal type for stdout/stderr signals.
Logs output to logger and keeps last N lines in circular buffer for later retrival.
auto Lines() const -> boost::circular_buffer< std::string >
std::ostream & operator<<(std::ostream &os, AsyncProcessIf const &proc)
Formats proc representation in the form [<pid>] <args>
Utility class that represents a result and an error.