[fractal] API: remove thread_pool and user_info_cache from BackendData



commit 61141e8b1208e1a4258007d61a5ccc4567018e6c
Author: Alejandro Domínguez <adomu net-c com>
Date:   Fri Jun 12 06:07:26 2020 +0200

    API: remove thread_pool and user_info_cache from BackendData

 fractal-gtk/src/actions/message.rs       | 11 ++--
 fractal-gtk/src/appop/account.rs         |  3 +-
 fractal-gtk/src/appop/media_viewer.rs    |  5 +-
 fractal-gtk/src/appop/message.rs         | 30 ++++++++--
 fractal-gtk/src/appop/mod.rs             | 12 ++++
 fractal-gtk/src/appop/notify.rs          | 10 ++--
 fractal-gtk/src/appop/room.rs            |  7 ++-
 fractal-gtk/src/appop/user.rs            |  6 +-
 fractal-gtk/src/cache/mod.rs             |  9 ++-
 fractal-gtk/src/widgets/image.rs         | 19 +++++--
 fractal-gtk/src/widgets/inline_player.rs | 14 ++---
 fractal-gtk/src/widgets/media_viewer.rs  | 96 +++++++++++++++++++-------------
 fractal-gtk/src/widgets/member.rs        | 20 +++++--
 fractal-gtk/src/widgets/message.rs       | 96 ++++++++++++++++++++++----------
 fractal-gtk/src/widgets/room_history.rs  | 70 ++++++++++++++++++-----
 fractal-matrix-api/src/backend/media.rs  | 25 ++++++---
 fractal-matrix-api/src/backend/mod.rs    | 45 +--------------
 fractal-matrix-api/src/backend/types.rs  | 19 +------
 fractal-matrix-api/src/backend/user.rs   | 65 ++++++---------------
 fractal-matrix-api/src/cache.rs          | 15 ++---
 20 files changed, 329 insertions(+), 248 deletions(-)
---
diff --git a/fractal-gtk/src/actions/message.rs b/fractal-gtk/src/actions/message.rs
index b0174602..938b246b 100644
--- a/fractal-gtk/src/actions/message.rs
+++ b/fractal-gtk/src/actions/message.rs
@@ -1,4 +1,4 @@
-use fractal_api::backend::room;
+use fractal_api::backend::{media, room, ThreadPool};
 use fractal_api::clone;
 use fractal_api::identifiers::RoomId;
 use fractal_api::r0::AccessToken;
@@ -37,6 +37,7 @@ use crate::widgets::SourceDialog;
 
 /* This creates all actions the room history can perform */
 pub fn new(
+    thread_pool: ThreadPool,
     backend: Sender<BKCommand>,
     server_url: Url,
     access_token: AccessToken,
@@ -145,15 +146,14 @@ pub fn new(
         }
     }));
 
-    let b = backend.clone();
     let parent_weak = parent.downgrade();
