LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
lqns_probe.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012-2026, QORE Lab, Imperial College London
3 * All rights reserved.
4 */
5#ifndef LINE_SOLVERS_WRAPPERS_LQNS_LQNS_PROBE_H
6#define LINE_SOLVERS_WRAPPERS_LQNS_LQNS_PROBE_H
7
8/**
9 * @file
10 * @ingroup line_solvers
11 * Is a usable lqns installed on this machine?
12 *
13 * Its own header, small enough for SolverAUTO to include: the layered arm of
14 * `chooseAvgSolverHeur` gates its LQNS candidate on `SolverLQNS.isAvailable()`,
15 * so the chooser needs the answer without taking on the wrapper, the .lqnx
16 * writer and the XML DOM behind it.
17 *
18 * THE ANSWER IS CACHED for the life of the process. A binary does not appear or
19 * vanish mid-run, and the probe is a fork and an exec: SolverAUTO would
20 * otherwise pay for one on every layered choice it makes.
21 */
22
23#include <cstdlib>
24#include <string>
25#include <vector>
26
28
29namespace line {
30namespace lqns {
31
32namespace detail {
33
34/** The first line of `lqns -V -H`, empty when there is no binary to ask. */
35inline std::string probe_version_banner() {
36 std::vector<std::string> argv;
37 argv.push_back("lqns");
38 argv.push_back("-V");
39 argv.push_back("-H");
40 const util::ProcResult r = util::capture(argv, 20);
41 if (r.exitCode < 0 || r.timedOut) return std::string();
42 const std::size_t nl = r.out.find('\n');
43 return util::trim(nl == std::string::npos ? r.out : r.out.substr(0, nl));
44}
45
46} // namespace detail
47
48/** The version banner of the local lqns, empty when there is none. */
49inline const std::string& lqns_version() {
50 static const std::string banner = detail::probe_version_banner();
51 return banner;
52}
53
54/** The major release number, 0 when no binary answered. */
55inline int lqns_major_version() {
56 const std::string& b = lqns_version();
57 const std::size_t at = b.find("Version ");
58 if (at == std::string::npos) return 0;
59 return std::atoi(b.c_str() + at + 8);
60}
61
62/**
63 * True when lqns is installed AND is a release this port speaks.
64 *
65 * LINE requires 6.0 or greater: the 5.x .lqxo grammar spells several result
66 * attributes differently, so an older binary would parse into a table of NaNs
67 * rather than fail, and the caller would read "not reported" as an answer.
68 */
69inline bool lqns_is_available() { return lqns_major_version() >= 6; }
70
71} // namespace lqns
72} // namespace line
73
74#endif // LINE_SOLVERS_WRAPPERS_LQNS_LQNS_PROBE_H
const std::string & lqns_version()
The version banner of the local lqns, empty when there is none.
Definition lqns_probe.h:49
int lqns_major_version()
The major release number, 0 when no binary answered.
Definition lqns_probe.h:55
bool lqns_is_available()
True when lqns is installed AND is a release this port speaks.
Definition lqns_probe.h:69
ProcResult capture(const std::vector< std::string > &argv, int timeoutSeconds, bool mergeStderr=false)
Runs a command, capturing stdout and discarding stderr.
Definition subprocess.h:82
std::string trim(const std::string &s)
Trims ASCII whitespace from both ends, as Java's String.trim() does.
Definition subprocess.h:181
Outcome of a captured command.
Definition subprocess.h:42
int exitCode
Exit status, or -1 when the command could not run.
Definition subprocess.h:43
bool timedOut
True when the deadline expired and the child was killed.
Definition subprocess.h:45
std::string out
Everything the command wrote to stdout.
Definition subprocess.h:44
Running an external command and capturing its output, with a deadline.