Standarize behavior of pinger cancel

This commit is contained in:
michal.szwaj 2018-04-05 23:33:38 +02:00 committed by Huan Truong
parent b50e1d658e
commit a8d8a83e12
5 changed files with 46 additions and 27 deletions

View File

@ -33,7 +33,7 @@ class IPinger
{ {
public: public:
typedef std::shared_ptr<IPinger> Pointer; typedef std::shared_ptr<IPinger> Pointer;
typedef aasdk::io::Promise<void, void> Promise; typedef aasdk::io::Promise<void> Promise;
virtual ~IPinger() = default; virtual ~IPinger() = default;
virtual void ping(Promise::Pointer promise) = 0; virtual void ping(Promise::Pointer promise) = 0;

View File

@ -46,6 +46,7 @@ private:
boost::asio::io_service::strand strand_; boost::asio::io_service::strand strand_;
boost::asio::deadline_timer timer_; boost::asio::deadline_timer timer_;
time_t duration_; time_t duration_;
bool cancelled_;
Promise::Pointer promise_; Promise::Pointer promise_;
int64_t pingsCount_; int64_t pingsCount_;
int64_t pongsCount_; int64_t pongsCount_;

View File

@ -174,8 +174,8 @@ void App::onUSBHubError(const aasdk::error::Error& error)
{ {
OPENAUTO_LOG(error) << "[App] usb hub error: " << error.what(); OPENAUTO_LOG(error) << "[App] usb hub error: " << error.what();
if(error.getCode() != aasdk::error::ErrorCode::OPERATION_ABORTED && if(error != aasdk::error::ErrorCode::OPERATION_ABORTED &&
error.getCode() != aasdk::error::ErrorCode::OPERATION_IN_PROGRESS) error != aasdk::error::ErrorCode::OPERATION_IN_PROGRESS)
{ {
this->waitForDevice(); this->waitForDevice();
} }

View File

@ -60,17 +60,18 @@ void AndroidAutoEntity::start(IAndroidAutoEntityEventHandler& eventHandler)
{ {
strand_.dispatch([this, self = this->shared_from_this(), eventHandler = &eventHandler]() { strand_.dispatch([this, self = this->shared_from_this(), eventHandler = &eventHandler]() {
OPENAUTO_LOG(info) << "[AndroidAutoEntity] start."; OPENAUTO_LOG(info) << "[AndroidAutoEntity] start.";
eventHandler_ = eventHandler;
cryptor_->init(); cryptor_->init();
serviceList_ = serviceFactory_.create(messenger_); serviceList_ = serviceFactory_.create(messenger_);
std::for_each(serviceList_.begin(), serviceList_.end(), std::bind(&IService::start, std::placeholders::_1)); std::for_each(serviceList_.begin(), serviceList_.end(), std::bind(&IService::start, std::placeholders::_1));
this->ping();
controlServiceChannel_->receive(this->shared_from_this());
auto versionRequestPromise = aasdk::channel::SendPromise::defer(strand_); auto versionRequestPromise = aasdk::channel::SendPromise::defer(strand_);
versionRequestPromise->then([]() {}, std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1)); versionRequestPromise->then([]() {}, std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1));
controlServiceChannel_->sendVersionRequest(std::move(versionRequestPromise)); controlServiceChannel_->sendVersionRequest(std::move(versionRequestPromise));
eventHandler_ = eventHandler;
controlServiceChannel_->receive(this->shared_from_this());
}); });
} }
@ -79,12 +80,12 @@ void AndroidAutoEntity::stop()
strand_.dispatch([this, self = this->shared_from_this()]() { strand_.dispatch([this, self = this->shared_from_this()]() {
OPENAUTO_LOG(info) << "[AndroidAutoEntity] stop."; OPENAUTO_LOG(info) << "[AndroidAutoEntity] stop.";
eventHandler_ = nullptr;
pinger_->cancel(); pinger_->cancel();
std::for_each(serviceList_.begin(), serviceList_.end(), std::bind(&IService::stop, std::placeholders::_1)); std::for_each(serviceList_.begin(), serviceList_.end(), std::bind(&IService::stop, std::placeholders::_1));
messenger_->stop(); messenger_->stop();
cryptor_->deinit(); cryptor_->deinit();
transport_->stop(); transport_->stop();
eventHandler_ = nullptr;
}); });
} }
@ -145,7 +146,6 @@ void AndroidAutoEntity::onHandshake(const aasdk::common::DataConstBuffer& payloa
auto authCompletePromise = aasdk::channel::SendPromise::defer(strand_); auto authCompletePromise = aasdk::channel::SendPromise::defer(strand_);
authCompletePromise->then([]() {}, std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1)); authCompletePromise->then([]() {}, std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1));
controlServiceChannel_->sendAuthComplete(authCompleteIndication, std::move(authCompletePromise)); controlServiceChannel_->sendAuthComplete(authCompleteIndication, std::move(authCompletePromise));
this->ping();
} }
controlServiceChannel_->receive(this->shared_from_this()); controlServiceChannel_->receive(this->shared_from_this());
@ -212,7 +212,6 @@ void AndroidAutoEntity::onShutdownRequest(const aasdk::proto::messages::Shutdown
std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1)); std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1));
controlServiceChannel_->sendShutdownResponse(response, std::move(promise)); controlServiceChannel_->sendShutdownResponse(response, std::move(promise));
controlServiceChannel_->receive(this->shared_from_this());
} }
void AndroidAutoEntity::onShutdownResponse(const aasdk::proto::messages::ShutdownResponse&) void AndroidAutoEntity::onShutdownResponse(const aasdk::proto::messages::ShutdownResponse&)
@ -265,9 +264,13 @@ void AndroidAutoEntity::ping()
controlServiceChannel_->sendPingRequest(request, std::move(promise)); controlServiceChannel_->sendPingRequest(request, std::move(promise));
this->ping(); this->ping();
}, },
[this, self = this->shared_from_this()]() { [this, self = this->shared_from_this()](auto error) {
if(error != aasdk::error::ErrorCode::OPERATION_ABORTED &&
error != aasdk::error::ErrorCode::OPERATION_IN_PROGRESS)
{
OPENAUTO_LOG(error) << "[AndroidAutoEntity] ping timer exceeded."; OPENAUTO_LOG(error) << "[AndroidAutoEntity] ping timer exceeded.";
this->triggerQuit(); this->triggerQuit();
}
}); });
pinger_->ping(std::move(promise)); pinger_->ping(std::move(promise));

