Browse Source

Remove stuff from cache system

Since we are going to use matrix-sdk as the whole backend and it keeps
its state by itself and can drive the GUI, this clean up is needed to
wire up the support for that. Anyways, currently it doesn't store the
rooms at all.
fix-filtering
Alejandro Domínguez 6 years ago
parent
commit
752d6cc973
  1. 17
      Cargo.lock
  2. 11
      fractal-gtk/Cargo.toml
  3. 2
      fractal-gtk/src/appop/mod.rs
  4. 3
      fractal-gtk/src/appop/room.rs
  5. 44
      fractal-gtk/src/cache/mod.rs
  6. 67
      fractal-gtk/src/cache/state.rs
  7. 1
      fractal-gtk/src/globals.rs
  8. 6
      fractal-gtk/src/model/member.rs
  9. 3
      fractal-gtk/src/model/message.rs
  10. 10
      fractal-gtk/src/model/room.rs

17
Cargo.lock generated

@ -428,7 +428,6 @@ dependencies = [
"libc",
"num-integer",
"num-traits",
"serde",
"time 0.1.44",
"winapi 0.3.9",
]
@ -707,14 +706,6 @@ version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
[[package]]
name = "either"
version = "1.5.99"
source = "git+https://github.com/danigm/either.git?rev=60c99bc0723491e2dfd42bbe9b485c5f9323e96b#60c99bc0723491e2dfd42bbe9b485c5f9323e96b"
dependencies = [
"serde",
]
[[package]]
name = "either"
version = "1.6.1"
@ -785,7 +776,7 @@ dependencies = [
"comrak",
"directories",
"dirs",
"either 1.5.99",
"either",
"fragile",
"gdk",
"gdk-pixbuf",
@ -1698,7 +1689,7 @@ version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484"
dependencies = [
"either 1.6.1",
"either",
]
[[package]]
@ -1707,7 +1698,7 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
dependencies = [
"either 1.6.1",
"either",
]
[[package]]
@ -3663,7 +3654,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d611fd5d241872372d52a0a3d309c52d0b95a6a67671a6c8f7ab2c4a37fb2539"
dependencies = [
"bytes 0.4.12",
"either 1.6.1",
"either",
"futures",
"thiserror",
"tokio",

11
fractal-gtk/Cargo.toml

@ -9,9 +9,11 @@ edition = "2018"
anyhow = "1.0.32"
async-trait = "0.1.40"
clap = "2.33.0"
chrono = "0.4.10"
comrak = "0.7.0"
directories = "2.0.2"
dirs = "2.0.2"
either = "1.6.1"
fragile = "1.0.0"
gdk = "0.13.0"
gdk-pixbuf = "0.9.0"
@ -46,10 +48,6 @@ package = "gstreamer-player"
version = "0.9.1"
features = ["png"]
[dependencies.chrono]
version = "0.4.10"
features = ["serde"]
[dependencies.libhandy]
version = "0.7.1"
@ -70,11 +68,6 @@ features = ["derive"]
version = "0.9.0"
features = ["v2_56"]
[dependencies.either]
git = "https://github.com/danigm/either.git"
rev = "60c99bc0723491e2dfd42bbe9b485c5f9323e96b"
features = ["serde_untagged"]
[dependencies.tokio]
version = "0.2.22"
features = ["rt-threaded", "time"]

2
fractal-gtk/src/appop/mod.rs

@ -175,8 +175,6 @@ impl AppOp {
// FIXME: Username and uid should not be duplicated in cache.
let device_id = if let Ok(data) = cache::load() {
let r: Vec<Room> = data.rooms.values().cloned().collect();
self.set_rooms(r, true);
self.since = data.since.filter(|s| !s.is_empty());
Some(data.device_id)
} else {

3
fractal-gtk/src/appop/room.rs

@ -417,13 +417,12 @@ impl AppOp {
pub fn cache_rooms(&self) {
let login_data = unwrap_or_unit_return!(self.login_data.clone());
// serializing rooms
let rooms = self.rooms.clone();
let since = self.since.clone();
let username = login_data.username.unwrap_or_default();
let uid = login_data.uid;
let device_id = login_data.device_id;
if cache::store(&rooms, since, username, uid, device_id).is_err() {
if cache::store(since, username, uid, device_id).is_err() {
error!("Error caching rooms");
};
}

44
fractal-gtk/src/cache/mod.rs vendored

@ -4,17 +4,13 @@ use crate::backend::user;
use crate::util::cache_dir_path;
use gtk::LabelExt;
use matrix_sdk::Client as MatrixClient;
use serde::{Deserialize, Serialize};
use crate::model::room::{Room, RoomList};
use anyhow::Error;
use matrix_sdk::identifiers::{DeviceId, UserId};
use std::collections::HashMap;
use std::hash::Hash;
use std::time::{Duration, Instant};
use crate::globals;
use crate::widgets::AvatarData;
use std::cell::RefCell;
use std::rc::Rc;
@ -66,74 +62,40 @@ impl<K: Clone + Eq + Hash, V: Clone> CacheMap<K, V> {
}
}
// TODO: remove this struct
#[derive(Serialize, Deserialize)]
pub struct CacheData {
pub since: Option<String>,
pub rooms: RoomList,
pub username: String,
pub uid: UserId,
pub device_id: Box<DeviceId>,
}
pub fn store(
rooms: &RoomList,
since: Option<String>,
username: String,
uid: UserId,
device_id: Box<DeviceId>,
) -> Result<(), Error> {
// don't store all messages in the cache
let mut cacherooms: Vec<Room> = vec![];
for r in rooms.values() {
let mut r = r.clone();
let skip = match r.messages.len() {
n if n > globals::CACHE_SIZE => n - globals::CACHE_SIZE,
_ => 0,
};
r.messages = r.messages.iter().skip(skip).cloned().collect();
// setting prev_batch to none because we're removing some messages so the
// prev_batch isn't valid now, it's not pointing to the stored last msg
r.prev_batch = None;
cacherooms.push(r);
}
let st = AppState {
since,
username,
uid,
device_id,
};
get().save_st(st)?;
// This is slow because we iterate over all room msgs
// in the future we shouldn't do that, we should remove the
// Vec<Msg> from the room and treat messages as first level
// cache objects with something like cache.get_msgs(room),
// cache.get_msg(room_id, msg_id) and cache.save_msg(msg)
get().save_rooms(cacherooms)?;
get().save_st(st)?;
Ok(())
}
pub fn load() -> Result<CacheData, Error> {
let st = get().get_st()?;
let rooms = get().get_rooms()?;
let mut cacherooms: RoomList = HashMap::new();
for r in rooms {
cacherooms.insert(r.id.clone(), r);
}
let data = CacheData {
Ok(CacheData {
since: st.since,
username: st.username,
uid: st.uid,
device_id: st.device_id,
rooms: cacherooms,
};
Ok(data)
})
}
pub fn remove_from_cache(user_info_cache: UserInfoCache, user_id: &UserId) {

67
fractal-gtk/src/cache/state.rs vendored

@ -5,11 +5,9 @@ use serde::{Deserialize, Serialize};
use anyhow::{anyhow, Error};
use std::cell::RefCell;
use std::fs::remove_dir_all;
use std::sync::{Arc, Mutex, MutexGuard};
use crate::model::{message::Message, room::Room};
use crate::util::cache_dir_path;
use matrix_sdk::identifiers::{DeviceId, UserId};
@ -26,49 +24,13 @@ pub struct AppState {
pub device_id: Box<DeviceId>,
}
/// Backend Room model but without the list of messages
/// The list of messages is stored in cache with the Msg
/// struct and this struct defines a convenience method
/// to get a Vec<Msg>
#[derive(Serialize, Deserialize)]
pub struct AppRoom {
pub room: RefCell<Room>,
}
/// Message stored in the cache
#[derive(Serialize, Deserialize)]
pub struct AppMsg {
pub msg: Message,
}
impl Model for AppState {
fn key(&self) -> String {
"state".to_string()
}
}
impl Model for AppRoom {
fn key(&self) -> String {
format!("room:{}", self.room.borrow().id)
}
}
impl Model for AppMsg {
fn key(&self) -> String {
format!(
"msg:{}:{}",
self.msg.room,
self.msg
.id
.as_ref()
.map(|evid| evid.to_string())
.unwrap_or_default(),
)
}
}
// Cache
#[derive(Clone)]
pub struct FCache {
cache: Arc<Mutex<Option<Cache>>>,
@ -99,35 +61,6 @@ impl FCache {
remove_dir_all(fname).or_else(|_| Err(anyhow!("Can't remove cache file")))
}
pub fn get_rooms(&self) -> Result<Vec<Room>, Error> {
let cache = self.get_store();
let rooms = AppRoom::all(cache.as_ref().unwrap(), "room")?
.iter()
.map(|r| r.room.borrow().clone())
.collect();
Ok(rooms)
}
pub fn save_rooms(&self, rooms: Vec<Room>) -> Result<(), Error> {
for r in rooms {
self.save_room(r)?;
}
Ok(())
}
pub fn save_room(&self, room: Room) -> Result<(), Error> {
let cache = self.get_store();
let mut stored_room = room;
// Don't store typing notifications
stored_room.typing_users.clear();
let approom = AppRoom {
room: RefCell::new(stored_room),
};
approom.store(cache.as_ref().unwrap())?;
Ok(())
}
pub fn get_st(&self) -> Result<AppState, Error> {
let cache = self.get_store();
AppState::get(cache.as_ref().unwrap(), "state")

1
fractal-gtk/src/globals.rs

@ -9,7 +9,6 @@ pub const PAGE_LIMIT: u32 = 40;
pub const ROOM_DIRECTORY_LIMIT: u32 = 20;
pub const DEVICE_NAME: &str = "Fractal";
pub const CACHE_SIZE: usize = 40;
pub const MSG_ICON_SIZE: i32 = 40;
pub const USERLIST_ICON_SIZE: i32 = 30;
pub const PILL_ICON_SIZE: i32 = 18;

6
fractal-gtk/src/model/member.rs

@ -2,19 +2,15 @@ use either::Either;
use matrix_sdk::api::r0::membership::joined_members::RoomMember;
use matrix_sdk::api::r0::user_directory::search_users::User;
use matrix_sdk::identifiers::UserId;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::convert::TryFrom;
use std::path::PathBuf;
use url::{ParseError as UrlError, Url};
// TODO: Make this non-(de)serializable
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone)]
pub struct Member {
pub uid: UserId,
#[serde(rename = "display_name")]
pub alias: Option<String>,
#[serde(rename = "avatar_url")]
pub avatar: Option<Either<Url, PathBuf>>,
}

3
fractal-gtk/src/model/message.rs

@ -9,7 +9,6 @@ use matrix_sdk::{
},
identifiers::{EventId, RoomId, UserId},
};
use serde::{Deserialize, Serialize};
use serde_json::Value as JsonValue;
use std::cmp::Ordering;
use std::collections::HashMap;
@ -18,7 +17,7 @@ use std::path::PathBuf;
use url::Url;
//FIXME make properties private
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone)]
pub struct Message {
pub sender: UserId,
pub mtype: String,

10
fractal-gtk/src/model/room.rs

@ -20,7 +20,7 @@ use std::collections::{BTreeMap, HashMap, HashSet};
use std::convert::{TryFrom, TryInto};
use url::{ParseError as UrlError, Url};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[derive(Debug, Clone, PartialEq)]
pub enum RoomMembership {
// If the user hasn't yet joined a room, e.g. in the room directory
None,
@ -72,13 +72,15 @@ impl Default for RoomMembership {
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[derive(Debug, Clone, PartialEq)]
pub enum Reason {
None,
Kicked(String, UserId),
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
// This needs to opt-out of the lint to keep consistency
#[allow(dead_code)]
#[derive(Debug, Clone, PartialEq)]
pub enum RoomTag {
None,
Favourite,
@ -108,7 +110,7 @@ struct CustomDirectEvent {
_type: DirectType,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone)]
pub struct Room {
pub id: RoomId,
pub avatar: Option<Url>,

Loading…
Cancel
Save