From b46586d7a9947dc9fb0d15388c4388a224399628 Mon Sep 17 00:00:00 2001 From: Charlie Fenton Date: Sat, 8 Aug 2009 03:32:05 +0000 Subject: [PATCH] MGR: Test changes to avoid non-stop RPC Wait dialog when client is heavily loaded svn path=/trunk/boinc/; revision=18822 --- checkin_notes | 17 +++++++++ clientgui/AsyncRPC.cpp | 2 + clientgui/MainDocument.cpp | 77 ++++++++++++++++++++++++++++++++------ clientgui/MainDocument.h | 1 + 4 files changed, 85 insertions(+), 12 deletions(-) diff --git a/checkin_notes b/checkin_notes index 8029344171..c8bf1bc85a 100644 --- a/checkin_notes +++ b/checkin_notes @@ -6805,3 +6805,20 @@ Charlie 7 Aug 2009 clientgui/ mac/ SetupSecurity.cpp + +Charlie 7 Aug 2009 + - MGR: Test two changes which might avoid a problem when the client + is heavily loaded (e.g, very many tasks), where the RPC Wait + dialog may appear continuously: + (1) Delay periodic RPCs for 1 second after the dialog closes. + (2) In functions to retrieve cached RPC data, don't do a demand + RPC just because the time since th last such RPC exceeds the + normal periodic RPC rates. We still force the RPC if the + this RPC has never been called since the Manager was launched + or if (for some RPCs) called with the bForce argument TRUE. + This change #2 can be removed by setting USE_CACHE_TIMEOUTS + to 0. + + clientgui/ + AsyncRPC.cpp + MainDocument.cpp, .h diff --git a/clientgui/AsyncRPC.cpp b/clientgui/AsyncRPC.cpp index e7b1a927db..c7fa52e90d 100755 --- a/clientgui/AsyncRPC.cpp +++ b/clientgui/AsyncRPC.cpp @@ -804,6 +804,8 @@ int CMainDocument::RequestRPC(ASYNC_RPC_REQUEST& request, bool hasPriority) { // if (m_RPCWaitDlg) { response = m_RPCWaitDlg->ShowModal(); + // Remember time the dialog was closed for use by RunPeriodicRPCs() + m_dtLasAsyncRPCDlgTime = wxDateTime::Now(); if (response != wxID_OK) { // TODO: If user presses Cancel in Please Wait dialog but request // has not yet been started, should we just remove it from queue? diff --git a/clientgui/MainDocument.cpp b/clientgui/MainDocument.cpp index 2f9c141880..9b8caf08fd 100644 --- a/clientgui/MainDocument.cpp +++ b/clientgui/MainDocument.cpp @@ -44,6 +44,8 @@ #include #endif +#define USE_CACHE_TIMEOUTS 0 + // *** RPC update intervals in seconds *** // m_dtCachedCCStatusTimestamp #define CCSTATUS_RPC_INTERVAL 1 @@ -72,6 +74,8 @@ // m_dtCachedAcctMgrInfoTimestamp #define CACHEDACCTMGRINFORPC_INTERVAL 600 +// m_dtLasAsyncRPCDlgTime +#define DELAYAFTERASYNCRPC_DLG 1 bool g_use_sandbox = false; @@ -414,6 +418,8 @@ CMainDocument::CMainDocument() : rpc(this) { m_dtCachedAcctMgrInfoTimestamp = wxDateTime((time_t)0); m_iAcct_mgr_info_rpc_result = -1; + + m_dtLasAsyncRPCDlgTime = wxDateTime((time_t)0); } @@ -668,8 +674,11 @@ int CMainDocument::GetCoreClientStatus(CC_STATUS& ccs, bool bForce) { if (IsConnected()) { if (!m_bWaitingForRPC) { // Prevent recursive entry of RequestRPC() +#if USE_CACHE_TIMEOUTS wxTimeSpan ts(wxDateTime::Now() - m_dtCachedCCStatusTimestamp); if (ts.GetSeconds() >= (10 * CCSTATUS_RPC_INTERVAL)) bForce = true; +#endif + if (m_dtCachedCCStatusTimestamp.IsEqualTo(wxDateTime((time_t)0))) bForce = true; } if (bForce) { m_dtCachedCCStatusTimestamp = wxDateTime::Now(); @@ -777,6 +786,7 @@ void CMainDocument::RefreshRPCs() { void CMainDocument::RunPeriodicRPCs() { ASYNC_RPC_REQUEST request; + wxTimeSpan ts; // Timer events are handled while the RPC Wait dialog is shown // which may cause unintended recursion and repeatedly posting @@ -786,6 +796,19 @@ void CMainDocument::RunPeriodicRPCs() { CBOINCBaseFrame* pFrame = wxGetApp().GetFrame(); if (!pFrame) return; + int currentTabView = pFrame->GetCurrentViewPage(); + + // If the client is heavily loaded (e.g, very many tasks), the + // RPC Wait dialog could appear continuously. To prevent this, + // delay periodic RPCs for 1 second after the dialog closes. + wxDateTime dtNow(wxDateTime::Now()); + if ((currentTabView & (VW_STAT | VW_DISK)) == 0) { + ts = dtNow - m_dtLasAsyncRPCDlgTime; + if (ts.GetSeconds()<= DELAYAFTERASYNCRPC_DLG) { + return; + } + } + wxASSERT(wxDynamicCast(pFrame, CBOINCBaseFrame)); if (!IsConnected()) { @@ -803,8 +826,6 @@ void CMainDocument::RunPeriodicRPCs() { return; } - int currentTabView = pFrame->GetCurrentViewPage(); - // Several functions (such as Abort, Reset, Detach) display an // "Are you sure?" dialog before passing a pointer to a result // or project in a demand RPC call. If Periodic RPCs continue @@ -819,11 +840,9 @@ void CMainDocument::RunPeriodicRPCs() { return; } - wxDateTime dtNow(wxDateTime::Now()); - // *********** RPC_GET_CC_STATUS ************** - wxTimeSpan ts(dtNow - m_dtCachedCCStatusTimestamp); + ts = dtNow - m_dtCachedCCStatusTimestamp; if (ts.GetSeconds() >= CCSTATUS_RPC_INTERVAL) { request.clear(); request.which_rpc = RPC_GET_CC_STATUS; @@ -1128,8 +1147,12 @@ int CMainDocument::CachedProjectStatusUpdate(bool bForce) { if (! IsConnected()) return -1; +#if USE_CACHE_TIMEOUTS wxTimeSpan ts(wxDateTime::Now() - m_dtProjecStatusTimestamp); if (ts.GetSeconds() >= (2 * PROJECTSTATUSRPC_INTERVAL)) bForce = true; +#endif + if (m_dtProjecStatusTimestamp.IsEqualTo(wxDateTime((time_t)0))) bForce = true; + if (bForce) { m_dtProjecStatusTimestamp = wxDateTime::Now(); m_iGet_project_status1_rpc_result = rpc.get_project_status(async_projects_update_buf, state); @@ -1366,6 +1389,7 @@ int CMainDocument::ProjectAllowMoreWork(const wxString& projectname) { int CMainDocument::CachedResultsStatusUpdate() { if (! IsConnected()) return -1; bool active_tasks_only = false; + bool immediate = false; CBOINCBaseFrame* pFrame = wxGetApp().GetFrame(); if (pFrame) { @@ -1376,8 +1400,13 @@ int CMainDocument::CachedResultsStatusUpdate() { } } +#if USE_CACHE_TIMEOUTS wxTimeSpan ts(wxDateTime::Now() - m_dtResultsTimestamp); - if (ts.GetSeconds() >= (2 * RESULTSRPC_INTERVAL)) { + if (ts.GetSeconds() >= (2 * RESULTSRPC_INTERVAL)) immediate = true; +#endif + if (m_dtResultsTimestamp.IsEqualTo(wxDateTime((time_t)0))) immediate = true; + + if (immediate) { m_dtResultsTimestamp = wxDateTime::Now(); m_iGet_results_rpc_result = rpc.get_results(results, active_tasks_only); } @@ -1802,10 +1831,17 @@ int CMainDocument::ResetMessageState() { int CMainDocument::CachedFileTransfersUpdate() { + bool immediate = false; + if (! IsConnected()) return -1; +#if USE_CACHE_TIMEOUTS wxTimeSpan ts(wxDateTime::Now() - m_dtFileTransfersTimestamp); - if (ts.GetSeconds() >= (2* FILETRANSFERSRPC_INTERVAL)) { + if (ts.GetSeconds() >= (2* FILETRANSFERSRPC_INTERVAL)) immediate = true; +#endif + if (m_dtFileTransfersTimestamp.IsEqualTo(wxDateTime((time_t)0))) immediate = true; + + if (immediate) { m_dtFileTransfersTimestamp = wxDateTime::Now(); m_iGet_file_transfers_rpc_result = rpc.get_file_transfers(ft); } @@ -1923,14 +1959,21 @@ int CMainDocument::TransferAbort(const wxString& fileName, const wxString& proje int CMainDocument::CachedDiskUsageUpdate() { - if (! IsConnected()) return -1; + bool immediate = false; - wxTimeSpan ts(wxDateTime::Now() - m_dtDiskUsageTimestamp); + if (! IsConnected()) return -1; // don't get disk usage more than once per minute // unless we just connected to a client // - if ((ts.GetSeconds() >= (2 * DISKUSAGERPC_INTERVAL)) || disk_usage.projects.empty()) { +#if USE_CACHE_TIMEOUTS + wxTimeSpan ts(wxDateTime::Now() - m_dtDiskUsageTimestamp); + if (ts.GetSeconds() >= (2 * DISKUSAGERPC_INTERVAL)) immediate = true; +#endif + if (disk_usage.projects.empty()) immediate = true; + if (m_dtDiskUsageTimestamp.IsEqualTo(wxDateTime((time_t)0))) immediate = true; + + if (immediate) { m_dtDiskUsageTimestamp = wxDateTime::Now(); m_iGet_dsk_usage_rpc_result = rpc.get_disk_usage(disk_usage); } @@ -1960,12 +2003,19 @@ PROJECT* CMainDocument::DiskUsageProject(unsigned int i) { } int CMainDocument::CachedStatisticsStatusUpdate() { + bool immediate = false; + if (! IsConnected()) return -1; +#if USE_CACHE_TIMEOUTS wxTimeSpan ts(wxDateTime::Now() - m_dtStatisticsStatusTimestamp); - if ((ts.GetSeconds() >= (2 * STATISTICSSTATUSRPC_INTERVAL)) || statistics_status.projects.empty()) { + if (ts.GetSeconds() >= (2 * STATISTICSSTATUSRPC_INTERVAL)) immediate = true; +#endif + if (statistics_status.projects.empty()) immediate = true; + if (m_dtStatisticsStatusTimestamp.IsEqualTo(wxDateTime((time_t)0))) immediate = true; + + if (immediate) { m_dtStatisticsStatusTimestamp = wxDateTime::Now(); - m_dtStatisticsStatusTimestamp = rpc.get_statistics(statistics_status); } @@ -2045,8 +2095,11 @@ int CMainDocument::CachedSimpleGUIUpdate(bool bForce) { if (! IsConnected()) return -1; +#if USE_CACHE_TIMEOUTS wxTimeSpan ts(wxDateTime::Now() - m_dtCachedSimpleGUITimestamp); if (ts.GetSeconds() >= (2 * CACHEDSIMPLEGUIRPC_INTERVAL)) bForce = true; +#endif + if (m_dtCachedSimpleGUITimestamp.IsEqualTo(wxDateTime((time_t)0))) bForce = true; if (bForce) { m_dtCachedSimpleGUITimestamp = wxDateTime::Now(); m_iGet_simple_gui2_rpc_result = rpc.get_simple_gui_info(async_projects_update_buf, state, results); diff --git a/clientgui/MainDocument.h b/clientgui/MainDocument.h index b16f5cc9e4..ef2c7c4c08 100644 --- a/clientgui/MainDocument.h +++ b/clientgui/MainDocument.h @@ -198,6 +198,7 @@ private: BOINC_Condition* m_pRPC_Thread_Condition; BOINC_Mutex* m_pRPC_Request_Mutex; BOINC_Condition* m_pRPC_Request_Condition; + wxDateTime m_dtLasAsyncRPCDlgTime; // // Project Tab