better async exception handling

This commit is contained in:
badaix 2017-09-16 17:13:49 +02:00
parent 0ea51d95f3
commit 4670927d67
5 changed files with 30 additions and 18 deletions

View file

@ -22,7 +22,7 @@
#include "common/strCompat.h"
#include "common/snapException.h"
#include "message/hello.h"
#include "common/log.h"
#include "aixlog.hpp"
using namespace std;
@ -82,7 +82,7 @@ void ClientConnection::start()
// setsockopt(socket->native_handle(), SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
socket_->connect(*iterator);
connected_ = true;
SLOG(LOG_NOTICE) << "Connected to " << socket_->remote_endpoint().address().to_string() << endl;
SLOG(NOTICE) << "Connected to " << socket_->remote_endpoint().address().to_string() << endl;
active_ = true;
readerThread_ = new thread(&ClientConnection::reader, this);
}
@ -221,7 +221,7 @@ void ClientConnection::reader()
catch (const std::exception& e)
{
if (messageReceiver_ != NULL)
messageReceiver_->onException(this, e);
messageReceiver_->onException(this, make_shared<SnapException>(e.what()));
}
catch (...)
{

View file

@ -48,12 +48,16 @@ struct PendingRequest
};
/// would be nicer to use std::exception_ptr
/// but not supported on all plattforms
typedef std::shared_ptr<std::exception> shared_exception_ptr;
/// Interface: callback for a received message and error reporting
class MessageReceiver
{
public:
virtual void onMessageReceived(ClientConnection* connection, const msg::BaseMessage& baseMessage, char* buffer) = 0;
virtual void onException(ClientConnection* connection, const std::exception& exception) = 0;
virtual void onException(ClientConnection* connection, shared_exception_ptr exception) = 0;
};

View file

@ -29,7 +29,7 @@
#include "message/time.h"
#include "message/hello.h"
#include "common/snapException.h"
#include "common/log.h"
#include "aixlog.hpp"
using namespace std;
@ -43,16 +43,15 @@ Controller::Controller(const std::string& hostId, size_t instance) : MessageRece
decoder_(nullptr),
player_(nullptr),
serverSettings_(nullptr),
asyncException_(false)
async_exception_(nullptr)
{
}
void Controller::onException(ClientConnection* connection, const std::exception& exception)
void Controller::onException(ClientConnection* connection, shared_exception_ptr exception)
{
LOG(ERROR) << "Controller::onException: " << exception.what() << "\n";
exception_ = exception.what();
asyncException_ = true;
LOG(ERROR) << "Controller::onException: " << exception->what() << "\n";
async_exception_ = exception;
}
@ -196,6 +195,12 @@ void Controller::worker()
msg::Time timeReq;
for (size_t n=0; n<50 && active_; ++n)
{
if (async_exception_)
{
LOG(ERROR) << "Async exception: " << async_exception_->what() << "\n";
throw *async_exception_;
}
shared_ptr<msg::Time> reply = clientConnection_->sendReq<msg::Time>(&timeReq, chronos::msec(2000));
if (reply)
{
@ -208,11 +213,15 @@ void Controller::worker()
/// Main loop
while (active_)
{
LOG(DEBUG) << "Main loop\n";
for (size_t n=0; n<10 && active_; ++n)
{
chronos::sleep(100);
if (asyncException_)
throw AsyncSnapException(exception_);
if (async_exception_)
{
LOG(ERROR) << "Async exception: " << async_exception_->what() << "\n";
throw *async_exception_;
}
}
if (sendTimeSyncMessage(5000))
@ -221,8 +230,8 @@ void Controller::worker()
}
catch (const std::exception& e)
{
asyncException_ = false;
SLOG(LOG_ERR) << "Exception in Controller::worker(): " << e.what() << endl;
async_exception_ = nullptr;
SLOG(ERROR) << "Exception in Controller::worker(): " << e.what() << endl;
clientConnection_->stop();
player_.reset();
stream_.reset();

View file

@ -56,7 +56,7 @@ public:
/// Implementation of MessageReceiver.
/// Used for async exception reporting
virtual void onException(ClientConnection* connection, const std::exception& exception);
virtual void onException(ClientConnection* connection, shared_exception_ptr exception);
private:
void worker();
@ -76,8 +76,7 @@ private:
std::shared_ptr<msg::CodecHeader> headerChunk_;
std::mutex receiveMutex_;
std::string exception_;
bool asyncException_;
shared_exception_ptr async_exception_;
};

View file

@ -157,7 +157,7 @@ int main (int argc, char **argv)
AixLog::Log::init(
{
make_shared<AixLog::SinkCout>(debugSwitch.isSet()?(AixLog::Severity::trace):(AixLog::Severity::info), AixLog::Type::all, debugSwitch.isSet()?"%Y-%m-%d %H-%M-%S.#ms [#severity] (#tag)":"%Y-%m-%d %H-%M-%S [#severity]"),
make_shared<AixLog::SinkCout>(debugSwitch.isSet()?(AixLog::Severity::trace):(AixLog::Severity::info), AixLog::Type::all, debugSwitch.isSet()?"%Y-%m-%d %H-%M-%S.#ms [#severity] (#function)":"%Y-%m-%d %H-%M-%S [#severity]"),
make_shared<AixLog::SinkNative>("snapclient", AixLog::Severity::trace, AixLog::Type::special)
}
);