notify: webhook, gotify: set HTTP request timeout of 10s

By default, the sync client from proxmox-http (powered by ureq) does not
have any request timeout. To avoid blocking the current thread for a
prolonged period of time, we now make use of the previously added
`Client::new_with_timeout` function to create a new HTTP client with a
default timeout of 10 seconds.

In the long run it would be nicer to have a higher timeout here, say
60s, to cope with flaky and high-latency networks and potentially
overloaded targets. But for that we need to change the architecture of
how notifications are send out to ensure that now thread accepting
connections can be blocked.

Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
 [ TL: Change timeout from 5s to 10s as trade-off and expand commit
   message slightly with some reasoning for that still relatively
   short time value ]
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
Lukas Wagner 2024-11-22 11:08:15 +01:00 committed by Thomas Lamprecht
parent 6664b4150d
commit dfe81b5db8
2 changed files with 9 additions and 2 deletions

View File

@ -1,4 +1,5 @@
use std::collections::HashMap;
use std::time::Duration;
use serde::{Deserialize, Serialize};
use serde_json::json;
@ -13,6 +14,8 @@ use crate::renderer::TemplateType;
use crate::schema::ENTITY_NAME_SCHEMA;
use crate::{renderer, Content, Endpoint, Error, Notification, Origin, Severity};
const HTTP_TIMEOUT: Duration = Duration::from_secs(10);
fn severity_to_priority(level: Severity) -> u32 {
match level {
Severity::Info => 1,
@ -146,7 +149,7 @@ impl Endpoint for GotifyEndpoint {
..Default::default()
};
let client = Client::new(options);
let client = Client::new_with_timeout(options, HTTP_TIMEOUT);
let uri = format!("{}/message", self.config.server);
client

View File

@ -7,6 +7,8 @@
//! Secrets are kept in a private configuration file, accessible only by root, and are not retrievable via the API.
//! Within templates, secrets can be referenced using `{{ secrets.<name> }}`.
//! Additionally, we take measures to prevent secrets from appearing in logs or error messages.
use std::time::Duration;
use handlebars::{
Context as HandlebarsContext, Handlebars, Helper, HelperResult, Output, RenderContext,
RenderError as HandlebarsRenderError,
@ -30,6 +32,8 @@ use crate::{renderer, Content, Endpoint, Error, Notification, Origin};
/// This will be used as a section type in the public/private configuration file.
pub(crate) const WEBHOOK_TYPENAME: &str = "webhook";
const HTTP_TIMEOUT: Duration = Duration::from_secs(10);
#[api]
#[derive(Serialize, Deserialize, Clone, Copy, Default)]
#[serde(rename_all = "kebab-case")]
@ -270,7 +274,7 @@ impl WebhookEndpoint {
..Default::default()
};
Ok(Client::new(options))
Ok(Client::new_with_timeout(options, HTTP_TIMEOUT))
}
fn build_request(&self, notification: &Notification) -> Result<Request<String>, Error> {