Skip to content

Commit

Permalink
Add Graphite Web HTTP request timeout option
Browse files Browse the repository at this point in the history
If the Graphite Web server is unreachable, all requests for frontend
pages containing graphs hang until the backend HTTP request times out,
resulting in a very poor UX.

The Guzzle documentation states that the default behaviour is to wait
indefinitely, however in our testing the cURL handler has an internal
default of 30 seconds:

https://docs.guzzlephp.org/en/stable/request-options.html#timeout

This commit makes the HTTP request timeout configurable and sets a
reasonable default of 10 seconds.
  • Loading branch information
atj authored and nilmerg committed Feb 20, 2024
1 parent f4cdeee commit 5e0d57c
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 3 deletions.
10 changes: 10 additions & 0 deletions application/forms/Config/BackendForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@ public function createElements(array $formData)
'label' => $this->translate('Connect insecurely'),
'description' => $this->translate('Check this to not verify the remote\'s TLS certificate')
]
],
[
'number',
'graphite_timeout',
[
'label' => $this->translate('Request timeout'),
'description' => $this->translate('The timeout for HTTP requests to Graphite Web'),
'min' => 0,
'placeholder' => 10
]
]
]);
}
Expand Down
1 change: 1 addition & 0 deletions library/Graphite/Graphing/GraphingTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ public static function getMetricsDataSource()
->setUser($graphite->user)
->setPassword($graphite->password)
->setInsecure((bool) $graphite->insecure)
->setTimeout(isset($graphite->timeout) ? intval($graphite->timeout) : 10)
);
}

Expand Down
40 changes: 37 additions & 3 deletions library/Graphite/Graphing/GraphiteWebClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ class GraphiteWebClient
*/
protected $insecure = false;

/**
* Timeout for every Graphite Web HTTP request
*
* @var ?int
*/
protected $timeout;

/**
* HTTP client
*
Expand Down Expand Up @@ -79,9 +86,12 @@ public function request(Url $url, $method = 'GET', array $headers = [], $body =
// TODO(ak): keep connections alive (TCP handshakes are a bit expensive and TLS handshakes are very expensive)
return (string) $this->httpClient->send(
new Request($method, $this->completeUrl($url)->getAbsoluteUrl(), $headers, $body),
['curl' => [
CURLOPT_SSL_VERIFYPEER => ! $this->insecure
]]
[
'curl' => [
CURLOPT_SSL_VERIFYPEER => ! $this->insecure
],
'timeout' => $this->timeout ?? 10
]
)->getBody();
}

Expand Down Expand Up @@ -195,4 +205,28 @@ public function setInsecure($insecure = true)

return $this;
}

/**
* Get the HTTP request timeout
*
* @return ?int
*/
public function getTimeout(): ?int
{
return $this->timeout;
}

/**
* Set the HTTP request timeout
*
* @param ?int $timeout
*
* @return $this
*/
public function setTimeout(?int $timeout): self
{
$this->timeout = $timeout;

return $this;
}
}

0 comments on commit 5e0d57c

Please sign in to comment.