Improve connection handling

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/4/head
trivernis 3 years ago
parent 68ffdc323b
commit 5e4d6e098f

File diff suppressed because it is too large Load Diff

@ -18,15 +18,22 @@ tauri-build = { version = "1.0.0-beta.4" }
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
tauri = { version = "1.0.0-beta.8", features = ["api-all"] }
rmp-ipc = "0.4.0"
rmp-ipc = "0.4.3"
thiserror = "1.0.30"
directories = "4.0.1"
toml = "0.5.8"
typemap_rev = "0.1.5"
[dependencies.tokio]
version = "1.12.0"
features = ["fs", "io-std", "io-util"]
[dependencies.mediarepo]
git = "https://github.com/Trivernis/mediarepo-daemon"
rev = "edc5877582cde744fe23c22f31075da792821e77"
features = ["library"]
default-features=false
[features]
default = [ "custom-protocol" ]
custom-protocol = [ "tauri/custom-protocol" ]

@ -1 +1,17 @@
use crate::context::Context;
use crate::error::AppResult;
pub mod repo;
#[tauri::command]
pub async fn emit_info(context: tauri::State<'_, Context>) -> AppResult<()> {
let ipc = context.ipc.read().await;
if let Some(ipc) = &*ipc {
ipc.emitter.emit("info", ()).await?;
println!("Emitted info event.");
} else {
println!("No IPC Context");
}
Ok(())
}

@ -6,6 +6,9 @@ use crate::error::{AppError, AppResult};
use tokio::fs;
use crate::settings::save_settings;
use rmp_ipc::context::Context as IPCContext;
use tauri::Window;
use crate::ipc::build_ipc_context;
use std::mem;
static REPO_CONFIG_FILE: &str = "repo.toml";
@ -30,6 +33,12 @@ pub async fn get_repositories(context: tauri::State<'_, Context>) -> AppResult<V
Ok(settings.repositories.values().cloned().collect())
}
#[tauri::command]
pub async fn get_active_repository(context: tauri::State<'_, Context>) -> AppResult<Option<Repository>> {
let repo = context.active_repository.read().await;
Ok(repo.clone())
}
#[tauri::command]
pub async fn add_repository(name: String, path: String, context: tauri::State<'_, Context>) -> AppResult<Vec<Repository>> {
let repo_path = path.clone();
@ -54,12 +63,18 @@ pub async fn add_repository(name: String, path: String, context: tauri::State<'_
}
#[tauri::command]
pub async fn select_repository(name: String, context: tauri::State<'_, Context>) -> AppResult<()> {
pub async fn select_repository(window: Window, name: String, context: tauri::State<'_, Context>) -> AppResult<()> {
let settings = context.settings.read().await;
let repo = settings.repositories.get(&name).ok_or(AppError::new(format!("Repository '{}' not found", name)))?;
let ipc = connect(&repo.address).await?;
let ipc = connect(window, &repo.address).await?;
let mut ipc_ctx = context.ipc.write().await;
*ipc_ctx = Some(ipc);
let old_ipc = mem::replace(&mut *ipc_ctx, Some(ipc));
if let Some(old_ctx) = old_ipc {
old_ctx.stop().await?;
}
let mut active_repo = context.active_repository.write().await;
*active_repo = Some(repo.clone());
Ok(())
}
@ -72,8 +87,6 @@ async fn read_repo_config(path: PathBuf) -> AppResult<RepoConfig> {
}
/// Connects to the IPC Server
async fn connect(address: &str) -> AppResult<IPCContext> {
let ctx = IPCBuilder::new().address(address).build_client().await?;
Ok(ctx)
async fn connect(window: Window, address: &str) -> AppResult<IPCContext> {
build_ipc_context(window, address).await
}

@ -6,7 +6,7 @@ use crate::settings::Settings;
#[derive(Clone)]
pub struct Context {
pub active_repository: Option<Repository>,
pub active_repository: Arc<RwLock<Option<Repository>>>,
pub ipc: Arc<RwLock<Option<IPCContext>>>,
pub settings: Arc<RwLock<Settings>>
}
@ -15,7 +15,7 @@ impl Context {
pub fn new(settings: Settings) -> Self {
Self {
ipc: Arc::new(RwLock::new(None)),
active_repository: None,
active_repository: Arc::new(RwLock::new(None)),
settings: Arc::new(RwLock::new(settings))
}
}

@ -48,3 +48,15 @@ impl From<rmp_ipc::error::Error> for AppError {
Self::new(format!("Daemon Error: {:?}", e))
}
}
impl From<tauri::Error> for AppError {
fn from(e: tauri::Error) -> Self {
Self::new(format!("Tauri error: {:?}", e))
}
}
impl From<AppError> for rmp_ipc::error::Error {
fn from(e: AppError) -> Self {
rmp_ipc::error::Error::Message(e.message)
}
}

@ -0,0 +1 @@
use mediarepo::requests::AddFileRequest;

@ -0,0 +1,45 @@
mod files;
use mediarepo::responses::InfoResponse;
use rmp_ipc::context::{Context as IPCContext, Context};
use rmp_ipc::{Event, IPCBuilder};
use rmp_ipc::error::Result;
use rmp_ipc::error_event::{ERROR_EVENT_NAME, ErrorEventData};
use tauri::Window;
use typemap_rev::TypeMapKey;
use crate::error::AppResult;
pub struct WindowKey;
impl TypeMapKey for WindowKey {
type Value = Window;
}
pub async fn build_ipc_context(window: Window, address: &str) -> AppResult<IPCContext> {
let ctx = IPCBuilder::new()
.address(address)
.insert::<WindowKey>(window)
.on(ERROR_EVENT_NAME, |c, e|Box::pin(handle_error(c, e)))
.on("info", |c, e| Box::pin(handle_info(c, e)))
.build_client().await?;
Ok(ctx)
}
async fn handle_error(ctx: &Context, event: Event) -> Result<()> {
let error_data = event.data::<ErrorEventData>()?;
let data = ctx.data.read().await;
let window = data.get::<WindowKey>().unwrap();
window.emit("error", error_data).expect("Failed to emit error event");
Ok(())
}
async fn handle_info(ctx: &Context, event: Event) -> Result<()> {
let info_data = event.data::<InfoResponse>()?;
let data = ctx.data.read().await;
let window = data.get::<WindowKey>().unwrap();
window.emit("info", info_data).expect("Failed to emit info event");
Ok(())
}

@ -3,7 +3,8 @@
windows_subsystem = "windows"
)]
use crate::commands::repo::{get_repositories, add_repository, select_repository};
use crate::commands::repo::{get_repositories, add_repository, select_repository, get_active_repository};
use crate::commands::emit_info;
use crate::context::Context;
use crate::settings::load_settings;
@ -11,6 +12,7 @@ mod commands;
pub mod context;
pub mod error;
mod settings;
mod ipc;
fn main() {
let settings = load_settings().expect("Failed to load settings");
@ -18,7 +20,7 @@ fn main() {
tauri::Builder::default()
.manage(context)
.invoke_handler(tauri::generate_handler![get_repositories, add_repository, select_repository])
.invoke_handler(tauri::generate_handler![get_repositories, add_repository, select_repository, get_active_repository, emit_info])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}

Loading…
Cancel
Save