-    save_as.connect_activate(clone!(server_url => move |_, data| {
+    save_as.connect_activate(clone!(server_url, thread_pool => move |_, data| {
         if let Some(m) = get_message(data) {
             let name = m.body;
             let url = m.url.unwrap_or_default();
 
             let (tx, rx): (Sender<Result<String, Error>>, Receiver<Result<String, Error>>) = channel();
-            let _ = b.send(BKCommand::GetMediaAsync(server_url.clone(), url, tx));
+            media::get_media_async(thread_pool.clone(), server_url.clone(), url, tx);
 
             let parent_weak = parent_weak.clone();
             gtk::timeout_add(
@@ -185,7 +185,6 @@ pub fn new(
         }
     }));
 
-    let b = backend.clone();
     copy_image.connect_activate(clone!(server_url => move |_, data| {
         if let Some(m) = get_message(data) {
             let url = m.url.unwrap_or_default();
@@ -195,7 +194,7 @@ pub fn new(
                 Receiver<Result<String, Error>>,
             ) = channel();
 
-            let _ = b.send(BKCommand::GetMediaAsync(server_url.clone(), url.clone(), tx));
+            media::get_media_async(thread_pool.clone(), server_url.clone(), url, tx);
 
             gtk::timeout_add(50, move || match rx.try_recv() {
                 Err(TryRecvError::Empty) => Continue(true),
diff --git a/fractal-gtk/src/appop/account.rs b/fractal-gtk/src/appop/account.rs
index e5cc58a8..ce331a96 100644
--- a/fractal-gtk/src/appop/account.rs
+++ b/fractal-gtk/src/appop/account.rs
@@ -561,7 +561,8 @@ impl AppOp {
             None,
         );
         download_to_cache(
-            self.backend.clone(),
+            self.thread_pool.clone(),
+            self.user_info_cache.clone(),
             login_data.server_url,
             login_data.uid,
             data.clone(),
diff --git a/fractal-gtk/src/appop/media_viewer.rs b/fractal-gtk/src/appop/media_viewer.rs
index ab8d84c4..09eaf452 100644
--- a/fractal-gtk/src/appop/media_viewer.rs
+++ b/fractal-gtk/src/appop/media_viewer.rs
@@ -45,13 +45,14 @@ impl AppOp {
                 login_data.access_token,
                 login_data.uid,
             );
-            panel.display_media_viewer(msg);
-            let (body, header) = panel.create()?;
+            panel.display_media_viewer(self.thread_pool.clone(), msg);
+            let (body, header) = panel.create(self.thread_pool.clone())?;
             *self.media_viewer.borrow_mut() = Some(panel);
 
             if let Some(login_data) = self.login_data.clone() {
                 let back_history = self.room_back_history.clone();
                 let actions = actions::Message::new(
+                    self.thread_pool.clone(),
                     self.backend.clone(),
                     login_data.server_url,
                     login_data.access_token,
diff --git a/fractal-gtk/src/appop/message.rs b/fractal-gtk/src/appop/message.rs
index 1ae5c23b..bba0d092 100644
--- a/fractal-gtk/src/appop/message.rs
+++ b/fractal-gtk/src/appop/message.rs
@@ -49,7 +49,11 @@ impl AppOp {
     pub fn add_room_message(&mut self, msg: &Message) -> Option<()> {
         if let Some(ui_msg) = self.create_new_room_message(msg) {
             if let Some(ref mut history) = self.history {
-                history.add_new_message(ui_msg);
+                history.add_new_message(
+                    self.thread_pool.clone(),
+                    self.user_info_cache.clone(),
+                    ui_msg,
+                );
             }
         }
         None
@@ -58,7 +62,11 @@ impl AppOp {
     pub fn remove_room_message(&mut self, msg: &Message) {
         if let Some(ui_msg) = self.create_new_room_message(msg) {
             if let Some(ref mut history) = self.history {
-                history.remove_message(ui_msg);
+                history.remove_message(
+                    self.thread_pool.clone(),
+                    self.user_info_cache.clone(),
+                    ui_msg,
+                );
             }
         }
     }
@@ -68,7 +76,11 @@ impl AppOp {
         let messages = self.history.as_ref()?.get_listbox();
         if let Some(ui_msg) = self.create_new_room_message(&msg) {
             let backend = self.backend.clone();
-            let mb = widgets::MessageBox::new(backend, login_data.server_url).tmpwidget(&ui_msg);
+            let mb = widgets::MessageBox::new(backend, login_data.server_url).tmpwidget(
+                self.thread_pool.clone(),
+                self.user_info_cache.clone(),
+                &ui_msg,
+            );
             let m = mb.get_listbox_row();
             messages.add(m);
 
@@ -104,7 +116,11 @@ impl AppOp {
             if let Some(ui_msg) = self.create_new_room_message(&t.msg) {
                 let backend = self.backend.clone();
                 let mb = widgets::MessageBox::new(backend, login_data.server_url.clone())
-                    .tmpwidget(&ui_msg);
+                    .tmpwidget(
+                        self.thread_pool.clone(),
+                        self.user_info_cache.clone(),
+                        &ui_msg,
+                    );
                 let m = mb.get_listbox_row();
                 messages.add(m);
 
@@ -425,7 +441,11 @@ impl AppOp {
         }
 
         if let Some(ref mut history) = self.history {
-            history.add_old_messages_in_batch(list);
+            history.add_old_messages_in_batch(
+                self.thread_pool.clone(),
+                self.user_info_cache.clone(),
+                list,
+            );
         }
     }
 
diff --git a/fractal-gtk/src/appop/mod.rs b/fractal-gtk/src/appop/mod.rs
index 19b0ad13..bb2c9f82 100644
--- a/fractal-gtk/src/appop/mod.rs
+++ b/fractal-gtk/src/appop/mod.rs
@@ -3,6 +3,8 @@ use std::collections::HashMap;
 use std::path::PathBuf;
 use std::rc::Rc;
 use std::sync::mpsc::Sender;
+use std::sync::{Arc, Mutex};
+use std::time::Duration;
 
 use fractal_api::identifiers::{RoomId, UserId};
 use fractal_api::r0::AccessToken;
@@ -10,6 +12,8 @@ use fractal_api::r0::AccessToken;
 use gtk;
 use gtk::prelude::*;
 
+use fractal_api::backend::ThreadPool;
+use fractal_api::cache::CacheMap;
 use fractal_api::url::Url;
 
 use crate::backend;
@@ -116,6 +120,9 @@ pub struct AppOp {
 
     pub directory: Vec<Room>,
     pub leaflet: libhandy::Leaflet,
+
+    pub thread_pool: ThreadPool,
+    pub user_info_cache: Arc<Mutex<CacheMap<UserId, (String, String)>>>,
 }
 
 impl PasswordStorage for AppOp {}
@@ -157,6 +164,11 @@ impl AppOp {
 
             directory: vec![],
             leaflet: leaflet,
+
+            thread_pool: ThreadPool::new(20),
+            user_info_cache: Arc::new(Mutex::new(
+                CacheMap::new().timeout(Duration::from_secs(60 * 60)),
+            )),
         }
     }
 
diff --git a/fractal-gtk/src/appop/notify.rs b/fractal-gtk/src/appop/notify.rs
index 85e0216a..17d602f6 100644
--- a/fractal-gtk/src/appop/notify.rs
+++ b/fractal-gtk/src/appop/notify.rs
@@ -1,3 +1,4 @@
+use fractal_api::backend::user;
 use fractal_api::identifiers::{EventId, RoomId};
 use gio::ApplicationExt;
 use gio::FileExt;
@@ -13,7 +14,6 @@ use std::sync::mpsc::{Receiver, Sender};
 use crate::i18n::i18n;
 
 use crate::appop::AppOp;
-use crate::backend::BKCommand;
 
 use crate::widgets::ErrorDialog;
 
@@ -65,11 +65,13 @@ impl AppOp {
         };
 
         let (tx, rx): (Sender<(String, String)>, Receiver<(String, String)>) = channel();
-        let _ = self.backend.send(BKCommand::GetUserInfoAsync(
+        user::get_user_info_async(
+            self.thread_pool.clone(),
+            self.user_info_cache.clone(),
             server_url,
             msg.sender.clone(),
-            Some(tx),
-        ));
+            tx,
+        );
 
         let room_id = room_id.to_string();
         let id = id.to_string();
diff --git a/fractal-gtk/src/appop/room.rs b/fractal-gtk/src/appop/room.rs
index 5c8d381c..0b7c89fc 100644
--- a/fractal-gtk/src/appop/room.rs
+++ b/fractal-gtk/src/appop/room.rs
@@ -285,6 +285,7 @@ impl AppOp {
 
         let back_history = self.room_back_history.clone();
         let actions = actions::Message::new(
+            self.thread_pool.clone(),
             self.backend.clone(),
             login_data.server_url,
             login_data.access_token,
@@ -293,7 +294,11 @@ impl AppOp {
         );
         let history = widgets::RoomHistory::new(actions, active_room.clone(), self);
         self.history = if let Some(mut history) = history {
-            history.create(messages);
+            history.create(
+                self.thread_pool.clone(),
+                self.user_info_cache.clone(),
+                messages,
+            );
             Some(history)
         } else {
             None
diff --git a/fractal-gtk/src/appop/user.rs b/fractal-gtk/src/appop/user.rs
index 7fbd1281..6c34551a 100644
--- a/fractal-gtk/src/appop/user.rs
+++ b/fractal-gtk/src/appop/user.rs
@@ -94,7 +94,8 @@ impl AppOp {
                 None,
             );
             download_to_cache(
-                self.backend.clone(),
+                self.thread_pool.clone(),
+                self.user_info_cache.clone(),
                 login_data.server_url.clone(),
                 login_data.uid.clone(),
                 data.clone(),
@@ -118,7 +119,8 @@ impl AppOp {
                     None,
                 );
                 download_to_cache(
-                    self.backend.clone(),
+                    self.thread_pool.clone(),
+                    self.user_info_cache.clone(),
                     login_data.server_url.clone(),
                     login_data.uid.clone(),
                     data.clone(),
diff --git a/fractal-gtk/src/cache/mod.rs b/fractal-gtk/src/cache/mod.rs
index b25563ff..fef5e7fc 100644
--- a/fractal-gtk/src/cache/mod.rs
+++ b/fractal-gtk/src/cache/mod.rs
@@ -1,4 +1,6 @@
 use fractal_api::backend::user;
+use fractal_api::backend::ThreadPool;
+use fractal_api::cache::CacheMap;
 use fractal_api::url::Url;
 use fractal_api::util::ResultExpectLog;
 use glib::source::Continue;
@@ -16,11 +18,11 @@ use std::collections::HashMap;
 use crate::globals;
 
 /* includes for avatar download */
-use crate::backend::BKCommand;
 use std::sync::mpsc::channel;
 use std::sync::mpsc::Receiver;
 use std::sync::mpsc::Sender;
 use std::sync::mpsc::TryRecvError;
+use std::sync::{Arc, Mutex};
 
 use crate::widgets::AvatarData;
 use std::cell::RefCell;
@@ -103,13 +105,14 @@ pub fn load() -> Result<CacheData, Error> {
 
 /// this downloads a avatar and stores it in the cache folder
 pub fn download_to_cache(
-    backend: Sender<BKCommand>,
+    thread_pool: ThreadPool,
+    user_info_cache: Arc<Mutex<CacheMap<UserId, (String, String)>>>,
     server_url: Url,
     uid: UserId,
     data: Rc<RefCell<AvatarData>>,
 ) {
     let (tx, rx) = channel::<(String, String)>();
-    let _ = backend.send(BKCommand::GetUserInfoAsync(server_url, uid, Some(tx)));
+    user::get_user_info_async(thread_pool, user_info_cache, server_url, uid, tx);
 
     gtk::timeout_add(50, move || match rx.try_recv() {
         Err(TryRecvError::Empty) => Continue(true),
diff --git a/fractal-gtk/src/widgets/image.rs b/fractal-gtk/src/widgets/image.rs
index 7c524b4c..2971629a 100644
--- a/fractal-gtk/src/widgets/image.rs
+++ b/fractal-gtk/src/widgets/image.rs
@@ -1,3 +1,5 @@
+use fractal_api::backend::media;
+use fractal_api::backend::ThreadPool;
 use fractal_api::url::Url;
 use gdk::prelude::GdkContextExt;
 use gdk_pixbuf;
@@ -124,9 +126,9 @@ impl Image {
         self
     }
 
-    pub fn build(self) -> Image {
+    pub fn build(self, thread_pool: ThreadPool) -> Image {
         self.draw();
-        self.load_async();
+        self.load_async(thread_pool);
 
         self
     }
@@ -261,7 +263,7 @@ impl Image {
 
     /// If `path` starts with mxc this func download the img async, in other case the image is loaded
     /// in the `image` widget scaled to size
-    pub fn load_async(&self) {
+    pub fn load_async(&self, thread_pool: ThreadPool) {
         if self.path.starts_with("mxc:") {
             // asyn load
             let (tx, rx): (
@@ -269,11 +271,16 @@ impl Image {
                 Receiver<Result<String, Error>>,
             ) = channel();
             let command = if self.thumb {
-                BKCommand::GetThumbAsync(self.server_url.clone(), self.path.to_string(), tx)
+                media::get_thumb_async
             } else {
-                BKCommand::GetMediaAsync(self.server_url.clone(), self.path.to_string(), tx)
+                media::get_media_async
             };
-            self.backend.send(command).unwrap();
+            command(
+                thread_pool,
+                self.server_url.clone(),
+                self.path.to_string(),
+                tx,
+            );
             let local_path = self.local_path.clone();
             let pix = self.pixbuf.clone();
             let scaled = self.scaled.clone();
diff --git a/fractal-gtk/src/widgets/inline_player.rs b/fractal-gtk/src/widgets/inline_player.rs
index 496de462..d42a5bf3 100644
--- a/fractal-gtk/src/widgets/inline_player.rs
+++ b/fractal-gtk/src/widgets/inline_player.rs
@@ -17,6 +17,7 @@
 //
 // SPDX-License-Identifier: GPL-3.0-or-later
 
+use fractal_api::backend::{media, ThreadPool};
 use fractal_api::clone;
 
 use gst::prelude::*;
@@ -46,7 +47,6 @@ use std::sync::mpsc::{Receiver, Sender};
 use fractal_api::url::Url;
 
 use crate::app::App;
-use crate::backend::BKCommand;
 use crate::error::Error;
 use crate::i18n::i18n;
 
@@ -56,9 +56,9 @@ pub trait PlayerExt {
     fn stop(&self);
     fn initialize_stream(
         player: &Rc<Self>,
-        backend: &Sender<BKCommand>,
         media_url: &String,
         server_url: &Url,
+        thread_pool: ThreadPool,
         bx: &gtk::Box,
         start_playing: bool,
     );
@@ -496,9 +496,9 @@ impl<T: MediaPlayer + 'static> PlayerExt for T {
 
     fn initialize_stream(
         player: &Rc<Self>,
-        backend: &Sender<BKCommand>,
         media_url: &String,
         server_url: &Url,
+        thread_pool: ThreadPool,
         bx: &gtk::Box,
         start_playing: bool,
     ) {
@@ -507,13 +507,7 @@ impl<T: MediaPlayer + 'static> PlayerExt for T {
             Sender<Result<String, Error>>,
             Receiver<Result<String, Error>>,
         ) = channel();
-        backend
-            .send(BKCommand::GetMediaAsync(
-                server_url.clone(),
-                media_url.clone(),
-                tx,
-            ))
-            .unwrap();
+        media::get_media_async(thread_pool, server_url.clone(), media_url.clone(), tx);
         let local_path = player.get_local_path_access();
         gtk::timeout_add(
             50,
diff --git a/fractal-gtk/src/widgets/media_viewer.rs b/fractal-gtk/src/widgets/media_viewer.rs
index af879d8f..7b5d221f 100644
--- a/fractal-gtk/src/widgets/media_viewer.rs
+++ b/fractal-gtk/src/widgets/media_viewer.rs
@@ -1,3 +1,5 @@
+use fractal_api::backend::media;
+use fractal_api::backend::ThreadPool;
 use fractal_api::clone;
 use fractal_api::r0::AccessToken;
 use gdk;
@@ -186,7 +188,7 @@ impl Data {
         }
     }
 
-    pub fn enter_full_screen(&mut self) {
+    pub fn enter_full_screen(&mut self, thread_pool: ThreadPool) {
         self.main_window.fullscreen();
         self.is_fullscreen = true;
 
@@ -233,12 +235,12 @@ impl Data {
                 media_viewport.show();
             }
             _ => {
-                self.redraw_media_in_viewport();
+                self.redraw_media_in_viewport(thread_pool);
             }
         }
     }
 
-    pub fn leave_full_screen(&mut self) {
+    pub fn leave_full_screen(&mut self, thread_pool: ThreadPool) {
         self.main_window.unfullscreen();
         self.is_fullscreen = false;
 
@@ -292,7 +294,7 @@ impl Data {
                 }
             }
             _ => {
-                self.redraw_media_in_viewport();
+                self.redraw_media_in_viewport(thread_pool);
             }
         }
     }
@@ -321,7 +323,7 @@ impl Data {
         }
     }
 
-    pub fn previous_media(&mut self) -> bool {
+    pub fn previous_media(&mut self, thread_pool: ThreadPool) -> bool {
         if self.no_more_media {
             return true;
         }
@@ -335,12 +337,12 @@ impl Data {
                 set_header_title(&self.builder, name);
             }
 
-            self.redraw_media_in_viewport();
+            self.redraw_media_in_viewport(thread_pool);
             return true;
         }
     }
 
-    pub fn next_media(&mut self) {
+    pub fn next_media(&mut self, thread_pool: ThreadPool) {
         if self.current_media_index >= self.media_list.len() - 1 {
             return;
         }
@@ -350,10 +352,10 @@ impl Data {
             set_header_title(&self.builder, name);
         }
 
-        self.redraw_media_in_viewport();
+        self.redraw_media_in_viewport(thread_pool);
     }
 
-    pub fn redraw_media_in_viewport(&mut self) {
+    pub fn redraw_media_in_viewport(&mut self, thread_pool: ThreadPool) {
         let media_viewport = self
             .builder
             .get_object::<gtk::Viewport>("media_viewport")
@@ -370,13 +372,13 @@ impl Data {
                 let image = image::Image::new(&self.backend, self.server_url.clone(), &url)
                     .shrink_to_fit(true)
                     .center(true)
-                    .build();
+                    .build(thread_pool);
                 media_viewport.add(&image.widget);
                 image.widget.show();
                 self.widget = Widget::Image(image);
             }
             "m.video" => {
-                let widget = self.create_video_widget(&url);
+                let widget = self.create_video_widget(thread_pool, &url);
                 media_viewport.add(&widget.outer_box);
                 self.widget = Widget::Video(widget);
                 media_viewport.show_all();
@@ -388,16 +390,16 @@ impl Data {
         self.set_nav_btn_visibility();
     }
 
-    fn create_video_widget(&self, url: &String) -> VideoWidget {
+    fn create_video_widget(&self, thread_pool: ThreadPool, url: &String) -> VideoWidget {
         let with_controls = true;
         let player = VideoPlayerWidget::new(with_controls);
         let bx = gtk::Box::new(gtk::Orientation::Vertical, 0);
         let start_playing = true;
         PlayerExt::initialize_stream(
             &player,
-            &self.backend,
             url,
             &self.server_url.clone(),
+            thread_pool,
             &bx,
             start_playing,
         );
@@ -683,7 +685,7 @@ impl MediaViewer {
         }
     }
 
-    pub fn create(&mut self) -> Option<(gtk::Box, gtk::Box)> {
+    pub fn create(&mut self, thread_pool: ThreadPool) -> Option<(gtk::Box, gtk::Box)> {
         let body = self
             .builder
             .get_object::<gtk::Box>("media_viewer_box")
@@ -692,14 +694,14 @@ impl MediaViewer {
             .builder
             .get_object::<gtk::Box>("media_viewer_headerbar_box")
             .expect("Can't find media_viewer_headerbar in ui file.");
-        self.connect_media_viewer_headerbar();
-        self.connect_media_viewer_box();
+        self.connect_media_viewer_headerbar(thread_pool.clone());
+        self.connect_media_viewer_box(thread_pool);
         self.connect_stop_video_when_leaving();
 
         Some((body, header))
     }
 
-    pub fn display_media_viewer(&mut self, media_msg: Message) {
+    pub fn display_media_viewer(&mut self, thread_pool: ThreadPool, media_msg: Message) {
         let previous_media_revealer = self
             .builder
             .get_object::<gtk::Revealer>("previous_media_revealer")
@@ -726,7 +728,7 @@ impl MediaViewer {
                     image::Image::new(&self.backend, self.data.borrow().server_url.clone(), &url)
                         .shrink_to_fit(true)
                         .center(true)
-                        .build();
+                        .build(thread_pool.clone());
 
                 media_viewport.add(&image.widget);
                 media_viewport.show_all();
@@ -734,7 +736,7 @@ impl MediaViewer {
                 self.data.borrow_mut().widget = Widget::Image(image);
             }
             "m.video" => {
-                let video_widget = self.data.borrow().create_video_widget(&url);
+                let video_widget = self.data.borrow().create_video_widget(thread_pool, &url);
                 media_viewport.add(&video_widget.outer_box);
                 media_viewport.show_all();
 
@@ -748,7 +750,7 @@ impl MediaViewer {
     }
 
     /* connect media viewer headerbar */
-    pub fn connect_media_viewer_headerbar(&self) {
+    pub fn connect_media_viewer_headerbar(&self, thread_pool: ThreadPool) {
         let own_weak = Rc::downgrade(&self.data);
         let full_screen_button = self
             .builder
@@ -759,16 +761,16 @@ impl MediaViewer {
                 let main_window = own.borrow().main_window.clone();
                 if let Some(win) = main_window.get_window() {
                     if !win.get_state().contains(gdk::WindowState::FULLSCREEN) {
-                        own.borrow_mut().enter_full_screen();
+                        own.borrow_mut().enter_full_screen(thread_pool.clone());
                     } else {
-                        own.borrow_mut().leave_full_screen()
+                        own.borrow_mut().leave_full_screen(thread_pool.clone())
                     }
                 }
             });
         });
     }
 
-    pub fn connect_media_viewer_box(&self) {
+    pub fn connect_media_viewer_box(&self, thread_pool: ThreadPool) {
         let full_screen_button = self
             .builder
             .get_object::<gtk::Button>("full_screen_button")
@@ -915,10 +917,16 @@ impl MediaViewer {
             .builder
             .get_object::<gtk::Button>("previous_media_button")
             .expect("Cant find previous_media_button in ui file.");
+        let t_pool = thread_pool.clone();
         previous_media_button.connect_clicked(move |_| {
             own_weak.upgrade().map(|own| {
-                if !own.borrow_mut().previous_media() {
-                    load_more_media(own.clone(), builder.clone(), backend.clone());
+                if !own.borrow_mut().previous_media(t_pool.clone()) {
+                    load_more_media(
+                        t_pool.clone(),
+                        own.clone(),
+                        builder.clone(),
+                        backend.clone(),
+                    );
                 }
             });
         });
@@ -930,7 +938,7 @@ impl MediaViewer {
             .expect("Cant find next_media_button in ui file.");
         next_media_button.connect_clicked(move |_| {
             own_weak.upgrade().map(|own| {
-                own.borrow_mut().next_media();
+                own.borrow_mut().next_media(thread_pool.clone());
             });
         });
         let full_screen_button = self
@@ -1037,7 +1045,12 @@ fn loading_state(ui: &gtk::Builder, val: bool) -> bool {
     val
 }
 
-fn load_more_media(data: Rc<RefCell<Data>>, builder: gtk::Builder, backend: Sender<BKCommand>) {
+fn load_more_media(
+    thread_pool: ThreadPool,
+    data: Rc<RefCell<Data>>,
+    builder: gtk::Builder,
+    backend: Sender<BKCommand>,
+) {
     data.borrow_mut().loading_more_media = loading_state(&builder, true);
 
     let msg = data.borrow().media_list[data.borrow().current_media_index].clone();
@@ -1051,16 +1064,15 @@ fn load_more_media(data: Rc<RefCell<Data>>, builder: gtk::Builder, backend: Send
         Sender<(Vec<Message>, String)>,
         Receiver<(Vec<Message>, String)>,
     ) = channel();
-    backend
-        .send(BKCommand::GetMediaListAsync(
-            server_url,
-            access_token,
-            roomid,
-            first_media_id,
-            prev_batch,
-            tx,
-        ))
-        .unwrap();
+    media::get_media_list_async(
+        thread_pool.clone(),
+        server_url,
+        access_token,
+        roomid,
+        first_media_id,
+        prev_batch,
+        tx,
+    );
 
     let ui = builder.clone();
     let data_weak = Rc::downgrade(&data);
@@ -1082,6 +1094,7 @@ fn load_more_media(data: Rc<RefCell<Data>>, builder: gtk::Builder, backend: Send
                 });
                 return Continue(false);
             }
+            let thread_pool = thread_pool.clone();
             data_weak.upgrade().map(|data| {
                 let media_list = data.borrow().media_list.clone();
                 let img_msgs: Vec<Message> = msgs
@@ -1094,10 +1107,15 @@ fn load_more_media(data: Rc<RefCell<Data>>, builder: gtk::Builder, backend: Send
                 data.borrow_mut().media_list = new_media_list;
                 data.borrow_mut().prev_batch = Some(prev_batch);
                 if img_msgs_count == 0 {
-                    load_more_media(data.clone(), builder.clone(), backend.clone());
+                    load_more_media(
+                        thread_pool.clone(),
+                        data.clone(),
+                        builder.clone(),
+                        backend.clone(),
+                    );
                 } else {
                     data.borrow_mut().current_media_index += img_msgs_count;
-                    data.borrow_mut().previous_media();
+                    data.borrow_mut().previous_media(thread_pool);
                     data.borrow_mut().loading_more_media = loading_state(&ui, false);
                 }
             });
diff --git a/fractal-gtk/src/widgets/member.rs b/fractal-gtk/src/widgets/member.rs
index 9d291d6e..f9f3a03e 100644
--- a/fractal-gtk/src/widgets/member.rs
+++ b/fractal-gtk/src/widgets/member.rs
@@ -61,10 +61,14 @@ impl<'a> MemberBox<'a> {
             badge,
             None,
         );
-        let backend = self.op.backend.clone();
-        let member_id = self.member.uid.clone();
         if let Some(login_data) = self.op.login_data.clone() {
-            download_to_cache(backend, login_data.server_url, member_id, data);
+            download_to_cache(
+                self.op.thread_pool.clone(),
+                self.op.user_info_cache.clone(),
+                login_data.server_url,
+                self.member.uid.clone(),
+                data,
+            );
         };
 
         avatar.set_margin_start(3);
@@ -101,10 +105,14 @@ impl<'a> MemberBox<'a> {
             None,
             None,
         );
-        let backend = self.op.backend.clone();
-        let member_id = self.member.uid.clone();
         if let Some(login_data) = self.op.login_data.clone() {
-            download_to_cache(backend, login_data.server_url, member_id, data);
+            download_to_cache(
+                self.op.thread_pool.clone(),
+                self.op.user_info_cache.clone(),
+                login_data.server_url,
+                self.member.uid.clone(),
+                data,
+            );
         };
 
         avatar.set_margin_start(3);
diff --git a/fractal-gtk/src/widgets/message.rs b/fractal-gtk/src/widgets/message.rs
index 3b493eed..5e57798a 100644
--- a/fractal-gtk/src/widgets/message.rs
+++ b/fractal-gtk/src/widgets/message.rs
@@ -2,6 +2,9 @@ use crate::i18n::i18n;
 use itertools::Itertools;
 
 use chrono::prelude::*;
+use fractal_api::backend::ThreadPool;
+use fractal_api::cache::CacheMap;
+use fractal_api::identifiers::UserId;
 use fractal_api::url::Url;
 use glib;
 use gtk;
@@ -10,6 +13,7 @@ use pango;
 use std::cmp::max;
 use std::rc::Rc;
 use std::sync::mpsc::Sender;
+use std::sync::{Arc, Mutex};
 
 use crate::backend::BKCommand;
 
@@ -69,7 +73,14 @@ impl MessageBox {
     }
 
     /* create the message row with or without a header */
-    pub fn create(&mut self, msg: &Message, has_header: bool, is_temp: bool) {
+    pub fn create(
+        &mut self,
+        thread_pool: ThreadPool,
+        user_info_cache: Arc<Mutex<CacheMap<UserId, (String, String)>>>,
+        msg: &Message,
+        has_header: bool,
+        is_temp: bool,
+    ) {
         self.set_msg_styles(msg, &self.row);
         self.row.set_selectable(false);
         let upload_attachment_msg = gtk::Box::new(gtk::Orientation::Horizontal, 10);
@@ -77,7 +88,7 @@ impl MessageBox {
             RowType::Emote => {
                 self.row.set_margin_top(12);
                 self.header = false;
-                self.small_widget(msg)
+                self.small_widget(thread_pool.clone(), msg)
             }
             RowType::Video if is_temp => {
                 upload_attachment_msg
@@ -101,11 +112,11 @@ impl MessageBox {
             _ if has_header => {
                 self.row.set_margin_top(12);
                 self.header = true;
-                self.widget(msg)
+                self.widget(thread_pool.clone(), user_info_cache, msg)
             }
             _ => {
                 self.header = false;
-                self.small_widget(msg)
+                self.small_widget(thread_pool, msg)
             }
         };
 
@@ -119,8 +130,13 @@ impl MessageBox {
         &self.row
     }
 
-    pub fn tmpwidget(mut self, msg: &Message) -> MessageBox {
-        self.create(msg, true, true);
+    pub fn tmpwidget(
+        mut self,
+        thread_pool: ThreadPool,
+        user_info_cache: Arc<Mutex<CacheMap<UserId, (String, String)>>>,
+        msg: &Message,
+    ) -> MessageBox {
+        self.create(thread_pool, user_info_cache, msg, true, true);
         {
             let w = self.get_listbox_row();
             w.get_style_context().add_class("msg-tmp");
@@ -128,17 +144,23 @@ impl MessageBox {
         self
     }
 
-    pub fn update_header(&mut self, msg: Message, has_header: bool) {
+    pub fn update_header(
+        &mut self,
+        thread_pool: ThreadPool,
+        user_info_cache: Arc<Mutex<CacheMap<UserId, (String, String)>>>,
+        msg: Message,
+        has_header: bool,
+    ) {
         let w = if has_header && msg.mtype != RowType::Emote {
             self.row.set_margin_top(12);
             self.header = true;
-            self.widget(&msg)
+            self.widget(thread_pool.clone(), user_info_cache, &msg)
         } else {
             if let RowType::Emote = msg.mtype {
                 self.row.set_margin_top(12);
             }
             self.header = false;
-            self.small_widget(&msg)
+            self.small_widget(thread_pool, &msg)
         };
         match self.eventbox.get_child() {
             Some(eb) => {
@@ -150,15 +172,20 @@ impl MessageBox {
         self.row.show_all();
     }
 
-    fn widget(&mut self, msg: &Message) -> gtk::Box {
+    fn widget(
+        &mut self,
+        thread_pool: ThreadPool,
+        user_info_cache: Arc<Mutex<CacheMap<UserId, (String, String)>>>,
+        msg: &Message,
+    ) -> gtk::Box {
         // msg
         // +--------+---------+
         // | avatar | content |
         // +--------+---------+
         let msg_widget = gtk::Box::new(gtk::Orientation::Horizontal, 10);
-        let content = self.build_room_msg_content(msg, false);
+        let content = self.build_room_msg_content(thread_pool.clone(), msg, false);
         /* Todo: make build_room_msg_avatar() faster (currently ~1ms) */
-        let avatar = self.build_room_msg_avatar(msg);
+        let avatar = self.build_room_msg_avatar(thread_pool, user_info_cache, msg);
 
         msg_widget.pack_start(&avatar, false, false, 0);
         msg_widget.pack_start(&content, true, true, 0);
@@ -166,13 +193,13 @@ impl MessageBox {
         msg_widget
     }
 
-    fn small_widget(&mut self, msg: &Message) -> gtk::Box {
+    fn small_widget(&mut self, thread_pool: ThreadPool, msg: &Message) -> gtk::Box {
         // msg
         // +--------+---------+
         // |        | content |
         // +--------+---------+
         let msg_widget = gtk::Box::new(gtk::Orientation::Horizontal, 5);
-        let content = self.build_room_msg_content(msg, true);
+        let content = self.build_room_msg_content(thread_pool, msg, true);
         content.set_margin_start(50);
 
         msg_widget.pack_start(&content, true, true, 0);
@@ -180,7 +207,12 @@ impl MessageBox {
         msg_widget
     }
 
-    fn build_room_msg_content(&mut self, msg: &Message, small: bool) -> gtk::Box {
+    fn build_room_msg_content(
+        &mut self,
+        thread_pool: ThreadPool,
+        msg: &Message,
+        small: bool,
+    ) -> gtk::Box {
         // content
         // +------+
         // | info |
@@ -197,11 +229,11 @@ impl MessageBox {
         }
 
         let body = match msg.mtype {
-            RowType::Sticker => self.build_room_msg_sticker(msg),
-            RowType::Image => self.build_room_msg_image(msg),
+            RowType::Sticker => self.build_room_msg_sticker(thread_pool.clone(), msg),
+            RowType::Image => self.build_room_msg_image(thread_pool.clone(), msg),
             RowType::Emote => self.build_room_msg_emote(msg),
-            RowType::Audio => self.build_room_audio_player(msg),
-            RowType::Video => self.build_room_video_player(msg),
+            RowType::Audio => self.build_room_audio_player(thread_pool.clone(), msg),
+            RowType::Video => self.build_room_video_player(thread_pool, msg),
             RowType::File => self.build_room_msg_file(msg),
             _ => self.build_room_msg_body(msg),
         };
@@ -211,7 +243,12 @@ impl MessageBox {
         content
     }
 
-    fn build_room_msg_avatar(&self, msg: &Message) -> widgets::Avatar {
+    fn build_room_msg_avatar(
+        &self,
+        thread_pool: ThreadPool,
+        user_info_cache: Arc<Mutex<CacheMap<UserId, (String, String)>>>,
+        msg: &Message,
+    ) -> widgets::Avatar {
         let uid = msg.sender.clone();
         let alias = msg.sender_name.clone();
         let avatar = widgets::Avatar::avatar_new(Some(globals::MSG_ICON_SIZE));
@@ -230,7 +267,8 @@ impl MessageBox {
         }
 
         download_to_cache(
-            self.backend.clone(),
+            thread_pool,
+            user_info_cache,
             self.server_url.clone(),
             uid.clone(),
             data.clone(),
@@ -356,7 +394,7 @@ impl MessageBox {
         msg_part
     }
 
-    fn build_room_msg_image(&mut self, msg: &Message) -> gtk::Box {
+    fn build_room_msg_image(&mut self, thread_pool: ThreadPool, msg: &Message) -> gtk::Box {
         let bx = gtk::Box::new(gtk::Orientation::Horizontal, 0);
 
         let img_path = match msg.thumb {
@@ -366,7 +404,7 @@ impl MessageBox {
         };
         let image = widgets::image::Image::new(&self.backend, self.server_url.clone(), &img_path)
             .size(Some(globals::MAX_IMAGE_SIZE))
-            .build();
+            .build(thread_pool);
 
         image.widget.get_style_context().add_class("image-widget");
 
@@ -378,13 +416,13 @@ impl MessageBox {
         bx
     }
 
-    fn build_room_msg_sticker(&self, msg: &Message) -> gtk::Box {
+    fn build_room_msg_sticker(&self, thread_pool: ThreadPool, msg: &Message) -> gtk::Box {
         let bx = gtk::Box::new(gtk::Orientation::Horizontal, 0);
         let backend = self.backend.clone();
         if let Some(url) = msg.url.as_ref() {
             let image = widgets::image::Image::new(&backend, self.server_url.clone(), url)
                 .size(Some(globals::MAX_STICKER_SIZE))
-                .build();
+                .build(thread_pool);
             image.widget.set_tooltip_text(Some(&msg.body[..]));
 
             bx.add(&image.widget);
@@ -393,15 +431,15 @@ impl MessageBox {
         bx
     }
 
-    fn build_room_audio_player(&self, msg: &Message) -> gtk::Box {
+    fn build_room_audio_player(&self, thread_pool: ThreadPool, msg: &Message) -> gtk::Box {
         let bx = gtk::Box::new(gtk::Orientation::Horizontal, 6);
         let player = AudioPlayerWidget::new();
         let start_playing = false;
         PlayerExt::initialize_stream(
             &player,
-            &self.backend,
             &msg.url.clone().unwrap_or_default(),
             &self.server_url,
+            thread_pool,
             &bx,
             start_playing,
         );
@@ -438,16 +476,16 @@ impl MessageBox {
         outer_box
     }
 
-    fn build_room_video_player(&mut self, msg: &Message) -> gtk::Box {
+    fn build_room_video_player(&mut self, thread_pool: ThreadPool, msg: &Message) -> gtk::Box {
         let with_controls = false;
         let player = VideoPlayerWidget::new(with_controls);
         let bx = gtk::Box::new(gtk::Orientation::Vertical, 6);
         let start_playing = false;
         PlayerExt::initialize_stream(
             &player,
-            &self.backend,
             &msg.url.clone().unwrap_or_default(),
             &self.server_url,
+            thread_pool,
             &bx,
             start_playing,
         );
diff --git a/fractal-gtk/src/widgets/room_history.rs b/fractal-gtk/src/widgets/room_history.rs
index 946c2afc..06a988be 100644
--- a/fractal-gtk/src/widgets/room_history.rs
+++ b/fractal-gtk/src/widgets/room_history.rs
@@ -8,6 +8,7 @@ use std::cell::RefCell;
 use std::collections::VecDeque;
 use std::rc::Rc;
 use std::sync::mpsc::Sender;
+use std::sync::{Arc, Mutex};
 
 use crate::appop::AppOp;
 use crate::backend::BKCommand;
@@ -18,7 +19,9 @@ use crate::uitypes::RowType;
 use crate::globals;
 use crate::widgets;
 use crate::widgets::{PlayerExt, VideoPlayerWidget};
-use fractal_api::identifiers::RoomId;
+use fractal_api::backend::ThreadPool;
+use fractal_api::cache::CacheMap;
+use fractal_api::identifiers::{RoomId, UserId};
 use fractal_api::url::Url;
 use gio::ActionMapExt;
 use gio::SimpleActionGroup;
@@ -293,7 +296,12 @@ impl RoomHistory {
         Some(rh)
     }
 
-    pub fn create(&mut self, mut messages: Vec<MessageContent>) -> Option<()> {
+    pub fn create(
+        &mut self,
+        thread_pool: ThreadPool,
+        user_info_cache: Arc<Mutex<CacheMap<UserId, (String, String)>>>,
+        mut messages: Vec<MessageContent>,
+    ) -> Option<()> {
         let mut position = messages.len();
         /* Find position of last viewed message */
         for (i, item) in messages.iter().enumerate() {
@@ -303,9 +311,9 @@ impl RoomHistory {
         }
         let bottom = messages.split_off(position);
         messages.reverse();
-        self.add_old_messages_in_batch(messages);
+        self.add_old_messages_in_batch(thread_pool.clone(), user_info_cache.clone(), messages);
         /* Add the rest of the messages after the new message divider */
-        self.add_new_messages_in_batch(bottom);
+        self.add_new_messages_in_batch(thread_pool, user_info_cache, bottom);
 
         let weak_rows = Rc::downgrade(&self.rows);
         let id = timeout_add(250, move || {
@@ -428,7 +436,11 @@ impl RoomHistory {
         });
     }
 
-    fn run_queue(&mut self) -> Option<()> {
+    fn run_queue(
+        &mut self,
+        thread_pool: ThreadPool,
+        user_info_cache: Arc<Mutex<CacheMap<UserId, (String, String)>>>,
+    ) -> Option<()> {
         let backend = self.backend.clone();
         let queue = self.queue.clone();
         let rows = self.rows.clone();
@@ -484,6 +496,8 @@ impl RoomHistory {
                         rows.borrow_mut().new_divider_index = Some(new_divider_index);
                     }
                     item.widget = Some(create_row(
+                        thread_pool.clone(),
+                        user_info_cache.clone(),
                         item.clone(),
                         has_header,
                         backend.clone(),
@@ -519,7 +533,12 @@ impl RoomHistory {
     }
 
     /* This adds new incomming messages at then end of the list */
-    pub fn add_new_message(&mut self, mut item: MessageContent) -> Option<()> {
+    pub fn add_new_message(
+        &mut self,
+        thread_pool: ThreadPool,
+        user_info_cache: Arc<Mutex<CacheMap<UserId, (String, String)>>>,
+        mut item: MessageContent,
+    ) -> Option<()> {
         let mut rows = self.rows.borrow_mut();
         let mut day_divider = None;
         let has_header = {
@@ -550,6 +569,8 @@ impl RoomHistory {
         }
 
         let b = create_row(
+            thread_pool,
+            user_info_cache,
             item.clone(),
             has_header,
             self.backend.clone(),
@@ -561,7 +582,12 @@ impl RoomHistory {
         None
     }
 
-    pub fn remove_message(&mut self, item: MessageContent) -> Option<()> {
+    pub fn remove_message(
+        &mut self,
+        thread_pool: ThreadPool,
+        user_info_cache: Arc<Mutex<CacheMap<UserId, (String, String)>>>,
+        item: MessageContent,
+    ) -> Option<()> {
         let mut rows = self.rows.borrow_mut();
         let (i, ref mut msg) = rows
             .list
@@ -604,27 +630,37 @@ impl RoomHistory {
                     msg_next_cloned.redactable && msg_next_cloned.sender == msg_sender
                 })
             {
-                msg_widget.update_header(msg_next_cloned, true);
+                msg_widget.update_header(thread_pool, user_info_cache, msg_next_cloned, true);
             }
         }
         None
     }
 
-    pub fn add_new_messages_in_batch(&mut self, messages: Vec<MessageContent>) -> Option<()> {
+    pub fn add_new_messages_in_batch(
+        &mut self,
+        thread_pool: ThreadPool,
+        user_info_cache: Arc<Mutex<CacheMap<UserId, (String, String)>>>,
+        messages: Vec<MessageContent>,
+    ) -> Option<()> {
         /* TODO: use lazy loading */
         for item in messages {
-            self.add_new_message(item);
+            self.add_new_message(thread_pool.clone(), user_info_cache.clone(), item);
         }
         None
     }
 
-    pub fn add_old_messages_in_batch(&mut self, messages: Vec<MessageContent>) -> Option<()> {
+    pub fn add_old_messages_in_batch(
+        &mut self,
+        thread_pool: ThreadPool,
+        user_info_cache: Arc<Mutex<CacheMap<UserId, (String, String)>>>,
+        messages: Vec<MessageContent>,
+    ) -> Option<()> {
         self.rows.borrow().view.reset_request_sent();
         /* TODO: Try if extend would be faster then append */
         self.queue
             .borrow_mut()
             .append(&mut VecDeque::from(messages));
-        self.run_queue();
+        self.run_queue(thread_pool, user_info_cache);
 
         None
     }
@@ -646,6 +682,8 @@ impl RoomHistory {
 
 /* This function creates the content for a Row based on the content of msg */
 fn create_row(
+    thread_pool: ThreadPool,
+    user_info_cache: Arc<Mutex<CacheMap<UserId, (String, String)>>>,
     row: MessageContent,
     has_header: bool,
     backend: Sender<BKCommand>,
@@ -655,7 +693,13 @@ fn create_row(
     /* we need to create a message with the username, so that we don't have to pass
      * all information to the widget creating each row */
     let mut mb = widgets::MessageBox::new(backend, server_url);
-    mb.create(&row, has_header && row.mtype != RowType::Emote, false);
+    mb.create(
+        thread_pool,
+        user_info_cache,
+        &row,
+        has_header && row.mtype != RowType::Emote,
+        false,
+    );
 
     match row.mtype {
         RowType::Video => {
diff --git a/fractal-matrix-api/src/backend/media.rs b/fractal-matrix-api/src/backend/media.rs
index 8966a932..b99eb926 100644
--- a/fractal-matrix-api/src/backend/media.rs
+++ b/fractal-matrix-api/src/backend/media.rs
@@ -1,4 +1,3 @@
-use crate::backend::types::Backend;
 use crate::error::Error;
 use crate::globals;
 use ruma_identifiers::{EventId, RoomId};
@@ -19,22 +18,34 @@ use crate::r0::message::get_message_events::Parameters as GetMessagesEventsParam
 use crate::r0::message::get_message_events::Response as GetMessagesEventsResponse;
 use crate::types::Message;
 
-pub fn get_thumb_async(bk: &Backend, baseu: Url, media: String, tx: Sender<Result<String, Error>>) {
-    bk.thread_pool.run(move || {
+use super::types::ThreadPool;
+
+pub fn get_thumb_async(
+    thread_pool: ThreadPool,
+    baseu: Url,
+    media: String,
+    tx: Sender<Result<String, Error>>,
+) {
+    thread_pool.run(move || {
         let fname = dw_media(baseu, &media, ContentType::default_thumbnail(), None);
         tx.send(fname).expect_log("Connection closed");
     });
 }
 
-pub fn get_media_async(bk: &Backend, baseu: Url, media: String, tx: Sender<Result<String, Error>>) {
-    bk.thread_pool.run(move || {
+pub fn get_media_async(
+    thread_pool: ThreadPool,
+    baseu: Url,
+    media: String,
+    tx: Sender<Result<String, Error>>,
+) {
+    thread_pool.run(move || {
         let fname = dw_media(baseu, &media, ContentType::Download, None);
         tx.send(fname).expect_log("Connection closed");
     });
 }
 
 pub fn get_media_list_async(
-    bk: &Backend,
+    thread_pool: ThreadPool,
     baseu: Url,
     access_token: AccessToken,
     room_id: RoomId,
@@ -42,7 +53,7 @@ pub fn get_media_list_async(
     prev_batch: Option<String>,
     tx: Sender<(Vec<Message>, String)>,
 ) {
-    bk.thread_pool.run(move || {
+    thread_pool.run(move || {
         let media_list = prev_batch
             // FIXME: This should never be an empty token
             .or_else(|| get_prev_batch_from(baseu.clone(), access_token.clone(), &room_id, 
&first_media_id).ok())
diff --git a/fractal-matrix-api/src/backend/mod.rs b/fractal-matrix-api/src/backend/mod.rs
index ed99aae0..d4e11484 100644
--- a/fractal-matrix-api/src/backend/mod.rs
+++ b/fractal-matrix-api/src/backend/mod.rs
@@ -5,12 +5,8 @@ use std::thread;
 
 use crate::util::ResultExpectLog;
 
-use crate::cache::CacheMap;
-
-use self::types::ThreadPool;
-
 pub mod directory;
-mod media;
+pub mod media;
 pub mod register;
 pub mod room;
 mod sync;
@@ -21,14 +17,11 @@ pub use self::types::BKCommand;
 pub use self::types::BKResponse;
 pub use self::types::Backend;
 pub use self::types::RoomType;
+pub use self::types::ThreadPool;
 
 impl Backend {
     pub fn new(tx: Sender<BKResponse>) -> Backend {
-        Backend {
-            tx,
-            user_info_cache: CacheMap::new().timeout(60 * 60),
-            thread_pool: ThreadPool::new(20),
-        }
+        Backend { tx }
     }
 
     pub fn run(mut self) -> Sender<BKCommand> {
@@ -57,14 +50,6 @@ impl Backend {
             }
             Ok(BKCommand::Guest(server, id_url)) => register::guest(self, server, id_url),
 
-            // User module
-            Ok(BKCommand::GetAvatarAsync(server, member, ctx)) => {
-                user::get_avatar_async(self, server, member, ctx)
-            }
-            Ok(BKCommand::GetUserInfoAsync(server, sender, ctx)) => {
-                user::get_user_info_async(self, server, sender, ctx)
-            }
-
             // Sync module
             Ok(BKCommand::Sync(server, access_token, uid, jtr, since, initial, number_tries)) => {
                 sync::sync(
@@ -88,30 +73,6 @@ impl Backend {
                 bkerror!(r, tx, BKResponse::AttachedFile);
             }
 
-            // Media module
-            Ok(BKCommand::GetThumbAsync(server, media, ctx)) => {
-                media::get_thumb_async(self, server, media, ctx)
-            }
-            Ok(BKCommand::GetMediaAsync(server, media, ctx)) => {
-                media::get_media_async(self, server, media, ctx)
-            }
-            Ok(BKCommand::GetMediaListAsync(
-                server,
-                access_token,
-                room_id,
-                first_media_id,
-                prev_batch,
-                ctx,
-            )) => media::get_media_list_async(
-                self,
-                server,
-                access_token,
-                room_id,
-                first_media_id,
-                prev_batch,
-                ctx,
-            ),
-
             // Internal commands
             Ok(BKCommand::SendBKResponse(response)) => {
                 tx.send(response).expect_log("Connection closed");
diff --git a/fractal-matrix-api/src/backend/types.rs b/fractal-matrix-api/src/backend/types.rs
index 4f8e1e7d..cadde004 100644
--- a/fractal-matrix-api/src/backend/types.rs
+++ b/fractal-matrix-api/src/backend/types.rs
@@ -7,11 +7,9 @@ use crate::error::Error;
 
 use crate::r0::AccessToken;
 use crate::types::Event;
-use crate::types::Member;
 use crate::types::Message;
 use crate::types::Room;
 
-use crate::cache::CacheMap;
 use url::Url;
 
 #[derive(Debug)]
@@ -28,18 +26,6 @@ pub enum BKCommand {
         bool,
         u64,
     ),
-    GetThumbAsync(Url, String, Sender<Result<String, Error>>),
-    GetMediaAsync(Url, String, Sender<Result<String, Error>>),
-    GetMediaListAsync(
-        Url,
-        AccessToken,
-        RoomId,
-        EventId,
-        Option<String>,
-        Sender<(Vec<Message>, String)>,
-    ),
-    GetAvatarAsync(Url, Option<Member>, Sender<String>),
-    GetUserInfoAsync(Url, UserId, Option<Sender<(String, String)>>),
     SetRoom(Url, AccessToken, RoomId),
     ShutDown,
     AttachFile(Url, AccessToken, Message),
@@ -110,6 +96,7 @@ pub enum RoomType {
     Private,
 }
 
+#[derive(Clone, Debug)]
 pub struct ThreadPool {
     thread_count: Arc<(Mutex<u8>, Condvar)>,
     limit: u8,
@@ -154,8 +141,4 @@ impl ThreadPool {
 
 pub struct Backend {
     pub tx: Sender<BKResponse>,
-
-    // user info cache, uid -> (name, avatar)
-    pub user_info_cache: CacheMap<UserId, Arc<Mutex<(String, String)>>>,
-    pub thread_pool: ThreadPool,
 }
diff --git a/fractal-matrix-api/src/backend/user.rs b/fractal-matrix-api/src/backend/user.rs
index f6ff9035..d9a1cd25 100644
--- a/fractal-matrix-api/src/backend/user.rs
+++ b/fractal-matrix-api/src/backend/user.rs
@@ -2,12 +2,10 @@ use ruma_identifiers::UserId;
 use std::fs;
 use url::Url;
 
-use crate::backend::types::Backend;
+use crate::backend::types::ThreadPool;
+use crate::cache::CacheMap;
 use crate::error::Error;
-use crate::util::cache_dir_path;
-use crate::util::dw_media;
 use crate::util::get_user_avatar;
-use crate::util::ContentType;
 use crate::util::ResultExpectLog;
 use crate::util::HTTP_CLIENT;
 use std::convert::TryInto;
@@ -286,20 +284,6 @@ pub fn get_avatar(base: Url, userid: UserId) -> Result<PathBuf, Error> {
     get_user_avatar(base, &userid).map(|(_, fname)| fname.into())
 }
 
-pub fn get_avatar_async(bk: &Backend, base: Url, member: Option<Member>, tx: Sender<String>) {
-    if let Some(member) = member {
-        let uid = member.uid.clone();
-        let avatar = member.avatar.clone().unwrap_or_default();
-
-        bk.thread_pool.run(move || {
-            let fname = get_user_avatar_img(base, &uid, &avatar).unwrap_or_default();
-            tx.send(fname).expect_log("Connection closed");
-        });
-    } else {
-        tx.send(Default::default()).expect_log("Connection closed");
-    }
-}
-
 pub fn set_user_avatar(
     base: Url,
     access_token: AccessToken,
@@ -328,35 +312,28 @@ pub fn set_user_avatar(
 }
 
 pub fn get_user_info_async(
-    bk: &mut Backend,
+    thread_pool: ThreadPool,
+    user_info_cache: Arc<Mutex<CacheMap<UserId, (String, String)>>>,
     baseu: Url,
     uid: UserId,
-    tx: Option<Sender<(String, String)>>,
+    tx: Sender<(String, String)>,
 ) {
-    if let Some(info) = bk.user_info_cache.get(&uid).cloned() {
-        if let Some(tx) = tx.clone() {
-            thread::spawn(move || {
-                let i = info.lock().unwrap().clone();
-                tx.send(i).expect_log("Connection closed");
-            });
-        }
+    if let Some(info) = user_info_cache.lock().unwrap().get(&uid).cloned() {
+        thread::spawn(move || {
+            tx.send(info).expect_log("Connection closed");
+        });
         return;
     }
 
-    let info: Arc<Mutex<(String, String)>> = Default::default();
-    bk.user_info_cache.insert(uid.clone(), info.clone());
-
-    bk.thread_pool.run(move || {
-        match (get_user_avatar(baseu, &uid), tx) {
-            (Ok(i0), Some(tx)) => {
-                tx.send(i0.clone()).expect_log("Connection closed");
-                *info.lock().unwrap() = i0;
-            }
-            (Err(_), Some(tx)) => {
-                tx.send(Default::default()).expect_log("Connection closed");
-            }
-            _ => {}
-        };
+    thread_pool.run(move || {
+        let info = get_user_avatar(baseu, &uid);
+
+        if let Ok(ref i0) = info {
+            user_info_cache.lock().unwrap().insert(uid, i0.clone());
+        }
+
+        tx.send(info.unwrap_or_default())
+            .expect_log("Connection closed");
     });
 }
 
@@ -376,9 +353,3 @@ pub fn search(
 
     Ok(response.results.into_iter().map(Into::into).collect())
 }
-
-fn get_user_avatar_img(baseu: Url, userid: &UserId, avatar: &str) -> Result<String, Error> {
-    let dest = cache_dir_path(None, &userid.to_string())?;
-
-    dw_media(baseu, avatar, ContentType::default_thumbnail(), Some(dest))
-}
diff --git a/fractal-matrix-api/src/cache.rs b/fractal-matrix-api/src/cache.rs
index 1615c039..1ec05b5e 100644
--- a/fractal-matrix-api/src/cache.rs
+++ b/fractal-matrix-api/src/cache.rs
@@ -1,22 +1,23 @@
 use std::collections::HashMap;
 use std::hash::Hash;
-use std::time::Instant;
+use std::time::{Duration, Instant};
 
-#[derive(Clone)]
-pub struct CacheMap<K: Clone, V: Clone> {
+// user info cache, uid -> (name, avatar)
+#[derive(Clone, Debug)]
+pub struct CacheMap<K: Clone + Eq + Hash, V: Clone> {
     map: HashMap<K, (Instant, V)>,
-    timeout: u64,
+    timeout: Duration,
 }
 
 impl<K: Clone + Eq + Hash, V: Clone> CacheMap<K, V> {
     pub fn new() -> Self {
         CacheMap {
             map: HashMap::new(),
-            timeout: 10,
+            timeout: Duration::from_secs(10),
         }
     }
 
-    pub fn timeout(mut self, timeout: u64) -> Self {
+    pub fn timeout(mut self, timeout: Duration) -> Self {
         self.timeout = timeout;
         self
     }
@@ -24,7 +25,7 @@ impl<K: Clone + Eq + Hash, V: Clone> CacheMap<K, V> {
     pub fn get(&self, k: &K) -> Option<&V> {
         match self.map.get(k) {
             Some(t) => {
-                if t.0.elapsed().as_secs() >= self.timeout {
+                if t.0.elapsed() >= self.timeout {
                     return None;
                 }
                 Some(&t.1)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]