Warn when server has not heard from us (even if we have heard from server)

This commit is contained in:
Keith Winstein
2012-04-30 22:43:45 -04:00
parent e70254bad5
commit 2ea3f3a347
5 changed files with 29 additions and 4 deletions
+1
View File
@@ -201,6 +201,7 @@ bool STMClient::process_network_input( void )
/* Now give hints to the overlays */ /* Now give hints to the overlays */
overlays.get_notification_engine().server_heard( network->get_latest_remote_state().timestamp ); overlays.get_notification_engine().server_heard( network->get_latest_remote_state().timestamp );
overlays.get_notification_engine().server_acked( network->get_sent_state_acked_timestamp() );
overlays.get_prediction_engine().set_local_frame_acked( network->get_sent_state_acked() ); overlays.get_prediction_engine().set_local_frame_acked( network->get_sent_state_acked() );
overlays.get_prediction_engine().set_send_interval( network->send_interval() ); overlays.get_prediction_engine().set_send_interval( network->send_interval() );
+21 -3
View File
@@ -153,6 +153,7 @@ void ConditionalCursorMove::apply( Framebuffer &fb, uint64_t confirmed_epoch ) c
NotificationEngine::NotificationEngine() NotificationEngine::NotificationEngine()
: last_word_from_server( timestamp() ), : last_word_from_server( timestamp() ),
last_acked_state( timestamp() ),
message(), message(),
message_expiration( -1 ) message_expiration( -1 )
{} {}
@@ -188,15 +189,32 @@ void NotificationEngine::apply( Framebuffer &fb ) const
/* write message */ /* write message */
wchar_t tmp[ 128 ]; wchar_t tmp[ 128 ];
/* We want to prefer the "last contact" message if we simply haven't
heard from the server in a while, but print the "last reply" message
if the problem is uplink-only. */
double since_heard = (double)(now - last_word_from_server) / 1000.0;
double since_ack = (double)(now - last_acked_state) / 1000.0;
const char server_message[] = "contact";
const char reply_message[] = "reply";
double time_elapsed = since_heard;
const char *explanation = server_message;
if ( reply_late( now ) && (!server_late( now )) ) {
time_elapsed = since_ack;
explanation = reply_message;
}
if ( message.empty() && (!time_expired) ) { if ( message.empty() && (!time_expired) ) {
return; return;
} else if ( message.empty() && time_expired ) { } else if ( message.empty() && time_expired ) {
swprintf( tmp, 128, L"mosh: Last contact %.0f seconds ago. [To quit: Ctrl-^ .]", (double)(now - last_word_from_server) / 1000.0 ); swprintf( tmp, 128, L"mosh: Last %s %.0f seconds ago. [To quit: Ctrl-^ .]", explanation, time_elapsed );
} else if ( (!message.empty()) && (!time_expired) ) { } else if ( (!message.empty()) && (!time_expired) ) {
swprintf( tmp, 128, L"mosh: %ls [To quit: Ctrl-^ .]", message.c_str() ); swprintf( tmp, 128, L"mosh: %ls [To quit: Ctrl-^ .]", message.c_str() );
} else { } else {
swprintf( tmp, 128, L"mosh: %ls (%.0f s without contact.) [To quit: Ctrl-^ .]", message.c_str(), swprintf( tmp, 128, L"mosh: %ls (%.0f s without %s.) [To quit: Ctrl-^ .]", message.c_str(),
(double)(now - last_word_from_server) / 1000.0 ); time_elapsed, explanation );
} }
wstring string_to_draw( tmp ); wstring string_to_draw( tmp );
+5 -1
View File
@@ -127,16 +127,20 @@ namespace Overlay {
class NotificationEngine { class NotificationEngine {
private: private:
uint64_t last_word_from_server; uint64_t last_word_from_server;
uint64_t last_acked_state;
wstring message; wstring message;
uint64_t message_expiration; uint64_t message_expiration;
public: public:
bool need_countup( uint64_t ts ) const { return ts - last_word_from_server > 6500; } bool server_late( uint64_t ts ) const { return (ts - last_word_from_server) > 6500; }
bool reply_late( uint64_t ts ) const { return (ts - last_acked_state) > 10000; }
bool need_countup( uint64_t ts ) const { return server_late( ts ) || reply_late( ts ); }
void adjust_message( void ); void adjust_message( void );
void apply( Framebuffer &fb ) const; void apply( Framebuffer &fb ) const;
void set_notification_string( const wstring &s_message, bool permanent = false ) { message = s_message; if ( permanent ) { message_expiration = -1; } else { message_expiration = timestamp() + 1000; } } void set_notification_string( const wstring &s_message, bool permanent = false ) { message = s_message; if ( permanent ) { message_expiration = -1; } else { message_expiration = timestamp() + 1000; } }
const wstring &get_notification_string( void ) const { return message; } const wstring &get_notification_string( void ) const { return message; }
void server_heard( uint64_t s_last_word ) { last_word_from_server = s_last_word; } void server_heard( uint64_t s_last_word ) { last_word_from_server = s_last_word; }
void server_acked( uint64_t s_last_acked ) { last_acked_state = s_last_acked; }
uint64_t get_message_expiration( void ) const { return message_expiration; } uint64_t get_message_expiration( void ) const { return message_expiration; }
NotificationEngine(); NotificationEngine();
+1
View File
@@ -95,6 +95,7 @@ namespace Network {
void set_send_delay( int new_delay ) { sender.set_send_delay( new_delay ); } void set_send_delay( int new_delay ) { sender.set_send_delay( new_delay ); }
uint64_t get_sent_state_acked_timestamp( void ) const { return sender.get_sent_state_acked_timestamp(); }
uint64_t get_sent_state_acked( void ) const { return sender.get_sent_state_acked(); } uint64_t get_sent_state_acked( void ) const { return sender.get_sent_state_acked(); }
uint64_t get_sent_state_last( void ) const { return sender.get_sent_state_last(); } uint64_t get_sent_state_last( void ) const { return sender.get_sent_state_last(); }
+1
View File
@@ -126,6 +126,7 @@ namespace Network {
bool get_shutdown_in_progress( void ) const { return shutdown_in_progress; } bool get_shutdown_in_progress( void ) const { return shutdown_in_progress; }
bool get_shutdown_acknowledged( void ) const { return sent_states.front().num == uint64_t(-1); } bool get_shutdown_acknowledged( void ) const { return sent_states.front().num == uint64_t(-1); }
bool get_counterparty_shutdown_acknowledged( void ) const { return fragmenter.last_ack_sent() == uint64_t(-1); } bool get_counterparty_shutdown_acknowledged( void ) const { return fragmenter.last_ack_sent() == uint64_t(-1); }
uint64_t get_sent_state_acked_timestamp( void ) const { return sent_states.front().timestamp; }
uint64_t get_sent_state_acked( void ) const { return sent_states.front().num; } uint64_t get_sent_state_acked( void ) const { return sent_states.front().num; }
uint64_t get_sent_state_last( void ) const { return sent_states.back().num; } uint64_t get_sent_state_last( void ) const { return sent_states.back().num; }