forked from Silverfish/proton-bridge
GODT-2038: interrupt gRPC initialisation of bridge process terminates.
This commit is contained in:
committed by
Romain LE JEUNE
parent
a949a113cf
commit
f5148074fd
@ -19,6 +19,7 @@
|
||||
#include "GRPCClient.h"
|
||||
#include "GRPCUtils.h"
|
||||
#include "../Exception/Exception.h"
|
||||
#include "../ProcessMonitor.h"
|
||||
|
||||
|
||||
using namespace google::protobuf;
|
||||
@ -56,9 +57,10 @@ void GRPCClient::removeServiceConfigFile()
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \param[in] timeoutMs The timeout in milliseconds
|
||||
/// \param[in] serverProcess An optional server process to monitor. If the process it, no need and retry, as connexion cannot be established. Ignored if null.
|
||||
/// \return The service config.
|
||||
//****************************************************************************************************************************************************
|
||||
GRPCConfig GRPCClient::waitAndRetrieveServiceConfig(qint64 timeoutMs)
|
||||
GRPCConfig GRPCClient::waitAndRetrieveServiceConfig(qint64 timeoutMs, ProcessMonitor *serverProcess)
|
||||
{
|
||||
QString const path = grpcServerConfigPath();
|
||||
QFile file(path);
|
||||
@ -68,6 +70,9 @@ GRPCConfig GRPCClient::waitAndRetrieveServiceConfig(qint64 timeoutMs)
|
||||
bool found = false;
|
||||
while (true)
|
||||
{
|
||||
if (serverProcess && serverProcess->getStatus().ended)
|
||||
throw Exception("Bridge application exited before providing a gRPC service configuration file.");
|
||||
|
||||
if (file.exists())
|
||||
{
|
||||
found = true;
|
||||
@ -100,9 +105,10 @@ void GRPCClient::setLog(Log *log)
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
/// \param[out] outError If the function returns false, this variable contains a description of the error.
|
||||
/// \param[in] serverProcess An optional server process to monitor. If the process it, no need and retry, as connexion cannot be established. Ignored if null.
|
||||
/// \return true iff the connection was successful.
|
||||
//****************************************************************************************************************************************************
|
||||
bool GRPCClient::connectToServer(GRPCConfig const &config, QString &outError)
|
||||
bool GRPCClient::connectToServer(GRPCConfig const &config, ProcessMonitor *serverProcess, QString &outError)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -123,6 +129,9 @@ bool GRPCClient::connectToServer(GRPCConfig const &config, QString &outError)
|
||||
int i = 0;
|
||||
while (true)
|
||||
{
|
||||
if (serverProcess && serverProcess->getStatus().ended)
|
||||
throw Exception("Bridge application ended before gRPC connexion could be established.");
|
||||
|
||||
this->logInfo(QString("Connection to gRPC server at %1. attempt #%2").arg(address).arg(++i));
|
||||
|
||||
if (channel_->WaitForConnected(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(grpcConnectionRetryDelayMs, GPR_TIMESPAN))))
|
||||
|
||||
@ -50,7 +50,7 @@ class GRPCClient : public QObject
|
||||
Q_OBJECT
|
||||
public: // static member functions
|
||||
static void removeServiceConfigFile(); ///< Delete the service config file.
|
||||
static GRPCConfig waitAndRetrieveServiceConfig(qint64 timeoutMs); ///< Wait and retrieve the service configuration.
|
||||
static GRPCConfig waitAndRetrieveServiceConfig(qint64 timeoutMs, class ProcessMonitor *serverProcess); ///< Wait and retrieve the service configuration.
|
||||
|
||||
public: // member functions.
|
||||
GRPCClient() = default; ///< Default constructor.
|
||||
@ -60,7 +60,7 @@ public: // member functions.
|
||||
GRPCClient &operator=(GRPCClient const &) = delete; ///< Disabled assignment operator.
|
||||
GRPCClient &operator=(GRPCClient &&) = delete; ///< Disabled move assignment operator.
|
||||
void setLog(Log *log); ///< Set the log for the client.
|
||||
bool connectToServer(GRPCConfig const &config, QString &outError); ///< Establish connection to the gRPC server.
|
||||
bool connectToServer(GRPCConfig const &config, class ProcessMonitor *serverProcess, QString &outError); ///< Establish connection to the gRPC server.
|
||||
|
||||
grpc::Status checkTokens(QString const &clientConfigPath, QString &outReturnedClientToken); ///< Performs a token check.
|
||||
grpc::Status addLogEntry(Log::Level level, QString const &package, QString const &message); ///< Performs the "AddLogEntry" gRPC call.
|
||||
|
||||
@ -33,6 +33,8 @@ ProcessMonitor::ProcessMonitor(QString const &exePath, QStringList const &args,
|
||||
: Worker(parent)
|
||||
, exePath_(exePath)
|
||||
, args_(args)
|
||||
, out_(stdout)
|
||||
, err_(stderr)
|
||||
{
|
||||
QFileInfo fileInfo(exePath);
|
||||
if (!fileInfo.exists())
|
||||
@ -42,6 +44,26 @@ ProcessMonitor::ProcessMonitor(QString const &exePath, QStringList const &args,
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
//
|
||||
//****************************************************************************************************************************************************
|
||||
void ProcessMonitor::forwardProcessOutput(QProcess &p) {
|
||||
QByteArray array = p.readAllStandardError();
|
||||
if (!array.isEmpty())
|
||||
{
|
||||
err_ << array;
|
||||
err_.flush();
|
||||
}
|
||||
|
||||
array = p.readAllStandardOutput();
|
||||
if (!array.isEmpty())
|
||||
{
|
||||
out_ << array;
|
||||
out_.flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//****************************************************************************************************************************************************
|
||||
//
|
||||
//****************************************************************************************************************************************************
|
||||
@ -49,35 +71,31 @@ void ProcessMonitor::run()
|
||||
{
|
||||
try
|
||||
{
|
||||
{
|
||||
QMutexLocker locker(&statusMutex_);
|
||||
status_.ended = false;
|
||||
status_.pid = -1;
|
||||
}
|
||||
|
||||
emit started();
|
||||
|
||||
QProcess p;
|
||||
p.start(exePath_, args_);
|
||||
p.waitForStarted();
|
||||
|
||||
status_.running = true;
|
||||
status_.pid = p.processId();
|
||||
|
||||
QTextStream out(stdout), err(stderr);
|
||||
QByteArray array;
|
||||
while (!p.waitForFinished(100))
|
||||
{
|
||||
array = p.readAllStandardError();
|
||||
if (!array.isEmpty())
|
||||
{
|
||||
err << array;
|
||||
err.flush();
|
||||
}
|
||||
|
||||
array = p.readAllStandardOutput();
|
||||
if (!array.isEmpty())
|
||||
{
|
||||
out << array;
|
||||
out.flush();
|
||||
}
|
||||
QMutexLocker locker(&statusMutex_);
|
||||
status_.pid = p.processId();
|
||||
}
|
||||
|
||||
status_.running = false;
|
||||
while (!p.waitForFinished(100))
|
||||
{
|
||||
this->forwardProcessOutput(p);
|
||||
}
|
||||
this->forwardProcessOutput(p);
|
||||
|
||||
QMutexLocker locker(&statusMutex_);
|
||||
status_.ended = true;
|
||||
status_.returnCode = p.exitCode();
|
||||
|
||||
emit processExited(status_.returnCode);
|
||||
@ -93,8 +111,9 @@ void ProcessMonitor::run()
|
||||
//****************************************************************************************************************************************************
|
||||
/// \return status of the monitored process
|
||||
//****************************************************************************************************************************************************
|
||||
const ProcessMonitor::MonitorStatus &ProcessMonitor::getStatus()
|
||||
const ProcessMonitor::MonitorStatus ProcessMonitor::getStatus()
|
||||
{
|
||||
QMutexLocker locker(&statusMutex_);
|
||||
return status_;
|
||||
}
|
||||
|
||||
|
||||
@ -36,7 +36,7 @@ Q_OBJECT
|
||||
public: // static member functions
|
||||
struct MonitorStatus
|
||||
{
|
||||
bool running = false;
|
||||
bool ended = false;
|
||||
int returnCode = 0;
|
||||
qint64 pid = 0;
|
||||
};
|
||||
@ -49,15 +49,21 @@ public: // member functions.
|
||||
ProcessMonitor &operator=(ProcessMonitor const &) = delete; ///< Disabled assignment operator.
|
||||
ProcessMonitor &operator=(ProcessMonitor &&) = delete; ///< Disabled move assignment operator.
|
||||
void run() override; ///< Run the worker.
|
||||
MonitorStatus const &getStatus();
|
||||
MonitorStatus const getStatus(); ///< Retrieve the current status of the process.
|
||||
|
||||
signals:
|
||||
void processExited(int code); ///< Slot for the exiting of the process.
|
||||
|
||||
private: // member functions
|
||||
void forwardProcessOutput(QProcess &p); ///< Forward the standard output and error from the process to this application standard output and error.
|
||||
|
||||
private: // data members
|
||||
QMutex statusMutex_; ///< The status mutex.
|
||||
QString const exePath_; ///< The path to the executable.
|
||||
QStringList args_; ///< arguments to be passed to the brigde.
|
||||
MonitorStatus status_; ///< Status of the monitoring.
|
||||
QTextStream out_; ///< The standard output stream.
|
||||
QTextStream err_; ///< The standard error stream.
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user