Create dedicate crate for php_escaping.rs
[hiphop-php.git] / hphp / runtime / server / host-health-monitor.cpp
blob5b958692cb9ea093094a3ca2bd568d1ca9851e9c
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/runtime/server/host-health-monitor.h"
19 #include <folly/Singleton.h>
20 #include <folly/system/ThreadName.h>
22 #include "hphp/runtime/base/init-fini-node.h"
23 #include "hphp/runtime/ext/extension.h"
24 #include "hphp/util/alloc-defs.h"
25 #include "hphp/util/compatibility.h"
26 #include "hphp/util/health-monitor-types.h"
27 #include "hphp/util/logger.h"
29 namespace HPHP {
31 namespace {
32 bool Enabled;
33 int32_t UpdateFreq;
35 struct HostHealthMonitorExtension final : public Extension {
36 HostHealthMonitorExtension() : Extension("hosthealthmonitor", "1.0") {}
38 void moduleLoad(const IniSetting::Map& ini, Hdf globalConfig) override {
39 Config::Bind(Enabled, ini, globalConfig,
40 "HealthMonitor.EnableHealthMonitor", true);
41 Config::Bind(UpdateFreq, ini, globalConfig,
42 "HealthMonitor.UpdateFreq", 1000 /* miliseconds */);
44 } s_host_health_monitor_extension;
46 folly::Singleton<HostHealthMonitor> s_health_monitor;
50 void HostHealthMonitor::addMetric(IHealthMonitorMetric* metric) {
51 assertx(metric != nullptr);
52 std::lock_guard<std::mutex> g(m_lock);
53 m_metrics.push_back(metric);
56 void IHealthMonitorMetric::registerSelf() {
57 folly::Singleton<HostHealthMonitor>::try_get()->addMetric(this);
60 void HostHealthMonitor::start() {
61 if (!Enabled || !m_stopped) return;
62 if (UpdateFreq < 10) UpdateFreq = 10;
63 if (UpdateFreq > 10000) UpdateFreq = 10000;
65 m_monitor_thread = std::make_unique<std::thread>([] {
66 folly::setThreadName("HostHealthMonitor");
67 folly::Singleton<HostHealthMonitor>::try_get()->monitor();
68 });
70 // Make sure the thread is gone after hphp_process_exit(). The node
71 // is intentionally leaked.
72 new InitFiniNode(
73 [] { folly::Singleton<HostHealthMonitor>::try_get()->waitForEnd(); },
74 InitFiniNode::When::ProcessExit
78 void HostHealthMonitor::stop() {
79 notifyObservers(HealthLevel::Bold);
80 std::unique_lock<std::mutex> guard(m_stopped_lock);
81 m_stopped = true;
82 m_condition.notify_one();
85 void HostHealthMonitor::waitForEnd() {
86 if (!m_stopped) stop();
87 if (m_monitor_thread) {
88 m_monitor_thread->join();
89 m_monitor_thread.reset();
93 void HostHealthMonitor::monitor() {
94 Logger::Info("Host health monitor starts working.");
95 std::unique_lock<std::mutex> guard(m_stopped_lock);
96 m_stopped = false;
98 std::chrono::milliseconds dura(UpdateFreq);
99 while (!m_stopped) {
100 HealthLevel newStatus = evaluate();
101 notifyObservers(newStatus);
102 m_condition.wait_for(guard, dura, [this] { return m_stopped; });
104 Logger::Info("Host health monitor exits.");
107 HealthLevel HostHealthMonitor::evaluate() {
108 #ifdef USE_JEMALLOC
109 mallctl_epoch();
110 #endif
111 HealthLevel res = HealthLevel::Bold;
112 std::lock_guard<std::mutex> g(m_lock);
113 for (auto metric : m_metrics) {
114 res = std::max(res, metric->evaluate());
116 return res;
119 void HostHealthMonitor::notifyObservers(HealthLevel newStatus) {
120 if (newStatus != m_status) {
121 Logger::Warning("Health level (lower is better) changes from %d to %d.",
122 static_cast<int>(m_status), static_cast<int>(newStatus));
124 std::lock_guard<std::mutex> g(m_lock);
125 for (auto observer : m_observers) {
126 observer->notifyNewStatus(newStatus);
128 m_status = newStatus;