Give the server more time to send a heartbeat to make sure one missed heartbeat does not close the connection
This commit is contained in:
parent
3e5cbd0c5d
commit
a3c68009e7
|
|
@ -192,11 +192,12 @@ private:
|
||||||
ev_tstamp _expire;
|
ev_tstamp _expire;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interval between heartbeats (we should send every interval / 2 a new heartbeat)
|
* Timeout after which the connection is no longer considered alive.
|
||||||
|
* A heartbeat must be sent every _timeout / 2 seconds.
|
||||||
* Value zero means heartbeats are disabled, or not yet negotiated.
|
* Value zero means heartbeats are disabled, or not yet negotiated.
|
||||||
* @var uint16_t
|
* @var uint16_t
|
||||||
*/
|
*/
|
||||||
uint16_t _interval = 0;
|
uint16_t _timeout = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback method that is called by libev when the timer expires
|
* Callback method that is called by libev when the timer expires
|
||||||
|
|
@ -221,8 +222,8 @@ private:
|
||||||
// get the current time
|
// get the current time
|
||||||
ev_tstamp now = ev_now(_loop);
|
ev_tstamp now = ev_now(_loop);
|
||||||
|
|
||||||
// if the onNegotiate method was not yet called, and no heartbeat interval was negotiated
|
// if the onNegotiate method was not yet called, and no heartbeat timeout was negotiated
|
||||||
if (_interval == 0)
|
if (_timeout == 0)
|
||||||
{
|
{
|
||||||
// there is a theoretical scenario in which the onNegotiate() method
|
// there is a theoretical scenario in which the onNegotiate() method
|
||||||
// was overridden, so that the connection-timeout-timer expires, but
|
// was overridden, so that the connection-timeout-timer expires, but
|
||||||
|
|
@ -245,7 +246,7 @@ private:
|
||||||
_connection->heartbeat();
|
_connection->heartbeat();
|
||||||
|
|
||||||
// remember when we should send out the next one
|
// remember when we should send out the next one
|
||||||
_next += std::max(_interval / 2, 1);
|
_next += std::max(_timeout / 2, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset the timer to trigger again later
|
// reset the timer to trigger again later
|
||||||
|
|
@ -264,7 +265,9 @@ private:
|
||||||
virtual void onActive(int fd, int events) override
|
virtual void onActive(int fd, int events) override
|
||||||
{
|
{
|
||||||
// if the server is readable, we have some extra time before it expires
|
// if the server is readable, we have some extra time before it expires
|
||||||
if (_interval != 0 && (events & EV_READ)) _expire = ev_now(_loop) + _interval;
|
// the expire time is set to 1.5 * _timeout to close the connection when the
|
||||||
|
// third heartbeat is about to be sent
|
||||||
|
if (_timeout != 0 && (events & EV_READ)) _expire = ev_now(_loop) + _timeout * 1.5;
|
||||||
|
|
||||||
// pass on to the connection
|
// pass on to the connection
|
||||||
_connection->process(fd, events);
|
_connection->process(fd, events);
|
||||||
|
|
@ -283,7 +286,7 @@ private:
|
||||||
_loop(loop),
|
_loop(loop),
|
||||||
_next(0.0),
|
_next(0.0),
|
||||||
_expire(ev_now(loop) + timeout),
|
_expire(ev_now(loop) + timeout),
|
||||||
_interval(0)
|
_timeout(0)
|
||||||
{
|
{
|
||||||
// store the object in the data "void*"
|
// store the object in the data "void*"
|
||||||
_timer.data = this;
|
_timer.data = this;
|
||||||
|
|
@ -323,19 +326,19 @@ private:
|
||||||
* @param interval the heartbeat interval proposed by the server
|
* @param interval the heartbeat interval proposed by the server
|
||||||
* @return uint16_t the heartbeat interval that we accepted
|
* @return uint16_t the heartbeat interval that we accepted
|
||||||
*/
|
*/
|
||||||
uint16_t start(uint16_t interval)
|
uint16_t start(uint16_t timeout)
|
||||||
{
|
{
|
||||||
// we now know for sure that the connection was set up
|
// we now know for sure that the connection was set up
|
||||||
_interval = interval;
|
_timeout = timeout;
|
||||||
|
|
||||||
// if heartbeats are disabled we do not have to set it
|
// if heartbeats are disabled we do not have to set it
|
||||||
if (_interval == 0) return 0;
|
if (_timeout == 0) return 0;
|
||||||
|
|
||||||
// calculate current time
|
// calculate current time
|
||||||
auto now = ev_now(_loop);
|
auto now = ev_now(_loop);
|
||||||
|
|
||||||
// we also know when the next heartbeat should be sent
|
// we also know when the next heartbeat should be sent
|
||||||
_next = now + std::max(1, _interval / 2);
|
_next = now + std::max(_timeout / 2, 1);
|
||||||
|
|
||||||
// find the earliest thing that expires
|
// find the earliest thing that expires
|
||||||
// @todo does this work?
|
// @todo does this work?
|
||||||
|
|
@ -345,7 +348,7 @@ private:
|
||||||
ev_timer_again(_loop, &_timer);
|
ev_timer_again(_loop, &_timer);
|
||||||
|
|
||||||
// expose the accepted interval
|
// expose the accepted interval
|
||||||
return _interval;
|
return _timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue