From b573ff04e6aefcb9050da330408e757410ede53b Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 17 May 2022 16:34:06 +0200 Subject: [dnbd3] Show upload speed and client count in realtime --- modules-available/dnbd3/inc/dnbd3rpc.inc.php | 73 ++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'modules-available/dnbd3/inc') diff --git a/modules-available/dnbd3/inc/dnbd3rpc.inc.php b/modules-available/dnbd3/inc/dnbd3rpc.inc.php index 1a1e9f5c..9d7ba46c 100644 --- a/modules-available/dnbd3/inc/dnbd3rpc.inc.php +++ b/modules-available/dnbd3/inc/dnbd3rpc.inc.php @@ -82,4 +82,77 @@ class Dnbd3Rpc { return $str; } + /** + * Get statistics for multiple servers at once. + * @param string[] $servers + * @return array + */ + public static function getStatsMulti(array $servers, int $timeout = 2): array + { + if (empty($servers)) + return []; + $active = []; + $mh = curl_multi_init(); + curl_multi_setopt($mh, CURLMOPT_MAXCONNECTS, 8); + curl_multi_setopt($mh, CURLMOPT_MAX_HOST_CONNECTIONS, 2); + curl_multi_setopt($mh, CURLMOPT_MAX_TOTAL_CONNECTIONS, 8); + foreach ($servers as $server) { + $url = 'http://' . self::translateServer($server) . '/query?q=stats'; + $res = curl_init($url); + if ($res === false) { + error_log("curl_init($url) failed with $res"); + continue; + } + curl_setopt_array($res, [ + CURLOPT_CONNECTTIMEOUT => $timeout, + CURLOPT_TIMEOUT => $timeout, + CURLOPT_FOLLOWLOCATION => 0, + CURLOPT_ACCEPT_ENCODING => '', // Use everything libcurl supports + CURLOPT_PROTOCOLS => CURLPROTO_HTTP | CURLPROTO_HTTPS, + CURLOPT_RETURNTRANSFER => 1, + ]); + $err = curl_multi_add_handle($mh, $res); + if ($err !== 0) { + error_log("curl_multi_add_handle() failed with $err"); + curl_close($res); + } else { + $active[(int)$res] = $server; + } + } + // Wait + $running = 1; + $result = []; + $startTime = microtime(true); + for (;;) { + $ret = curl_multi_exec($mh, $running); + while (($info = curl_multi_info_read($mh)) !== false) { + if ($info['msg'] === CURLMSG_DONE) { + if (isset($active[(int)$info['handle']])) { + $server = $active[(int)$info['handle']]; + unset($active[(int)$info['handle']]); + if ($info['result'] === CURLE_OK) { + $data = json_decode(curl_multi_getcontent($info['handle']), true); + if (is_array($data)) { + $data['ts'] = microtime(true); + $result[$server] = $data; + } + } + } + curl_multi_remove_handle($mh, $info['handle']); + curl_close($info['handle']); + } + } + $delay = ($startTime + $timeout) - microtime(true); + if ($ret !== CURLM_OK || !$running || $delay <= 0) + break; + $sret = curl_multi_select($mh, $delay); + if ($sret < 0) { + error_log("curl_multi_select returned $sret"); + break; + } + } + curl_multi_close($mh); + return $result; + } + } -- cgit v1.2.3-55-g7522