View File

@ -31,6 +31,7 @@ Pinger::Pinger(boost::asio::io_service& ioService, time_t duration)
: strand_(ioService) : strand_(ioService)
, timer_(ioService) , timer_(ioService)
, duration_(duration) , duration_(duration)
, cancelled_(false)
, pingsCount_(0) , pingsCount_(0)
, pongsCount_(0) , pongsCount_(0)
{ {
@ -40,11 +41,20 @@ Pinger::Pinger(boost::asio::io_service& ioService, time_t duration)
void Pinger::ping(Promise::Pointer promise) void Pinger::ping(Promise::Pointer promise)
{ {
strand_.dispatch([this, self = this->shared_from_this(), promise = std::move(promise)]() mutable { strand_.dispatch([this, self = this->shared_from_this(), promise = std::move(promise)]() mutable {
cancelled_ = false;
if(promise_ != nullptr)
{
promise_->reject(aasdk::error::Error(aasdk::error::ErrorCode::OPERATION_IN_PROGRESS));
}
else
{
++pingsCount_; ++pingsCount_;
promise_ = std::move(promise); promise_ = std::move(promise);
timer_.expires_from_now(boost::posix_time::milliseconds(duration_)); timer_.expires_from_now(boost::posix_time::milliseconds(duration_));
timer_.async_wait(strand_.wrap(std::bind(&Pinger::onTimerExceeded, this->shared_from_this(), std::placeholders::_1))); timer_.async_wait(strand_.wrap(std::bind(&Pinger::onTimerExceeded, this->shared_from_this(), std::placeholders::_1)));
}
}); });
} }
@ -57,11 +67,17 @@ void Pinger::pong()
void Pinger::onTimerExceeded(const boost::system::error_code& error) void Pinger::onTimerExceeded(const boost::system::error_code& error)
{ {
if(!error && promise_ != nullptr) if(promise_ == nullptr)
{ {
if(std::abs(pingsCount_ - pongsCount_) > 1) return;
}
else if(error == boost::asio::error::operation_aborted || cancelled_)
{ {
promise_->reject(); promise_->reject(aasdk::error::Error(aasdk::error::ErrorCode::OPERATION_ABORTED));
}
else if(pingsCount_ - pongsCount_ > 1)
{
promise_->reject(aasdk::error::Error());
} }
else else
{ {
@ -70,12 +86,11 @@ void Pinger::onTimerExceeded(const boost::system::error_code& error)
promise_.reset(); promise_.reset();
} }
}
void Pinger::cancel() void Pinger::cancel()
{ {
strand_.dispatch([this, self = this->shared_from_this()]() { strand_.dispatch([this, self = this->shared_from_this()]() {
promise_.reset(); cancelled_ = true;
timer_.cancel(); timer_.cancel();
}); });
} }