diff --git a/Documentation/Monitors/Monitor-Common.md b/Documentation/Monitors/Monitor-Common.md index f70675749..8de168dee 100644 --- a/Documentation/Monitors/Monitor-Common.md +++ b/Documentation/Monitors/Monitor-Common.md @@ -16,12 +16,13 @@ the `monitorpw` parameter, that value will be used instead. ### `monitor_interval` -This is the time the monitor waits between each cycle of monitoring. The default -value of 2000 milliseconds (2 seconds) should be lowered if you want a faster -response to changes in the server states. The value is defined in milliseconds -and the smallest possible value is 100 milliseconds. +Defines, in milliseconds, how often the monitor updates the status of the +servers. The default value is 2000 (2 seconds). Choose a lower value if servers +should be queried more often. The smallest possible value is 100. If querying +the servers takes longer than `monitor_interval`, the effective update rate is +reduced. -The default value of _monitor_interval_ was updated from 10000 milliseconds to +The default value of `monitor_interval` was updated from 10000 milliseconds to 2000 milliseconds in MaxScale 2.2.0. ``` diff --git a/include/maxscale/monitor.hh b/include/maxscale/monitor.hh index ab745bde0..e2b0ba98c 100644 --- a/include/maxscale/monitor.hh +++ b/include/maxscale/monitor.hh @@ -220,6 +220,7 @@ private: void main(); static void main(void* pArg); + void sleep_until_next_tick(int64_t tick_start_ms); }; class MonitorInstanceSimple : public MonitorInstance diff --git a/server/core/monitor.cc b/server/core/monitor.cc index 427afa772..2b1d7202d 100644 --- a/server/core/monitor.cc +++ b/server/core/monitor.cc @@ -2927,6 +2927,9 @@ void MonitorInstance::main() while (!m_shutdown) { + /* Measure the time of monitor loop execution. */ + int64_t loop_start_ms = get_time_ms(); + monitor_check_maintenance_requests(m_monitor); tick(); @@ -2938,24 +2941,34 @@ void MonitorInstance::main() mon_hangup_failed_servers(m_monitor); store_server_journal(m_monitor, m_master); - - /** Sleep until the next monitoring interval */ - unsigned int ms = 0; - while (ms < m_monitor->interval && !m_shutdown) - { - if (atomic_load_int(&m_monitor->check_maintenance_flag) != MAINTENANCE_FLAG_NOCHECK) - { - // Admin has changed something, skip sleep - break; - } - thread_millisleep(MXS_MON_BASE_INTERVAL_MS); - ms += MXS_MON_BASE_INTERVAL_MS; - } + sleep_until_next_tick(loop_start_ms); } post_loop(); } +/** + * Sleep until the next monitor tick + * + * @param tick_start_ms When was the latest tick started + */ +void MonitorInstance::sleep_until_next_tick(int64_t tick_start_ms) +{ + // Check how much the monitor should sleep to get one full monitor interval. + int64_t sleep_time_remaining = m_monitor->interval - (get_time_ms() - tick_start_ms); + // Sleep at least one base interval. + sleep_time_remaining = MXS_MAX(MXS_MON_BASE_INTERVAL_MS, sleep_time_remaining); + /* Sleep in small increments to react fast to changes. */ + while (sleep_time_remaining > 0 && !should_shutdown() && + atomic_load_int(&m_monitor->check_maintenance_flag) == MAINTENANCE_FLAG_NOCHECK) + { + int small_sleep_ms = (sleep_time_remaining >= MXS_MON_BASE_INTERVAL_MS) ? + MXS_MON_BASE_INTERVAL_MS : sleep_time_remaining; + thread_millisleep(small_sleep_ms); + sleep_time_remaining -= small_sleep_ms; + } +} + //static void MonitorInstance::main(void* pArg) {