Make retry more aggressive even absent new data (fixes #23 github issue)
This commit is contained in:
@@ -301,8 +301,8 @@ int OverlayManager::wait_time( void )
|
|||||||
next_expiry = 1000;
|
next_expiry = 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( predictions.active() && ( next_expiry > 10 ) ) {
|
if ( predictions.active() && ( next_expiry > 20 ) ) {
|
||||||
next_expiry = 10;
|
next_expiry = 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
return next_expiry;
|
return next_expiry;
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ void Transport<MyState, RemoteState>::recv( void )
|
|||||||
received_states.push_back( new_state );
|
received_states.push_back( new_state );
|
||||||
sender.set_ack_num( received_states.back().num );
|
sender.set_ack_num( received_states.back().num );
|
||||||
|
|
||||||
|
sender.remote_heard( new_state.timestamp );
|
||||||
if ( !inst.diff().empty() ) {
|
if ( !inst.diff().empty() ) {
|
||||||
sender.set_data_ack();
|
sender.set_data_ack();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,8 @@ TransportSender<MyState>::TransportSender( Connection *s_connection, MyState &in
|
|||||||
pending_data_ack( false ),
|
pending_data_ack( false ),
|
||||||
ack_timestamp( 0 ),
|
ack_timestamp( 0 ),
|
||||||
ack_history(),
|
ack_history(),
|
||||||
SEND_MINDELAY( 15 )
|
SEND_MINDELAY( 15 ),
|
||||||
|
last_heard( 0 )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,41 +64,57 @@ unsigned int TransportSender<MyState>::send_interval( void ) const
|
|||||||
return SEND_INTERVAL;
|
return SEND_INTERVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* How many ms can the caller wait before we will have an event (empty ack or next frame)? */
|
/* Housekeeping routine to calculate next send and ack times */
|
||||||
template <class MyState>
|
template <class MyState>
|
||||||
int TransportSender<MyState>::wait_time( void )
|
void TransportSender<MyState>::calculate_timers( void )
|
||||||
{
|
{
|
||||||
if ( pending_data_ack && (next_ack_time > timestamp() + ACK_DELAY) ) {
|
uint64_t now = timestamp();
|
||||||
next_ack_time = timestamp() + ACK_DELAY;
|
|
||||||
|
/* Update assumed receiver state */
|
||||||
|
update_assumed_receiver_state();
|
||||||
|
|
||||||
|
/* Cut out common prefix of all states */
|
||||||
|
rationalize_states();
|
||||||
|
|
||||||
|
if ( pending_data_ack && (next_ack_time > now + ACK_DELAY) ) {
|
||||||
|
next_ack_time = now + ACK_DELAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !(current_state == sent_states.back().state) ) { /* pending data to send */
|
if ( ( !(current_state == assumed_receiver_state->state)
|
||||||
if ( next_send_time > timestamp() + SEND_MINDELAY ) {
|
&& (last_heard + ACTIVE_RETRY_TIMEOUT > now) )
|
||||||
next_send_time = timestamp() + SEND_MINDELAY;
|
|| !(current_state == sent_states.back().state) ) { /* pending data to send */
|
||||||
|
if ( next_send_time > now + SEND_MINDELAY ) {
|
||||||
|
next_send_time = now + SEND_MINDELAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( next_send_time < sent_states.back().timestamp + send_interval() ) {
|
if ( next_send_time < sent_states.back().timestamp + send_interval() ) {
|
||||||
next_send_time = sent_states.back().timestamp + send_interval();
|
next_send_time = sent_states.back().timestamp + send_interval();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
next_send_time = uint64_t(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* speed up shutdown sequence */
|
/* speed up shutdown sequence */
|
||||||
if ( shutdown_in_progress || (ack_num == uint64_t(-1)) ) {
|
if ( shutdown_in_progress || (ack_num == uint64_t(-1)) ) {
|
||||||
next_ack_time = sent_states.back().timestamp + send_interval();
|
next_ack_time = sent_states.back().timestamp + send_interval();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t next_wakeup = next_ack_time;
|
/* How many ms to wait until next event */
|
||||||
|
template <class MyState>
|
||||||
|
int TransportSender<MyState>::wait_time( void )
|
||||||
|
{
|
||||||
|
calculate_timers();
|
||||||
|
|
||||||
if ( next_send_time < next_wakeup ) {
|
uint64_t next_wakeup = min( next_ack_time, next_send_time );
|
||||||
next_wakeup = next_send_time;
|
uint64_t now = timestamp();
|
||||||
}
|
|
||||||
|
|
||||||
if ( !connection->get_attached() ) {
|
if ( !connection->get_attached() ) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( next_wakeup > timestamp() ) {
|
if ( next_wakeup > now ) {
|
||||||
return next_wakeup - timestamp();
|
return next_wakeup - now;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -107,35 +124,33 @@ int TransportSender<MyState>::wait_time( void )
|
|||||||
template <class MyState>
|
template <class MyState>
|
||||||
void TransportSender<MyState>::tick( void )
|
void TransportSender<MyState>::tick( void )
|
||||||
{
|
{
|
||||||
wait_time();
|
calculate_timers(); /* updates assumed receiver state and rationalizes */
|
||||||
|
|
||||||
if ( !connection->get_attached() ) {
|
if ( !connection->get_attached() ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (timestamp() < next_ack_time)
|
uint64_t now = timestamp();
|
||||||
&& (timestamp() < next_send_time) ) {
|
|
||||||
|
if ( (now < next_ack_time)
|
||||||
|
&& (now < next_send_time) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine if a new diff or empty ack needs to be sent */
|
/* Determine if a new diff or empty ack needs to be sent */
|
||||||
/* Update assumed receiver state */
|
|
||||||
update_assumed_receiver_state();
|
|
||||||
|
|
||||||
/* Cut out common prefix of all states */
|
|
||||||
rationalize_states();
|
|
||||||
|
|
||||||
string diff = current_state.diff_from( assumed_receiver_state->state );
|
string diff = current_state.diff_from( assumed_receiver_state->state );
|
||||||
|
|
||||||
if ( diff.empty() && (timestamp() >= next_ack_time) ) {
|
if ( diff.empty() && (now >= next_ack_time) ) {
|
||||||
send_empty_ack();
|
send_empty_ack();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !diff.empty() && ( (timestamp() >= next_send_time)
|
if ( !diff.empty() && ( (now >= next_send_time)
|
||||||
|| (timestamp() >= next_ack_time) ) ) {
|
|| (now >= next_ack_time) ) ) {
|
||||||
/* Send diffs or ack */
|
/* Send diffs or ack */
|
||||||
send_to_receiver( diff );
|
send_to_receiver( diff );
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,6 +171,7 @@ void TransportSender<MyState>::send_empty_ack( void )
|
|||||||
send_in_fragments( "", new_num );
|
send_in_fragments( "", new_num );
|
||||||
|
|
||||||
next_ack_time = timestamp() + ACK_INTERVAL;
|
next_ack_time = timestamp() + ACK_INTERVAL;
|
||||||
|
next_send_time = uint64_t(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class MyState>
|
template <class MyState>
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ namespace Network {
|
|||||||
static const int ACK_DELAY = 100; /* ms before delayed ack */
|
static const int ACK_DELAY = 100; /* ms before delayed ack */
|
||||||
static const int SHUTDOWN_RETRIES = 3; /* number of shutdown packets to send before giving up */
|
static const int SHUTDOWN_RETRIES = 3; /* number of shutdown packets to send before giving up */
|
||||||
static const int ECHO_TIMEOUT = 50; /* for late ack */
|
static const int ECHO_TIMEOUT = 50; /* for late ack */
|
||||||
|
static const int ACTIVE_RETRY_TIMEOUT = 10000; /* attempt to resend at frame rate */
|
||||||
|
|
||||||
/* helper methods for tick() */
|
/* helper methods for tick() */
|
||||||
void update_assumed_receiver_state( void );
|
void update_assumed_receiver_state( void );
|
||||||
@@ -72,6 +73,8 @@ namespace Network {
|
|||||||
uint64_t next_ack_time;
|
uint64_t next_ack_time;
|
||||||
uint64_t next_send_time;
|
uint64_t next_send_time;
|
||||||
|
|
||||||
|
void calculate_timers( void );
|
||||||
|
|
||||||
bool verbose;
|
bool verbose;
|
||||||
bool shutdown_in_progress;
|
bool shutdown_in_progress;
|
||||||
int shutdown_tries;
|
int shutdown_tries;
|
||||||
@@ -86,6 +89,8 @@ namespace Network {
|
|||||||
|
|
||||||
unsigned int SEND_MINDELAY; /* ms to collect all input */
|
unsigned int SEND_MINDELAY; /* ms to collect all input */
|
||||||
|
|
||||||
|
uint64_t last_heard; /* last time received new state */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/* constructor */
|
/* constructor */
|
||||||
TransportSender( Connection *s_connection, MyState &initial_state );
|
TransportSender( Connection *s_connection, MyState &initial_state );
|
||||||
@@ -105,6 +110,9 @@ namespace Network {
|
|||||||
/* Accelerate reply ack */
|
/* Accelerate reply ack */
|
||||||
void set_data_ack( void ) { pending_data_ack = true; }
|
void set_data_ack( void ) { pending_data_ack = true; }
|
||||||
|
|
||||||
|
/* Received something */
|
||||||
|
void remote_heard( uint64_t ts ) { last_heard = ts; }
|
||||||
|
|
||||||
/* Starts shutdown sequence */
|
/* Starts shutdown sequence */
|
||||||
void start_shutdown( void ) { shutdown_in_progress = true; }
|
void start_shutdown( void ) { shutdown_in_progress = true; }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user