Skip to content

Commit

Permalink
Add better modes to control how statistics are returned (#635)
Browse files Browse the repository at this point in the history
  • Loading branch information
aumetra authored Feb 3, 2025
1 parent 6d3d703 commit 0f7e347
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 49 deletions.
17 changes: 9 additions & 8 deletions config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -103,19 +103,20 @@ description = "https://www.youtube.com/watch?v=6lnnPnr_0SU"
# This is the maximum length of posts that can be posted on your instance
# On Mastodon it's 500, on most other implementations it's freely configurable
character-limit = 5000
# Randomize the statistics of your server
#
# Kitsune will expose certain statistics about your server by default.
# Set this value to `true` to serve randomized statistics instead.
#
# Why you'd want this can have many reasons, one of them being privacy reasons.
# Perhaps you don't want to expose accurate information about your server publicly.
randomize-statistics = false
# Registrations open
#
# This signals to clients whether your registrations are currently open or not.
# It will also hard-enforce the closed signups inside of Kitsune, returning an error when a signup is attempted.
registrations-open = true
# Statistics settings of your server
#
# Set to `regular` to just return actual statistics.
# Set to `zero` to return all zeroes.
# Set this value to `random` to serve randomized statistics instead.
#
# Why you'd want this can have many reasons, one of them being privacy reasons.
# Perhaps you don't want to expose accurate information about your server publicly.
statistics-mode = "regular"

# Federation filters
#
Expand Down
11 changes: 10 additions & 1 deletion crates/kitsune-config/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ pub enum FederationFilterConfiguration {
Deny { domains: Vec<SmolStr> },
}

#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub enum StatisticsMode {
#[serde(alias = "dansup")]
Random,
Regular,
Zero,
}

#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub struct Configuration {
Expand All @@ -17,6 +26,6 @@ pub struct Configuration {
pub webfinger_domain: Option<SmolStr>,
pub character_limit: usize,
pub federation_filter: FederationFilterConfiguration,
pub randomize_statistics: bool,
pub registrations_open: bool,
pub statistics_mode: StatisticsMode,
}
88 changes: 49 additions & 39 deletions crates/kitsune-service/src/instance.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use diesel::{ExpressionMethods, QueryDsl};
use diesel_async::RunQueryDsl;
use kitsune_config::instance::StatisticsMode;
use kitsune_db::{
schema::{accounts, posts, users},
with_connection, PgPool,
Expand All @@ -8,7 +9,7 @@ use kitsune_derive::kitsune_service;
use kitsune_error::{Error, Result};
use rand::seq::IteratorRandom;
use smol_str::SmolStr;
use std::ops::RangeInclusive;
use std::{future::Future, ops::RangeInclusive};

const STATISTICS_RANGE: RangeInclusive<u64> = 24..=1312_1312;

Expand All @@ -25,8 +26,20 @@ pub struct InstanceService {
#[builder(setter(into))]
description: SmolStr,
character_limit: usize,
randomize_statistics: bool,
registrations_open: bool,
statistics_mode: StatisticsMode,
}

#[inline]
async fn with_statistics_mode<F, E>(mode: StatisticsMode, fut: F) -> Result<u64, E>
where
F: Future<Output = Result<u64, E>>,
{
match mode {
StatisticsMode::Random => Ok(random_statistic()),
StatisticsMode::Regular => fut.await,
StatisticsMode::Zero => Ok(0),
}
}

impl InstanceService {
Expand All @@ -46,37 +59,35 @@ impl InstanceService {
}

pub async fn known_instances(&self) -> Result<u64> {
if self.randomize_statistics {
return Ok(random_statistic());
}

with_connection!(self.db_pool, |db_conn| {
accounts::table
.filter(accounts::local.eq(false))
.select(accounts::domain)
.distinct()
.count()
.get_result::<i64>(db_conn)
.await
.map(|count| count as u64)
with_statistics_mode(self.statistics_mode, async {
with_connection!(self.db_pool, |db_conn| {
accounts::table
.filter(accounts::local.eq(false))
.select(accounts::domain)
.distinct()
.count()
.get_result::<i64>(db_conn)
.await
.map(|count| count as u64)
})
.map_err(Error::from)
})
.map_err(Error::from)
.await
}

pub async fn local_post_count(&self) -> Result<u64> {
if self.randomize_statistics {
return Ok(random_statistic());
}

with_connection!(self.db_pool, |db_conn| {
posts::table
.filter(posts::is_local.eq(true))
.count()
.get_result::<i64>(db_conn)
.await
.map(|count| count as u64)
with_statistics_mode(self.statistics_mode, async {
with_connection!(self.db_pool, |db_conn| {
posts::table
.filter(posts::is_local.eq(true))
.count()
.get_result::<i64>(db_conn)
.await
.map(|count| count as u64)
})
.map_err(Error::from)
})
.map_err(Error::from)
.await
}

#[must_use]
Expand All @@ -85,17 +96,16 @@ impl InstanceService {
}

pub async fn user_count(&self) -> Result<u64> {
if self.randomize_statistics {
return Ok(random_statistic());
}

with_connection!(self.db_pool, |db_conn| {
users::table
.count()
.get_result::<i64>(db_conn)
.await
.map(|count| count as u64)
with_statistics_mode(self.statistics_mode, async {
with_connection!(self.db_pool, |db_conn| {
users::table
.count()
.get_result::<i64>(db_conn)
.await
.map(|count| count as u64)
})
.map_err(Error::from)
})
.map_err(Error::from)
.await
}
}
2 changes: 1 addition & 1 deletion kitsune/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ pub async fn initialise_state(
.db_pool(db_pool.clone())
.description(config.instance.description.clone())
.name(config.instance.name.clone())
.randomize_statistics(config.instance.randomize_statistics)
.registrations_open(config.instance.registrations_open)
.statistics_mode(config.instance.statistics_mode)
.build();

let mailing_service = MailingService::builder()
Expand Down
14 changes: 14 additions & 0 deletions website/src/content/docs/configuration/instance.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,20 @@ Similar to `name`, this setting adjusts the description on the landing page and

This setting sets the character limit specific to your instance.

## `statistics-mode`

Control how statistics about your server are reported.

Possible values:

- `regular`: Return accurate statistics read from the database
- `zero`: Set all the statistics to zero
- `random`: Set all the statistics to random values

The settings `zero` and `random` are great if you don't want crawlers to figure out how many people are on your instance.

<Aside type="caution">Booting your instance into `random` mode might upset techbros</Aside>

## `randomize-statistics`

Randomize the statistics of your server
Expand Down

0 comments on commit 0f7e347

Please sign in to comment.