cache local instance (#572)
* cache local instance fix #564 * don't use local instance cache for plm * use instance cache for plm, but initialize it * cargo fmt
This commit is contained in:
committed by
Baptiste Gelez
parent
5b50f90d2b
commit
773fbfe7c8
+18
-16
@@ -172,7 +172,7 @@ impl Blog {
|
||||
let mut icon = Image::default();
|
||||
icon.object_props.set_url_string(
|
||||
self.icon_id
|
||||
.and_then(|id| Media::get(conn, id).and_then(|m| m.url(conn)).ok())
|
||||
.and_then(|id| Media::get(conn, id).and_then(|m| m.url()).ok())
|
||||
.unwrap_or_default(),
|
||||
)?;
|
||||
icon.object_props.set_attributed_to_link(
|
||||
@@ -189,7 +189,7 @@ impl Blog {
|
||||
let mut banner = Image::default();
|
||||
banner.object_props.set_url_string(
|
||||
self.banner_id
|
||||
.and_then(|id| Media::get(conn, id).and_then(|m| m.url(conn)).ok())
|
||||
.and_then(|id| Media::get(conn, id).and_then(|m| m.url()).ok())
|
||||
.unwrap_or_default(),
|
||||
)?;
|
||||
banner.object_props.set_attributed_to_link(
|
||||
@@ -271,14 +271,14 @@ impl Blog {
|
||||
|
||||
pub fn icon_url(&self, conn: &Connection) -> String {
|
||||
self.icon_id
|
||||
.and_then(|id| Media::get(conn, id).and_then(|m| m.url(conn)).ok())
|
||||
.and_then(|id| Media::get(conn, id).and_then(|m| m.url()).ok())
|
||||
.unwrap_or_else(|| "/static/default-avatar.png".to_string())
|
||||
}
|
||||
|
||||
pub fn banner_url(&self, conn: &Connection) -> Option<String> {
|
||||
self.banner_id
|
||||
.and_then(|i| Media::get(conn, i).ok())
|
||||
.and_then(|c| c.url(conn).ok())
|
||||
.and_then(|c| c.url().ok())
|
||||
}
|
||||
|
||||
pub fn delete(&self, conn: &Connection, searcher: &Searcher) -> Result<()> {
|
||||
@@ -407,7 +407,9 @@ impl AsActor<&PlumeRocket> for Blog {
|
||||
}
|
||||
|
||||
fn is_local(&self) -> bool {
|
||||
self.instance_id == 1 // TODO: this is not always true
|
||||
Instance::get_local()
|
||||
.map(|i| self.instance_id == i.id)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -474,7 +476,7 @@ pub(crate) mod tests {
|
||||
"BlogName".to_owned(),
|
||||
"Blog name".to_owned(),
|
||||
"This is a small blog".to_owned(),
|
||||
Instance::get_local(conn).unwrap().id,
|
||||
Instance::get_local().unwrap().id,
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
@@ -485,7 +487,7 @@ pub(crate) mod tests {
|
||||
"MyBlog".to_owned(),
|
||||
"My blog".to_owned(),
|
||||
"Welcome to my blog".to_owned(),
|
||||
Instance::get_local(conn).unwrap().id,
|
||||
Instance::get_local().unwrap().id,
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
@@ -496,7 +498,7 @@ pub(crate) mod tests {
|
||||
"WhyILikePlume".to_owned(),
|
||||
"Why I like Plume".to_owned(),
|
||||
"In this blog I will explay you why I like Plume so much".to_owned(),
|
||||
Instance::get_local(conn).unwrap().id,
|
||||
Instance::get_local().unwrap().id,
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
@@ -556,7 +558,7 @@ pub(crate) mod tests {
|
||||
"SomeName".to_owned(),
|
||||
"Some name".to_owned(),
|
||||
"This is some blog".to_owned(),
|
||||
Instance::get_local(conn).unwrap().id,
|
||||
Instance::get_local().unwrap().id,
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
@@ -564,7 +566,7 @@ pub(crate) mod tests {
|
||||
|
||||
assert_eq!(
|
||||
blog.get_instance(conn).unwrap().id,
|
||||
Instance::get_local(conn).unwrap().id
|
||||
Instance::get_local().unwrap().id
|
||||
);
|
||||
// TODO add tests for remote instance
|
||||
|
||||
@@ -584,7 +586,7 @@ pub(crate) mod tests {
|
||||
"SomeName".to_owned(),
|
||||
"Some name".to_owned(),
|
||||
"This is some blog".to_owned(),
|
||||
Instance::get_local(conn).unwrap().id,
|
||||
Instance::get_local().unwrap().id,
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
@@ -595,7 +597,7 @@ pub(crate) mod tests {
|
||||
"Blog".to_owned(),
|
||||
"Blog".to_owned(),
|
||||
"I've named my blog Blog".to_owned(),
|
||||
Instance::get_local(conn).unwrap().id,
|
||||
Instance::get_local().unwrap().id,
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
@@ -687,7 +689,7 @@ pub(crate) mod tests {
|
||||
"SomeName".to_owned(),
|
||||
"Some name".to_owned(),
|
||||
"This is some blog".to_owned(),
|
||||
Instance::get_local(conn).unwrap().id,
|
||||
Instance::get_local().unwrap().id,
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
@@ -711,7 +713,7 @@ pub(crate) mod tests {
|
||||
"SomeName".to_owned(),
|
||||
"Some name".to_owned(),
|
||||
"This is some blog".to_owned(),
|
||||
Instance::get_local(conn).unwrap().id,
|
||||
Instance::get_local().unwrap().id,
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
@@ -749,7 +751,7 @@ pub(crate) mod tests {
|
||||
"SomeName".to_owned(),
|
||||
"Some name".to_owned(),
|
||||
"This is some blog".to_owned(),
|
||||
Instance::get_local(conn).unwrap().id,
|
||||
Instance::get_local().unwrap().id,
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
@@ -760,7 +762,7 @@ pub(crate) mod tests {
|
||||
"Blog".to_owned(),
|
||||
"Blog".to_owned(),
|
||||
"I've named my blog Blog".to_owned(),
|
||||
Instance::get_local(conn).unwrap().id,
|
||||
Instance::get_local().unwrap().id,
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
|
||||
@@ -79,7 +79,7 @@ impl Comment {
|
||||
pub fn count_local(conn: &Connection) -> Result<i64> {
|
||||
use schema::users;
|
||||
let local_authors = users::table
|
||||
.filter(users::instance_id.eq(Instance::get_local(conn)?.id))
|
||||
.filter(users::instance_id.eq(Instance::get_local()?.id))
|
||||
.select(users::id);
|
||||
comments::table
|
||||
.filter(comments::author_id.eq_any(local_authors))
|
||||
@@ -107,7 +107,7 @@ impl Comment {
|
||||
let author = User::get(&c.conn, self.author_id)?;
|
||||
let (html, mentions, _hashtags) = utils::md_to_html(
|
||||
self.content.get().as_ref(),
|
||||
Some(&Instance::get_local(&c.conn)?.public_domain),
|
||||
Some(&Instance::get_local()?.public_domain),
|
||||
true,
|
||||
Some(Media::get_media_processor(&c.conn, vec![&author])),
|
||||
);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use chrono::NaiveDateTime;
|
||||
use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl};
|
||||
use std::iter::Iterator;
|
||||
use std::sync::RwLock;
|
||||
|
||||
use ap_url;
|
||||
use medias::Media;
|
||||
@@ -40,8 +41,24 @@ pub struct NewInstance {
|
||||
pub short_description_html: String,
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref LOCAL_INSTANCE: RwLock<Option<Instance>> = RwLock::new(None);
|
||||
}
|
||||
|
||||
impl Instance {
|
||||
pub fn get_local(conn: &Connection) -> Result<Instance> {
|
||||
pub fn set_local(self) {
|
||||
LOCAL_INSTANCE.write().unwrap().replace(self);
|
||||
}
|
||||
|
||||
pub fn get_local() -> Result<Instance> {
|
||||
LOCAL_INSTANCE
|
||||
.read()
|
||||
.unwrap()
|
||||
.clone()
|
||||
.ok_or(Error::NotFound)
|
||||
}
|
||||
|
||||
pub fn get_local_uncached(conn: &Connection) -> Result<Instance> {
|
||||
instances::table
|
||||
.filter(instances::local.eq(true))
|
||||
.limit(1)
|
||||
@@ -51,6 +68,10 @@ impl Instance {
|
||||
.ok_or(Error::NotFound)
|
||||
}
|
||||
|
||||
pub fn cache_local(conn: &Connection) {
|
||||
*LOCAL_INSTANCE.write().unwrap() = Instance::get_local_uncached(conn).ok();
|
||||
}
|
||||
|
||||
pub fn get_remotes(conn: &Connection) -> Result<Vec<Instance>> {
|
||||
instances::table
|
||||
.filter(instances::local.eq(false))
|
||||
@@ -141,7 +162,7 @@ impl Instance {
|
||||
false,
|
||||
Some(Media::get_media_processor(conn, vec![])),
|
||||
);
|
||||
diesel::update(self)
|
||||
let res = diesel::update(self)
|
||||
.set((
|
||||
instances::name.eq(name),
|
||||
instances::open_registrations.eq(open_registrations),
|
||||
@@ -152,7 +173,11 @@ impl Instance {
|
||||
))
|
||||
.execute(conn)
|
||||
.map(|_| ())
|
||||
.map_err(Error::from)
|
||||
.map_err(Error::from);
|
||||
if self.local {
|
||||
Instance::cache_local(conn);
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
pub fn count(conn: &Connection) -> Result<i64> {
|
||||
@@ -171,7 +196,7 @@ pub(crate) mod tests {
|
||||
use Connection as Conn;
|
||||
|
||||
pub(crate) fn fill_database(conn: &Conn) -> Vec<(NewInstance, Instance)> {
|
||||
vec![
|
||||
let res = vec![
|
||||
NewInstance {
|
||||
default_license: "WTFPL".to_string(),
|
||||
local: true,
|
||||
@@ -225,7 +250,9 @@ pub(crate) mod tests {
|
||||
.unwrap_or_else(|_| Instance::insert(conn, inst).unwrap()),
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
.collect();
|
||||
Instance::cache_local(conn);
|
||||
res
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -237,7 +264,7 @@ pub(crate) mod tests {
|
||||
.map(|(inserted, _)| inserted)
|
||||
.find(|inst| inst.local)
|
||||
.unwrap();
|
||||
let res = Instance::get_local(conn).unwrap();
|
||||
let res = Instance::get_local().unwrap();
|
||||
|
||||
part_eq!(
|
||||
res,
|
||||
|
||||
@@ -104,8 +104,8 @@ impl Media {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn html(&self, conn: &Connection) -> Result<SafeString> {
|
||||
let url = self.url(conn)?;
|
||||
pub fn html(&self) -> Result<SafeString> {
|
||||
let url = self.url()?;
|
||||
Ok(match self.category() {
|
||||
MediaCategory::Image => SafeString::trusted(&format!(
|
||||
r#"<img src="{}" alt="{}" title="{}">"#,
|
||||
@@ -126,23 +126,23 @@ impl Media {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn markdown(&self, conn: &Connection) -> Result<SafeString> {
|
||||
pub fn markdown(&self) -> Result<SafeString> {
|
||||
Ok(match self.category() {
|
||||
MediaCategory::Image => {
|
||||
SafeString::new(&format!("", escape(&self.alt_text), self.id))
|
||||
}
|
||||
MediaCategory::Audio | MediaCategory::Video => self.html(conn)?,
|
||||
MediaCategory::Audio | MediaCategory::Video => self.html()?,
|
||||
MediaCategory::Unknown => SafeString::new(""),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn url(&self, conn: &Connection) -> Result<String> {
|
||||
pub fn url(&self) -> Result<String> {
|
||||
if self.is_remote {
|
||||
Ok(self.remote_url.clone().unwrap_or_default())
|
||||
} else {
|
||||
Ok(ap_url(&format!(
|
||||
"{}/{}",
|
||||
Instance::get_local(conn)?.public_domain,
|
||||
Instance::get_local()?.public_domain,
|
||||
self.file_path
|
||||
)))
|
||||
}
|
||||
@@ -237,7 +237,7 @@ impl Media {
|
||||
let media = Media::get(conn, id).ok()?;
|
||||
// if owner is user or check is disabled
|
||||
if uid.contains(&media.owner_id) || uid.is_empty() {
|
||||
Some((media.url(conn).ok()?, media.content_warning))
|
||||
Some((media.url().ok()?, media.content_warning))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ impl Post {
|
||||
use schema::post_authors;
|
||||
use schema::users;
|
||||
let local_authors = users::table
|
||||
.filter(users::instance_id.eq(Instance::get_local(conn)?.id))
|
||||
.filter(users::instance_id.eq(Instance::get_local()?.id))
|
||||
.select(users::id);
|
||||
let local_posts_id = post_authors::table
|
||||
.filter(post_authors::author_id.eq_any(local_authors))
|
||||
@@ -384,7 +384,7 @@ impl Post {
|
||||
.collect::<Vec<serde_json::Value>>();
|
||||
let mut tags_json = Tag::for_post(conn, self.id)?
|
||||
.into_iter()
|
||||
.map(|t| json!(t.to_activity(conn).ok()))
|
||||
.map(|t| json!(t.to_activity().ok()))
|
||||
.collect::<Vec<serde_json::Value>>();
|
||||
mentions_json.append(&mut tags_json);
|
||||
|
||||
@@ -419,7 +419,7 @@ impl Post {
|
||||
if let Some(media_id) = self.cover_id {
|
||||
let media = Media::get(conn, media_id)?;
|
||||
let mut cover = Image::default();
|
||||
cover.object_props.set_url_string(media.url(conn)?)?;
|
||||
cover.object_props.set_url_string(media.url()?)?;
|
||||
if media.sensitive {
|
||||
cover
|
||||
.object_props
|
||||
@@ -603,7 +603,7 @@ impl Post {
|
||||
pub fn cover_url(&self, conn: &Connection) -> Option<String> {
|
||||
self.cover_id
|
||||
.and_then(|i| Media::get(conn, i).ok())
|
||||
.and_then(|c| c.url(conn).ok())
|
||||
.and_then(|c| c.url().ok())
|
||||
}
|
||||
|
||||
pub fn build_delete(&self, conn: &Connection) -> Result<Delete> {
|
||||
|
||||
@@ -27,11 +27,11 @@ impl Tag {
|
||||
find_by!(tags, find_by_name, tag as &str);
|
||||
list_by!(tags, for_post, post_id as i32);
|
||||
|
||||
pub fn to_activity(&self, conn: &Connection) -> Result<Hashtag> {
|
||||
pub fn to_activity(&self) -> Result<Hashtag> {
|
||||
let mut ht = Hashtag::default();
|
||||
ht.set_href_string(ap_url(&format!(
|
||||
"{}/tag/{}",
|
||||
Instance::get_local(conn)?.public_domain,
|
||||
Instance::get_local()?.public_domain,
|
||||
self.tag
|
||||
)))?;
|
||||
ht.set_name_string(self.tag.clone())?;
|
||||
@@ -54,11 +54,11 @@ impl Tag {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn build_activity(conn: &Connection, tag: String) -> Result<Hashtag> {
|
||||
pub fn build_activity(tag: String) -> Result<Hashtag> {
|
||||
let mut ht = Hashtag::default();
|
||||
ht.set_href_string(ap_url(&format!(
|
||||
"{}/tag/{}",
|
||||
Instance::get_local(conn)?.public_domain,
|
||||
Instance::get_local()?.public_domain,
|
||||
tag
|
||||
)))?;
|
||||
ht.set_name_string(tag)?;
|
||||
|
||||
@@ -228,7 +228,7 @@ impl User {
|
||||
|
||||
pub fn count_local(conn: &Connection) -> Result<i64> {
|
||||
users::table
|
||||
.filter(users::instance_id.eq(Instance::get_local(conn)?.id))
|
||||
.filter(users::instance_id.eq(Instance::get_local()?.id))
|
||||
.count()
|
||||
.get_result(conn)
|
||||
.map_err(Error::from)
|
||||
@@ -353,7 +353,7 @@ impl User {
|
||||
|
||||
pub fn get_local_page(conn: &Connection, (min, max): (i32, i32)) -> Result<Vec<User>> {
|
||||
users::table
|
||||
.filter(users::instance_id.eq(Instance::get_local(conn)?.id))
|
||||
.filter(users::instance_id.eq(Instance::get_local()?.id))
|
||||
.order(users::username.asc())
|
||||
.offset(min.into())
|
||||
.limit((max - min).into())
|
||||
@@ -634,7 +634,7 @@ impl User {
|
||||
let mut avatar = Image::default();
|
||||
avatar.object_props.set_url_string(
|
||||
self.avatar_id
|
||||
.and_then(|id| Media::get(conn, id).and_then(|m| m.url(conn)).ok())
|
||||
.and_then(|id| Media::get(conn, id).and_then(|m| m.url()).ok())
|
||||
.unwrap_or_default(),
|
||||
)?;
|
||||
actor.object_props.set_icon_object(avatar)?;
|
||||
@@ -667,7 +667,7 @@ impl User {
|
||||
|
||||
pub fn avatar_url(&self, conn: &Connection) -> String {
|
||||
self.avatar_id
|
||||
.and_then(|id| Media::get(conn, id).and_then(|m| m.url(conn)).ok())
|
||||
.and_then(|id| Media::get(conn, id).and_then(|m| m.url()).ok())
|
||||
.unwrap_or_else(|| "/static/default-avatar.png".to_string())
|
||||
}
|
||||
|
||||
@@ -861,7 +861,9 @@ impl AsActor<&PlumeRocket> for User {
|
||||
}
|
||||
|
||||
fn is_local(&self) -> bool {
|
||||
self.instance_id == 1
|
||||
Instance::get_local()
|
||||
.map(|i| self.instance_id == i.id)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -934,7 +936,7 @@ impl NewUser {
|
||||
summary_html: SafeString::new(&utils::md_to_html(&summary, None, false, None).0),
|
||||
email: Some(email),
|
||||
hashed_password: Some(password),
|
||||
instance_id: Instance::get_local(conn)?.id,
|
||||
instance_id: Instance::get_local()?.id,
|
||||
ap_url: String::new(),
|
||||
public_key: String::from_utf8(pub_key).or(Err(Error::Signature))?,
|
||||
private_key: Some(String::from_utf8(priv_key).or(Err(Error::Signature))?),
|
||||
@@ -1007,7 +1009,7 @@ pub(crate) mod tests {
|
||||
|
||||
assert_eq!(
|
||||
test_user.id,
|
||||
User::find_by_name(conn, "test", Instance::get_local(conn).unwrap().id)
|
||||
User::find_by_name(conn, "test", Instance::get_local().unwrap().id)
|
||||
.unwrap()
|
||||
.id
|
||||
);
|
||||
@@ -1025,7 +1027,7 @@ pub(crate) mod tests {
|
||||
conn,
|
||||
&format!(
|
||||
"https://{}/@/{}/",
|
||||
Instance::get_local(conn).unwrap().public_domain,
|
||||
Instance::get_local().unwrap().public_domain,
|
||||
"test"
|
||||
)
|
||||
)
|
||||
@@ -1056,7 +1058,7 @@ pub(crate) mod tests {
|
||||
let conn = &db();
|
||||
conn.test_transaction::<_, (), _>(|| {
|
||||
let inserted = fill_database(conn);
|
||||
let local_inst = Instance::get_local(conn).unwrap();
|
||||
let local_inst = Instance::get_local().unwrap();
|
||||
let mut i = 0;
|
||||
while local_inst.has_admin(conn).unwrap() {
|
||||
assert!(i < 100); //prevent from looping indefinitelly
|
||||
|
||||
Reference in New Issue
Block a user