Add healthcheck for db, new clippy lints
This commit is contained in:
		
							parent
							
								
									96547230bc
								
							
						
					
					
						commit
						f9cad61049
					
				
					 13 changed files with 78 additions and 46 deletions
				
			
		| 
						 | 
					@ -5,7 +5,7 @@ fn git_info() {
 | 
				
			||||||
    if let Ok(output) = Command::new("git").args(["rev-parse", "HEAD"]).output() {
 | 
					    if let Ok(output) = Command::new("git").args(["rev-parse", "HEAD"]).output() {
 | 
				
			||||||
        if output.status.success() {
 | 
					        if output.status.success() {
 | 
				
			||||||
            let git_hash = String::from_utf8_lossy(&output.stdout);
 | 
					            let git_hash = String::from_utf8_lossy(&output.stdout);
 | 
				
			||||||
            println!("cargo:rustc-env=GIT_HASH={}", git_hash);
 | 
					            println!("cargo:rustc-env=GIT_HASH={git_hash}");
 | 
				
			||||||
            println!("cargo:rustc-env=GIT_SHORT_HASH={}", &git_hash[..8])
 | 
					            println!("cargo:rustc-env=GIT_SHORT_HASH={}", &git_hash[..8])
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,7 @@ fn git_info() {
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if output.status.success() {
 | 
					        if output.status.success() {
 | 
				
			||||||
            let git_branch = String::from_utf8_lossy(&output.stdout);
 | 
					            let git_branch = String::from_utf8_lossy(&output.stdout);
 | 
				
			||||||
            println!("cargo:rustc-env=GIT_BRANCH={}", git_branch);
 | 
					            println!("cargo:rustc-env=GIT_BRANCH={git_branch}");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -32,11 +32,11 @@ fn version_info() -> Result<(), anyhow::Error> {
 | 
				
			||||||
    let data: toml::Value = toml::from_str(&cargo_data)?;
 | 
					    let data: toml::Value = toml::from_str(&cargo_data)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if let Some(version) = data["package"]["version"].as_str() {
 | 
					    if let Some(version) = data["package"]["version"].as_str() {
 | 
				
			||||||
        println!("cargo:rustc-env=PKG_VERSION={}", version);
 | 
					        println!("cargo:rustc-env=PKG_VERSION={version}");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if let Some(name) = data["package"]["name"].as_str() {
 | 
					    if let Some(name) = data["package"]["name"].as_str() {
 | 
				
			||||||
        println!("cargo:rustc-env=PKG_NAME={}", name);
 | 
					        println!("cargo:rustc-env=PKG_NAME={name}");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,11 +40,11 @@ impl std::fmt::Display for Counter {
 | 
				
			||||||
        let labels = self
 | 
					        let labels = self
 | 
				
			||||||
            .labels
 | 
					            .labels
 | 
				
			||||||
            .iter()
 | 
					            .iter()
 | 
				
			||||||
            .map(|(k, v)| format!("{}: {}", k, v))
 | 
					            .map(|(k, v)| format!("{k}: {v}"))
 | 
				
			||||||
            .collect::<Vec<_>>()
 | 
					            .collect::<Vec<_>>()
 | 
				
			||||||
            .join(", ");
 | 
					            .join(", ");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        write!(f, "{} - {}", labels, self.value)
 | 
					        write!(f, "{labels} - {}", self.value)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -59,11 +59,11 @@ impl std::fmt::Display for Gauge {
 | 
				
			||||||
        let labels = self
 | 
					        let labels = self
 | 
				
			||||||
            .labels
 | 
					            .labels
 | 
				
			||||||
            .iter()
 | 
					            .iter()
 | 
				
			||||||
            .map(|(k, v)| format!("{}: {}", k, v))
 | 
					            .map(|(k, v)| format!("{k}: {v}"))
 | 
				
			||||||
            .collect::<Vec<_>>()
 | 
					            .collect::<Vec<_>>()
 | 
				
			||||||
            .join(", ");
 | 
					            .join(", ");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        write!(f, "{} - {}", labels, self.value)
 | 
					        write!(f, "{labels} - {}", self.value)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -78,7 +78,7 @@ impl std::fmt::Display for Histogram {
 | 
				
			||||||
        let labels = self
 | 
					        let labels = self
 | 
				
			||||||
            .labels
 | 
					            .labels
 | 
				
			||||||
            .iter()
 | 
					            .iter()
 | 
				
			||||||
            .map(|(k, v)| format!("{}: {}", k, v))
 | 
					            .map(|(k, v)| format!("{k}: {v}"))
 | 
				
			||||||
            .collect::<Vec<_>>()
 | 
					            .collect::<Vec<_>>()
 | 
				
			||||||
            .join(", ");
 | 
					            .join(", ");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -87,15 +87,15 @@ impl std::fmt::Display for Histogram {
 | 
				
			||||||
            .iter()
 | 
					            .iter()
 | 
				
			||||||
            .map(|(k, v)| {
 | 
					            .map(|(k, v)| {
 | 
				
			||||||
                if let Some(v) = v {
 | 
					                if let Some(v) = v {
 | 
				
			||||||
                    format!("{}: {:.6}", k, v)
 | 
					                    format!("{k}: {v:.6}")
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    format!("{}: None,", k)
 | 
					                    format!("{k}: None,")
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
            .collect::<Vec<_>>()
 | 
					            .collect::<Vec<_>>()
 | 
				
			||||||
            .join(", ");
 | 
					            .join(", ");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        write!(f, "{} - {}", labels, value)
 | 
					        write!(f, "{labels} - {value}")
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -172,18 +172,18 @@ impl Snapshot {
 | 
				
			||||||
                    continue;
 | 
					                    continue;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                println!("\t{}", key);
 | 
					                println!("\t{key}");
 | 
				
			||||||
                for counter in counters {
 | 
					                for counter in counters {
 | 
				
			||||||
                    println!("\t\t{}", counter);
 | 
					                    println!("\t\t{counter}");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for (key, counters) in merging {
 | 
					            for (key, counters) in merging {
 | 
				
			||||||
                println!("\t{}", key);
 | 
					                println!("\t{key}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                for (_, counter) in counters {
 | 
					                for (_, counter) in counters {
 | 
				
			||||||
                    if let Some(counter) = counter.merge() {
 | 
					                    if let Some(counter) = counter.merge() {
 | 
				
			||||||
                        println!("\t\t{}", counter);
 | 
					                        println!("\t\t{counter}");
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -192,10 +192,10 @@ impl Snapshot {
 | 
				
			||||||
        if !self.gauges.is_empty() {
 | 
					        if !self.gauges.is_empty() {
 | 
				
			||||||
            println!("Gauges");
 | 
					            println!("Gauges");
 | 
				
			||||||
            for (key, gauges) in self.gauges {
 | 
					            for (key, gauges) in self.gauges {
 | 
				
			||||||
                println!("\t{}", key);
 | 
					                println!("\t{key}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                for gauge in gauges {
 | 
					                for gauge in gauges {
 | 
				
			||||||
                    println!("\t\t{}", gauge);
 | 
					                    println!("\t\t{gauge}");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -203,10 +203,10 @@ impl Snapshot {
 | 
				
			||||||
        if !self.histograms.is_empty() {
 | 
					        if !self.histograms.is_empty() {
 | 
				
			||||||
            println!("Histograms");
 | 
					            println!("Histograms");
 | 
				
			||||||
            for (key, histograms) in self.histograms {
 | 
					            for (key, histograms) in self.histograms {
 | 
				
			||||||
                println!("\t{}", key);
 | 
					                println!("\t{key}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                for histogram in histograms {
 | 
					                for histogram in histograms {
 | 
				
			||||||
                    println!("\t\t{}", histogram);
 | 
					                    println!("\t\t{histogram}");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -170,7 +170,7 @@ impl Config {
 | 
				
			||||||
        let config: ParsedConfig = config.try_deserialize()?;
 | 
					        let config: ParsedConfig = config.try_deserialize()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let scheme = if config.https { "https" } else { "http" };
 | 
					        let scheme = if config.https { "https" } else { "http" };
 | 
				
			||||||
        let base_uri = iri!(format!("{}://{}", scheme, config.hostname)).into_absolute();
 | 
					        let base_uri = iri!(format!("{scheme}://{}", config.hostname)).into_absolute();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let tls = match (config.tls_key, config.tls_cert) {
 | 
					        let tls = match (config.tls_key, config.tls_cert) {
 | 
				
			||||||
            (Some(key), Some(cert)) => Some(TlsConfig { key, cert }),
 | 
					            (Some(key), Some(cert)) => Some(TlsConfig { key, cert }),
 | 
				
			||||||
| 
						 | 
					@ -207,8 +207,8 @@ impl Config {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let source_url = match Self::git_hash() {
 | 
					        let source_url = match Self::git_hash() {
 | 
				
			||||||
            Some(hash) => format!(
 | 
					            Some(hash) => format!(
 | 
				
			||||||
                "{}{}{}",
 | 
					                "{}{}{hash}",
 | 
				
			||||||
                config.source_repo, config.repository_commit_base, hash
 | 
					                config.source_repo, config.repository_commit_base
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            .parse()
 | 
					            .parse()
 | 
				
			||||||
            .expect("constructed source URL is valid"),
 | 
					            .expect("constructed source URL is valid"),
 | 
				
			||||||
| 
						 | 
					@ -332,7 +332,7 @@ impl Config {
 | 
				
			||||||
            match AdminConfig::build(api_token) {
 | 
					            match AdminConfig::build(api_token) {
 | 
				
			||||||
                Ok(conf) => Some(actix_web::web::Data::new(conf)),
 | 
					                Ok(conf) => Some(actix_web::web::Data::new(conf)),
 | 
				
			||||||
                Err(e) => {
 | 
					                Err(e) => {
 | 
				
			||||||
                    tracing::error!("Error creating admin config: {}", e);
 | 
					                    tracing::error!("Error creating admin config: {e}");
 | 
				
			||||||
                    None
 | 
					                    None
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -371,7 +371,7 @@ impl Config {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub(crate) fn software_version() -> String {
 | 
					    pub(crate) fn software_version() -> String {
 | 
				
			||||||
        if let Some(git) = Self::git_version() {
 | 
					        if let Some(git) = Self::git_version() {
 | 
				
			||||||
            return format!("v{}-{}", Self::version(), git);
 | 
					            return format!("v{}-{git}", Self::version());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        format!("v{}", Self::version())
 | 
					        format!("v{}", Self::version())
 | 
				
			||||||
| 
						 | 
					@ -381,7 +381,7 @@ impl Config {
 | 
				
			||||||
        let branch = Self::git_branch()?;
 | 
					        let branch = Self::git_branch()?;
 | 
				
			||||||
        let hash = Self::git_short_hash()?;
 | 
					        let hash = Self::git_short_hash()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Some(format!("{}-{}", branch, hash))
 | 
					        Some(format!("{branch}-{hash}"))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn name() -> &'static str {
 | 
					    fn name() -> &'static str {
 | 
				
			||||||
| 
						 | 
					@ -463,7 +463,7 @@ impl Config {
 | 
				
			||||||
                resolved
 | 
					                resolved
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            UrlKind::Media(uuid) => FixedBaseResolver::new(self.base_uri.as_ref())
 | 
					            UrlKind::Media(uuid) => FixedBaseResolver::new(self.base_uri.as_ref())
 | 
				
			||||||
                .resolve(IriRelativeStr::new(&format!("media/{}", uuid))?.as_ref())
 | 
					                .resolve(IriRelativeStr::new(&format!("media/{uuid}"))?.as_ref())
 | 
				
			||||||
                .try_to_dedicated_string()?,
 | 
					                .try_to_dedicated_string()?,
 | 
				
			||||||
            UrlKind::NodeInfo => FixedBaseResolver::new(self.base_uri.as_ref())
 | 
					            UrlKind::NodeInfo => FixedBaseResolver::new(self.base_uri.as_ref())
 | 
				
			||||||
                .resolve(IriRelativeStr::new("nodeinfo/2.0.json")?.as_ref())
 | 
					                .resolve(IriRelativeStr::new("nodeinfo/2.0.json")?.as_ref())
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -182,7 +182,7 @@ impl Node {
 | 
				
			||||||
        let authority = url.authority_str().ok_or(ErrorKind::MissingDomain)?;
 | 
					        let authority = url.authority_str().ok_or(ErrorKind::MissingDomain)?;
 | 
				
			||||||
        let scheme = url.scheme_str();
 | 
					        let scheme = url.scheme_str();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let base = iri!(format!("{}://{}", scheme, authority));
 | 
					        let base = iri!(format!("{scheme}://{authority}"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Ok(Node {
 | 
					        Ok(Node {
 | 
				
			||||||
            base,
 | 
					            base,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										30
									
								
								src/db.rs
									
										
									
									
									
								
							
							
						
						
									
										30
									
								
								src/db.rs
									
										
									
									
									
								
							| 
						 | 
					@ -10,7 +10,10 @@ use rsa::{
 | 
				
			||||||
use sled::{Batch, Tree};
 | 
					use sled::{Batch, Tree};
 | 
				
			||||||
use std::{
 | 
					use std::{
 | 
				
			||||||
    collections::{BTreeMap, HashMap},
 | 
					    collections::{BTreeMap, HashMap},
 | 
				
			||||||
    sync::Arc,
 | 
					    sync::{
 | 
				
			||||||
 | 
					        atomic::{AtomicU64, Ordering},
 | 
				
			||||||
 | 
					        Arc,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    time::SystemTime,
 | 
					    time::SystemTime,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use time::OffsetDateTime;
 | 
					use time::OffsetDateTime;
 | 
				
			||||||
| 
						 | 
					@ -22,6 +25,8 @@ pub(crate) struct Db {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Inner {
 | 
					struct Inner {
 | 
				
			||||||
 | 
					    healthz: Tree,
 | 
				
			||||||
 | 
					    healthz_counter: Arc<AtomicU64>,
 | 
				
			||||||
    actor_id_actor: Tree,
 | 
					    actor_id_actor: Tree,
 | 
				
			||||||
    public_key_id_actor_id: Tree,
 | 
					    public_key_id_actor_id: Tree,
 | 
				
			||||||
    connected_actor_ids: Tree,
 | 
					    connected_actor_ids: Tree,
 | 
				
			||||||
| 
						 | 
					@ -242,6 +247,8 @@ impl Db {
 | 
				
			||||||
    fn build_inner(restricted_mode: bool, db: sled::Db) -> Result<Self, Error> {
 | 
					    fn build_inner(restricted_mode: bool, db: sled::Db) -> Result<Self, Error> {
 | 
				
			||||||
        Ok(Db {
 | 
					        Ok(Db {
 | 
				
			||||||
            inner: Arc::new(Inner {
 | 
					            inner: Arc::new(Inner {
 | 
				
			||||||
 | 
					                healthz: db.open_tree("healthz")?,
 | 
				
			||||||
 | 
					                healthz_counter: Arc::new(AtomicU64::new(0)),
 | 
				
			||||||
                actor_id_actor: db.open_tree("actor-id-actor")?,
 | 
					                actor_id_actor: db.open_tree("actor-id-actor")?,
 | 
				
			||||||
                public_key_id_actor_id: db.open_tree("public-key-id-actor-id")?,
 | 
					                public_key_id_actor_id: db.open_tree("public-key-id-actor-id")?,
 | 
				
			||||||
                connected_actor_ids: db.open_tree("connected-actor-ids")?,
 | 
					                connected_actor_ids: db.open_tree("connected-actor-ids")?,
 | 
				
			||||||
| 
						 | 
					@ -273,6 +280,21 @@ impl Db {
 | 
				
			||||||
        Ok(t)
 | 
					        Ok(t)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub(crate) async fn check_health(&self) -> Result<(), Error> {
 | 
				
			||||||
 | 
					        let next = self.inner.healthz_counter.fetch_add(1, Ordering::Relaxed);
 | 
				
			||||||
 | 
					        self.unblock(move |inner| {
 | 
				
			||||||
 | 
					            inner
 | 
				
			||||||
 | 
					                .healthz
 | 
				
			||||||
 | 
					                .insert("healthz", &next.to_be_bytes()[..])
 | 
				
			||||||
 | 
					                .map_err(Error::from)
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .await?;
 | 
				
			||||||
 | 
					        self.inner.healthz.flush_async().await?;
 | 
				
			||||||
 | 
					        self.unblock(move |inner| inner.healthz.get("healthz").map_err(Error::from))
 | 
				
			||||||
 | 
					            .await?;
 | 
				
			||||||
 | 
					        Ok(())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub(crate) async fn mark_last_seen(
 | 
					    pub(crate) async fn mark_last_seen(
 | 
				
			||||||
        &self,
 | 
					        &self,
 | 
				
			||||||
        nodes: HashMap<String, OffsetDateTime>,
 | 
					        nodes: HashMap<String, OffsetDateTime>,
 | 
				
			||||||
| 
						 | 
					@ -468,7 +490,7 @@ impl Db {
 | 
				
			||||||
    pub(crate) async fn is_connected(&self, base_id: IriString) -> Result<bool, Error> {
 | 
					    pub(crate) async fn is_connected(&self, base_id: IriString) -> Result<bool, Error> {
 | 
				
			||||||
        let scheme = base_id.scheme_str();
 | 
					        let scheme = base_id.scheme_str();
 | 
				
			||||||
        let authority = base_id.authority_str().ok_or(ErrorKind::MissingDomain)?;
 | 
					        let authority = base_id.authority_str().ok_or(ErrorKind::MissingDomain)?;
 | 
				
			||||||
        let prefix = format!("{}://{}", scheme, authority);
 | 
					        let prefix = format!("{scheme}://{authority}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.unblock(move |inner| {
 | 
					        self.unblock(move |inner| {
 | 
				
			||||||
            let connected = inner
 | 
					            let connected = inner
 | 
				
			||||||
| 
						 | 
					@ -528,7 +550,7 @@ impl Db {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub(crate) async fn remove_connection(&self, actor_id: IriString) -> Result<(), Error> {
 | 
					    pub(crate) async fn remove_connection(&self, actor_id: IriString) -> Result<(), Error> {
 | 
				
			||||||
        tracing::debug!("Removing Connection: {}", actor_id);
 | 
					        tracing::debug!("Removing Connection: {actor_id}");
 | 
				
			||||||
        self.unblock(move |inner| {
 | 
					        self.unblock(move |inner| {
 | 
				
			||||||
            inner
 | 
					            inner
 | 
				
			||||||
                .connected_actor_ids
 | 
					                .connected_actor_ids
 | 
				
			||||||
| 
						 | 
					@ -540,7 +562,7 @@ impl Db {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub(crate) async fn add_connection(&self, actor_id: IriString) -> Result<(), Error> {
 | 
					    pub(crate) async fn add_connection(&self, actor_id: IriString) -> Result<(), Error> {
 | 
				
			||||||
        tracing::debug!("Adding Connection: {}", actor_id);
 | 
					        tracing::debug!("Adding Connection: {actor_id}");
 | 
				
			||||||
        self.unblock(move |inner| {
 | 
					        self.unblock(move |inner| {
 | 
				
			||||||
            inner
 | 
					            inner
 | 
				
			||||||
                .connected_actor_ids
 | 
					                .connected_actor_ids
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,7 +45,7 @@ impl QueryInstance {
 | 
				
			||||||
            .authority_str()
 | 
					            .authority_str()
 | 
				
			||||||
            .ok_or(ErrorKind::MissingDomain)?;
 | 
					            .ok_or(ErrorKind::MissingDomain)?;
 | 
				
			||||||
        let scheme = self.actor_id.scheme_str();
 | 
					        let scheme = self.actor_id.scheme_str();
 | 
				
			||||||
        let instance_uri = iri!(format!("{}://{}/api/v1/instance", scheme, authority));
 | 
					        let instance_uri = iri!(format!("{scheme}://{authority}/api/v1/instance"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let instance = match state
 | 
					        let instance = match state
 | 
				
			||||||
            .requests
 | 
					            .requests
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,7 +39,7 @@ impl QueryNodeinfo {
 | 
				
			||||||
            .authority_str()
 | 
					            .authority_str()
 | 
				
			||||||
            .ok_or(ErrorKind::MissingDomain)?;
 | 
					            .ok_or(ErrorKind::MissingDomain)?;
 | 
				
			||||||
        let scheme = self.actor_id.scheme_str();
 | 
					        let scheme = self.actor_id.scheme_str();
 | 
				
			||||||
        let well_known_uri = iri!(format!("{}://{}/.well-known/nodeinfo", scheme, authority));
 | 
					        let well_known_uri = iri!(format!("{scheme}://{authority}/.well-known/nodeinfo"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let well_known = match state
 | 
					        let well_known = match state
 | 
				
			||||||
            .requests
 | 
					            .requests
 | 
				
			||||||
| 
						 | 
					@ -168,7 +168,7 @@ impl<'de> serde::de::Visitor<'de> for SupportedVersionVisitor {
 | 
				
			||||||
    type Value = SupportedVersion;
 | 
					    type Value = SupportedVersion;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
 | 
					    fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
 | 
				
			||||||
        write!(f, "a string starting with '{}'", SUPPORTED_VERSIONS)
 | 
					        write!(f, "a string starting with '{SUPPORTED_VERSIONS}'")
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
 | 
					    fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
 | 
				
			||||||
| 
						 | 
					@ -187,7 +187,7 @@ impl<'de> serde::de::Visitor<'de> for SupportedNodeinfoVisitor {
 | 
				
			||||||
    type Value = SupportedNodeinfo;
 | 
					    type Value = SupportedNodeinfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
 | 
					    fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
 | 
				
			||||||
        write!(f, "a string starting with '{}'", SUPPORTED_NODEINFO)
 | 
					        write!(f, "a string starting with '{SUPPORTED_NODEINFO}'")
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
 | 
					    fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,7 +39,7 @@ use self::{
 | 
				
			||||||
    db::Db,
 | 
					    db::Db,
 | 
				
			||||||
    jobs::create_workers,
 | 
					    jobs::create_workers,
 | 
				
			||||||
    middleware::{DebugPayload, MyVerify, RelayResolver, Timings},
 | 
					    middleware::{DebugPayload, MyVerify, RelayResolver, Timings},
 | 
				
			||||||
    routes::{actor, inbox, index, nodeinfo, nodeinfo_meta, statics},
 | 
					    routes::{actor, healthz, inbox, index, nodeinfo, nodeinfo_meta, statics},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn init_subscriber(
 | 
					fn init_subscriber(
 | 
				
			||||||
| 
						 | 
					@ -273,6 +273,7 @@ async fn do_server_main(
 | 
				
			||||||
        app.wrap(Compress::default())
 | 
					        app.wrap(Compress::default())
 | 
				
			||||||
            .wrap(TracingLogger::default())
 | 
					            .wrap(TracingLogger::default())
 | 
				
			||||||
            .wrap(Timings)
 | 
					            .wrap(Timings)
 | 
				
			||||||
 | 
					            .route("/healthz", web::get().to(healthz))
 | 
				
			||||||
            .service(web::resource("/").route(web::get().to(index)))
 | 
					            .service(web::resource("/").route(web::get().to(index)))
 | 
				
			||||||
            .service(web::resource("/media/{path}").route(web::get().to(routes::media)))
 | 
					            .service(web::resource("/media/{path}").route(web::get().to(routes::media)))
 | 
				
			||||||
            .service(
 | 
					            .service(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -75,7 +75,7 @@ impl MyVerify {
 | 
				
			||||||
                Ok(res) => res.actor_id().ok_or(ErrorKind::MissingId),
 | 
					                Ok(res) => res.actor_id().ok_or(ErrorKind::MissingId),
 | 
				
			||||||
                Err(e) => {
 | 
					                Err(e) => {
 | 
				
			||||||
                    if e.is_gone() {
 | 
					                    if e.is_gone() {
 | 
				
			||||||
                        tracing::warn!("Actor gone: {}", public_key_id);
 | 
					                        tracing::warn!("Actor gone: {public_key_id}");
 | 
				
			||||||
                        return Ok(false);
 | 
					                        return Ok(false);
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                        return Err(e);
 | 
					                        return Err(e);
 | 
				
			||||||
| 
						 | 
					@ -178,13 +178,13 @@ mod tests {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[test]
 | 
					    #[test]
 | 
				
			||||||
    fn handles_masto_keys() {
 | 
					    fn handles_masto_keys() {
 | 
				
			||||||
        println!("{}", ASONIX_DOG_KEY);
 | 
					        println!("{ASONIX_DOG_KEY}");
 | 
				
			||||||
        let _ = RsaPublicKey::from_public_key_pem(ASONIX_DOG_KEY.trim()).unwrap();
 | 
					        let _ = RsaPublicKey::from_public_key_pem(ASONIX_DOG_KEY.trim()).unwrap();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[test]
 | 
					    #[test]
 | 
				
			||||||
    fn handles_pleromo_keys() {
 | 
					    fn handles_pleromo_keys() {
 | 
				
			||||||
        println!("{}", KARJALAZET_KEY);
 | 
					        println!("{KARJALAZET_KEY}");
 | 
				
			||||||
        let _ = RsaPublicKey::from_public_key_pem(KARJALAZET_KEY.trim()).unwrap();
 | 
					        let _ = RsaPublicKey::from_public_key_pem(KARJALAZET_KEY.trim()).unwrap();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -61,7 +61,7 @@ impl Breakers {
 | 
				
			||||||
                if let Some(mut breaker) = self.inner.get_mut(authority) {
 | 
					                if let Some(mut breaker) = self.inner.get_mut(authority) {
 | 
				
			||||||
                    breaker.fail();
 | 
					                    breaker.fail();
 | 
				
			||||||
                    if !breaker.should_try() {
 | 
					                    if !breaker.should_try() {
 | 
				
			||||||
                        tracing::warn!("Failed breaker for {}", authority);
 | 
					                        tracing::warn!("Failed breaker for {authority}");
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    false
 | 
					                    false
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
| 
						 | 
					@ -235,7 +235,7 @@ impl Requests {
 | 
				
			||||||
            if let Ok(bytes) = res.body().await {
 | 
					            if let Ok(bytes) = res.body().await {
 | 
				
			||||||
                if let Ok(s) = String::from_utf8(bytes.as_ref().to_vec()) {
 | 
					                if let Ok(s) = String::from_utf8(bytes.as_ref().to_vec()) {
 | 
				
			||||||
                    if !s.is_empty() {
 | 
					                    if !s.is_empty() {
 | 
				
			||||||
                        tracing::warn!("Response from {}, {}", parsed_url, s);
 | 
					                        tracing::warn!("Response from {parsed_url}, {s}");
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,5 @@
 | 
				
			||||||
mod actor;
 | 
					mod actor;
 | 
				
			||||||
 | 
					mod healthz;
 | 
				
			||||||
mod inbox;
 | 
					mod inbox;
 | 
				
			||||||
mod index;
 | 
					mod index;
 | 
				
			||||||
mod media;
 | 
					mod media;
 | 
				
			||||||
| 
						 | 
					@ -7,6 +8,7 @@ mod statics;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub(crate) use self::{
 | 
					pub(crate) use self::{
 | 
				
			||||||
    actor::route as actor,
 | 
					    actor::route as actor,
 | 
				
			||||||
 | 
					    healthz::route as healthz,
 | 
				
			||||||
    inbox::route as inbox,
 | 
					    inbox::route as inbox,
 | 
				
			||||||
    index::route as index,
 | 
					    index::route as index,
 | 
				
			||||||
    media::route as media,
 | 
					    media::route as media,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										7
									
								
								src/routes/healthz.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/routes/healthz.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					use crate::{data::State, error::Error};
 | 
				
			||||||
 | 
					use actix_web::{web, HttpResponse};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub(crate) async fn route(state: web::Data<State>) -> Result<HttpResponse, Error> {
 | 
				
			||||||
 | 
					    state.db.check_health().await?;
 | 
				
			||||||
 | 
					    Ok(HttpResponse::Ok().finish())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -89,19 +89,19 @@ async fn answer(bot: Bot, msg: Message, cmd: Command, db: Db) -> ResponseResult<
 | 
				
			||||||
                .await?;
 | 
					                .await?;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Command::Block { domain } if db.add_blocks(vec![domain.clone()]).await.is_ok() => {
 | 
					        Command::Block { domain } if db.add_blocks(vec![domain.clone()]).await.is_ok() => {
 | 
				
			||||||
            bot.send_message(msg.chat.id, format!("{} has been blocked", domain))
 | 
					            bot.send_message(msg.chat.id, format!("{domain} has been blocked"))
 | 
				
			||||||
                .await?;
 | 
					                .await?;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Command::Unblock { domain } if db.remove_blocks(vec![domain.clone()]).await.is_ok() => {
 | 
					        Command::Unblock { domain } if db.remove_blocks(vec![domain.clone()]).await.is_ok() => {
 | 
				
			||||||
            bot.send_message(msg.chat.id, format!("{} has been unblocked", domain))
 | 
					            bot.send_message(msg.chat.id, format!("{domain} has been unblocked"))
 | 
				
			||||||
                .await?;
 | 
					                .await?;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Command::Allow { domain } if db.add_allows(vec![domain.clone()]).await.is_ok() => {
 | 
					        Command::Allow { domain } if db.add_allows(vec![domain.clone()]).await.is_ok() => {
 | 
				
			||||||
            bot.send_message(msg.chat.id, format!("{} has been allowed", domain))
 | 
					            bot.send_message(msg.chat.id, format!("{domain} has been allowed"))
 | 
				
			||||||
                .await?;
 | 
					                .await?;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Command::Disallow { domain } if db.remove_allows(vec![domain.clone()]).await.is_ok() => {
 | 
					        Command::Disallow { domain } if db.remove_allows(vec![domain.clone()]).await.is_ok() => {
 | 
				
			||||||
            bot.send_message(msg.chat.id, format!("{} has been disallowed", domain))
 | 
					            bot.send_message(msg.chat.id, format!("{domain} has been disallowed"))
 | 
				
			||||||
                .await?;
 | 
					                .await?;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Command::ListAllowed => {
 | 
					        Command::ListAllowed => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue