mirror of https://github.com/LemmyNet/lemmy.git
Compare commits
8 Commits
ce186fdab4
...
f56a9918ab
Author | SHA1 | Date |
---|---|---|
![]() |
f56a9918ab | |
![]() |
b4f9ef24a5 | |
![]() |
866d752a3c | |
![]() |
e0b1d0553d | |
![]() |
691bce0e71 | |
![]() |
f2a6d73682 | |
![]() |
277524298b | |
![]() |
ca271eacf5 |
File diff suppressed because it is too large
Load Diff
|
@ -20,7 +20,8 @@ use lemmy_db_schema::{
|
||||||
};
|
};
|
||||||
use lemmy_utils::error::{LemmyErrorType, LemmyResult};
|
use lemmy_utils::error::{LemmyErrorType, LemmyResult};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::ops::Deref;
|
use std::{ops::Deref, time::Duration};
|
||||||
|
use tokio::time::timeout;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
mod comment;
|
mod comment;
|
||||||
|
@ -30,13 +31,22 @@ mod post;
|
||||||
pub mod routes;
|
pub mod routes;
|
||||||
pub mod site;
|
pub mod site;
|
||||||
|
|
||||||
|
const INCOMING_ACTIVITY_TIMEOUT: Duration = Duration::from_secs(9);
|
||||||
|
|
||||||
pub async fn shared_inbox(
|
pub async fn shared_inbox(
|
||||||
request: HttpRequest,
|
request: HttpRequest,
|
||||||
body: Bytes,
|
body: Bytes,
|
||||||
data: Data<LemmyContext>,
|
data: Data<LemmyContext>,
|
||||||
) -> LemmyResult<HttpResponse> {
|
) -> LemmyResult<HttpResponse> {
|
||||||
receive_activity::<SharedInboxActivities, UserOrCommunity, LemmyContext>(request, body, &data)
|
let receive_fut =
|
||||||
|
receive_activity::<SharedInboxActivities, UserOrCommunity, LemmyContext>(request, body, &data);
|
||||||
|
// Set a timeout shorter than `REQWEST_TIMEOUT` for processing incoming activities. This is to
|
||||||
|
// avoid taking a long time to process an incoming activity when a required data fetch times out.
|
||||||
|
// In this case our own instance would timeout and be marked as dead by the sender. Better to
|
||||||
|
// consider the activity broken and move on.
|
||||||
|
timeout(INCOMING_ACTIVITY_TIMEOUT, receive_fut)
|
||||||
.await
|
.await
|
||||||
|
.map_err(|_| LemmyErrorType::InboxTimeout)?
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert the data to json and turn it into an HTTP Response with the correct ActivityPub
|
/// Convert the data to json and turn it into an HTTP Response with the correct ActivityPub
|
||||||
|
|
|
@ -100,7 +100,7 @@ impl Object for ApubSite {
|
||||||
kind: ApplicationType::Application,
|
kind: ApplicationType::Application,
|
||||||
id: self.id().into(),
|
id: self.id().into(),
|
||||||
name: self.name.clone(),
|
name: self.name.clone(),
|
||||||
preferred_username: data.domain().to_string(),
|
preferred_username: Some(data.domain().to_string()),
|
||||||
content: self.sidebar.as_ref().map(|d| markdown_to_html(d)),
|
content: self.sidebar.as_ref().map(|d| markdown_to_html(d)),
|
||||||
source: self.sidebar.clone().map(Source::new),
|
source: self.sidebar.clone().map(Source::new),
|
||||||
summary: self.description.clone(),
|
summary: self.description.clone(),
|
||||||
|
|
|
@ -22,7 +22,7 @@ pub struct Instance {
|
||||||
/// site name
|
/// site name
|
||||||
pub(crate) name: String,
|
pub(crate) name: String,
|
||||||
/// instance domain, necessary for mastodon authorized fetch
|
/// instance domain, necessary for mastodon authorized fetch
|
||||||
pub(crate) preferred_username: String,
|
pub(crate) preferred_username: Option<String>,
|
||||||
pub(crate) inbox: Url,
|
pub(crate) inbox: Url,
|
||||||
/// mandatory field in activitypub, lemmy currently serves an empty outbox
|
/// mandatory field in activitypub, lemmy currently serves an empty outbox
|
||||||
pub(crate) outbox: Url,
|
pub(crate) outbox: Url,
|
||||||
|
|
|
@ -800,6 +800,12 @@ diesel::table! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
previously_run_sql (content) {
|
||||||
|
content -> Text,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
diesel::table! {
|
diesel::table! {
|
||||||
private_message (id) {
|
private_message (id) {
|
||||||
id -> Int4,
|
id -> Int4,
|
||||||
|
|
|
@ -9,15 +9,6 @@ const MIGRATIONS: EmbeddedMigrations = embed_migrations!();
|
||||||
/// This SQL code sets up the `r` schema, which contains things that can be safely dropped and replaced
|
/// This SQL code sets up the `r` schema, which contains things that can be safely dropped and replaced
|
||||||
/// instead of being changed using migrations. It may not create or modify things outside of the `r` schema
|
/// instead of being changed using migrations. It may not create or modify things outside of the `r` schema
|
||||||
/// (indicated by `r.` before the name), unless a comment says otherwise.
|
/// (indicated by `r.` before the name), unless a comment says otherwise.
|
||||||
///
|
|
||||||
/// Currently, this code is only run after the server starts and there's at least 1 pending migration
|
|
||||||
/// to run. This means every time you change something here, you must also create a migration (a blank
|
|
||||||
/// up.sql file works fine). This behavior will be removed when we implement a better way to avoid
|
|
||||||
/// useless schema updates and locks.
|
|
||||||
///
|
|
||||||
/// If you add something that depends on something (such as a table) created in a new migration, then down.sql
|
|
||||||
/// must use `CASCADE` when dropping it. This doesn't need to be fixed in old migrations because the
|
|
||||||
/// "replaceable-schema" migration runs `DROP SCHEMA IF EXISTS r CASCADE` in down.sql.
|
|
||||||
const REPLACEABLE_SCHEMA: &[&str] = &[
|
const REPLACEABLE_SCHEMA: &[&str] = &[
|
||||||
"DROP SCHEMA IF EXISTS r CASCADE;",
|
"DROP SCHEMA IF EXISTS r CASCADE;",
|
||||||
"CREATE SCHEMA r;",
|
"CREATE SCHEMA r;",
|
||||||
|
@ -26,17 +17,25 @@ const REPLACEABLE_SCHEMA: &[&str] = &[
|
||||||
];
|
];
|
||||||
|
|
||||||
pub fn run(db_url: &str) -> Result<(), LemmyError> {
|
pub fn run(db_url: &str) -> Result<(), LemmyError> {
|
||||||
|
let test_enabled = std::env::var("LEMMY_TEST_MIGRATIONS")
|
||||||
|
.map(|s| !s.is_empty())
|
||||||
|
.unwrap_or(false);
|
||||||
|
|
||||||
// Migrations don't support async connection
|
// Migrations don't support async connection
|
||||||
let mut conn = PgConnection::establish(db_url).with_context(|| "Error connecting to database")?;
|
let mut conn = PgConnection::establish(db_url).with_context(|| "Error connecting to database")?;
|
||||||
|
|
||||||
// Run all pending migrations except for the newest one, then run the newest one in the same transaction
|
|
||||||
// as `REPLACEABLE_SCHEMA`. This code will be becone less hacky when the conditional setup of things in
|
|
||||||
// `REPLACEABLE_SCHEMA` is done without using the number of pending migrations.
|
|
||||||
info!("Running Database migrations (This may take a long time)...");
|
info!("Running Database migrations (This may take a long time)...");
|
||||||
let migrations = conn
|
|
||||||
|
let unfiltered_migrations = conn
|
||||||
.pending_migrations(MIGRATIONS)
|
.pending_migrations(MIGRATIONS)
|
||||||
.map_err(|e| anyhow::anyhow!("Couldn't determine pending migrations: {e}"))?;
|
.map_err(|e| anyhow::anyhow!("Couldn't determine pending migrations: {e}"))?;
|
||||||
for migration in migrations.iter().rev().skip(1).rev() {
|
|
||||||
|
// Does not include the "forbid_diesel_cli" migration
|
||||||
|
let migrations = unfiltered_migrations.iter().filter(|m| m.name().version() != "000000000000000".into());
|
||||||
|
|
||||||
|
conn.transaction::<_, LemmyError, _>(|conn|) // left off here
|
||||||
|
|
||||||
|
for migration in migrations.clone() {
|
||||||
conn
|
conn
|
||||||
.run_migration(migration)
|
.run_migration(migration)
|
||||||
.map_err(|e| anyhow::anyhow!("Couldn't run DB Migrations: {e}"))?;
|
.map_err(|e| anyhow::anyhow!("Couldn't run DB Migrations: {e}"))?;
|
||||||
|
|
|
@ -175,6 +175,7 @@ pub enum LemmyErrorType {
|
||||||
InvalidBotAction,
|
InvalidBotAction,
|
||||||
CantBlockLocalInstance,
|
CantBlockLocalInstance,
|
||||||
UrlWithoutDomain,
|
UrlWithoutDomain,
|
||||||
|
InboxTimeout,
|
||||||
Unknown(String),
|
Unknown(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
RAISE NOTICE 'migrations must be managed using lemmy_server instead of diesel CLI';
|
||||||
|
END
|
||||||
|
$$;
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
drop table previously_run_sql;
|
|
@ -0,0 +1,4 @@
|
||||||
|
drop schema if exists r cascade;
|
||||||
|
create table previously_run_sql (content text primary key);
|
||||||
|
insert into previously_run_sql (content) values ('');
|
||||||
|
|
|
@ -160,10 +160,10 @@ pub async fn start_lemmy_server(args: CmdArgs) -> LemmyResult<()> {
|
||||||
rate_limit_cell.clone(),
|
rate_limit_cell.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
if !args.disable_scheduled_tasks {
|
let scheduled_tasks = (!args.disable_scheduled_tasks).then(|| {
|
||||||
// Schedules various cleanup tasks for the DB
|
// Schedules various cleanup tasks for the DB
|
||||||
let _scheduled_tasks = tokio::task::spawn(scheduled_tasks::setup(context.clone()));
|
tokio::task::spawn(scheduled_tasks::setup(context.clone()))
|
||||||
}
|
});
|
||||||
|
|
||||||
if let Some(prometheus) = SETTINGS.prometheus.clone() {
|
if let Some(prometheus) = SETTINGS.prometheus.clone() {
|
||||||
serve_prometheus(prometheus, context.clone())?;
|
serve_prometheus(prometheus, context.clone())?;
|
||||||
|
@ -218,7 +218,7 @@ pub async fn start_lemmy_server(args: CmdArgs) -> LemmyResult<()> {
|
||||||
let mut interrupt = tokio::signal::unix::signal(SignalKind::interrupt())?;
|
let mut interrupt = tokio::signal::unix::signal(SignalKind::interrupt())?;
|
||||||
let mut terminate = tokio::signal::unix::signal(SignalKind::terminate())?;
|
let mut terminate = tokio::signal::unix::signal(SignalKind::terminate())?;
|
||||||
|
|
||||||
if server.is_some() || federate.is_some() {
|
if server.is_some() || federate.is_some() || scheduled_tasks.is_some() {
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
_ = tokio::signal::ctrl_c() => {
|
_ = tokio::signal::ctrl_c() => {
|
||||||
tracing::warn!("Received ctrl-c, shutting down gracefully...");
|
tracing::warn!("Received ctrl-c, shutting down gracefully...");
|
||||||
|
|
Loading…
Reference in New Issue