diff --git a/mediarepo-daemon/mediarepo-model/src/repo.rs b/mediarepo-daemon/mediarepo-model/src/repo.rs index 2b8a36f..df1d06f 100644 --- a/mediarepo-daemon/mediarepo-model/src/repo.rs +++ b/mediarepo-daemon/mediarepo-model/src/repo.rs @@ -11,6 +11,7 @@ use std::path::PathBuf; use tokio::fs::OpenOptions; use tokio::io::BufReader; +#[derive(Clone)] pub struct Repo { db: DatabaseConnection, main_storage: Option, diff --git a/mediarepo-daemon/mediarepo-model/src/type_keys.rs b/mediarepo-daemon/mediarepo-model/src/type_keys.rs index 1105ea8..a604c7f 100644 --- a/mediarepo-daemon/mediarepo-model/src/type_keys.rs +++ b/mediarepo-daemon/mediarepo-model/src/type_keys.rs @@ -1,8 +1,9 @@ use crate::repo::Repo; +use std::sync::Arc; use typemap_rev::TypeMapKey; pub struct RepoKey; impl TypeMapKey for RepoKey { - type Value = Repo; + type Value = Arc; } diff --git a/mediarepo-daemon/mediarepo-socket/src/lib.rs b/mediarepo-daemon/mediarepo-socket/src/lib.rs index 0cc9bf6..ba46489 100644 --- a/mediarepo-daemon/mediarepo-socket/src/lib.rs +++ b/mediarepo-daemon/mediarepo-socket/src/lib.rs @@ -3,6 +3,7 @@ use mediarepo_core::rmp_ipc::prelude::*; mod namespaces; pub mod types; +mod utils; pub fn get_builder(address: &str) -> IPCBuilder { namespaces::build_namespaces(IPCBuilder::new().address(address)).on("info", callback!(info)) diff --git a/mediarepo-daemon/mediarepo-socket/src/namespaces/files.rs b/mediarepo-daemon/mediarepo-socket/src/namespaces/files.rs index e5db3eb..7c274e4 100644 --- a/mediarepo-daemon/mediarepo-socket/src/namespaces/files.rs +++ b/mediarepo-daemon/mediarepo-socket/src/namespaces/files.rs @@ -2,11 +2,11 @@ use crate::types::requests::{ AddFileRequest, FileIdentifier, GetFileThumbnailsRequest, ReadFileRequest, }; use crate::types::responses::{FileResponse, ThumbnailResponse}; +use crate::utils::get_repo_from_context; use mediarepo_core::error::{RepoError, RepoResult}; use mediarepo_core::rmp_ipc::prelude::*; use mediarepo_model::file::File; use mediarepo_model::repo::Repo; -use mediarepo_model::type_keys::RepoKey; use std::path::PathBuf; use tokio::io::AsyncReadExt; @@ -32,8 +32,7 @@ impl FilesNamespace { /// Returns a list of all files async fn all_files(ctx: &Context, event: Event) -> IPCResult<()> { let files = { - let data = ctx.data.read().await; - let repo = data.get::().unwrap(); + let repo = get_repo_from_context(ctx).await; repo.files().await? }; let responses: Vec = files.into_iter().map(FileResponse::from).collect(); @@ -48,11 +47,9 @@ impl FilesNamespace { async fn add_file(ctx: &Context, event: Event) -> IPCResult<()> { let request = event.data::()?; let path = PathBuf::from(request.path); - let file = { - let data = ctx.data.read().await; - let repo = data.get::().unwrap(); - repo.add_file_by_path(path).await? - }; + let repo = get_repo_from_context(ctx).await; + let file = repo.add_file_by_path(path).await?; + ctx.emitter .emit_response_to( event.id(), @@ -68,16 +65,13 @@ impl FilesNamespace { /// Reads the binary contents of a file async fn read_file(ctx: &Context, event: Event) -> IPCResult<()> { let request = event.data::()?; - let mut reader = { - let data = ctx.data.read().await; - let repo = data.get::().unwrap(); - let file = file_by_identifier(request, repo) - .await? - .ok_or_else(|| RepoError::from("File not found")); - file?.get_reader().await? - }; + + let repo = get_repo_from_context(ctx).await; + let file = file_by_identifier(request, &repo).await?; + let mut reader = file.get_reader().await?; let mut buf = Vec::new(); reader.read_to_end(&mut buf).await?; + ctx.emitter .emit_response_to(event.id(), Self::name(), "read_file", buf) .await?; @@ -88,12 +82,10 @@ impl FilesNamespace { /// Returns a list of available thumbnails of a file async fn thumbnails(ctx: &Context, event: Event) -> IPCResult<()> { let request = event.data::()?; - let data = ctx.data.read().await; - let repo = data.get::().unwrap(); - let file = file_by_identifier(request, repo) - .await? - .ok_or_else(|| RepoError::from("File not found"))?; + let repo = get_repo_from_context(ctx).await; + let file = file_by_identifier(request, &repo).await?; let thumbnails = file.thumbnails().await?; + let thumb_responses: Vec = thumbnails .into_iter() .map(ThumbnailResponse::from) @@ -108,15 +100,12 @@ impl FilesNamespace { /// Reads a thumbnail for the given thumbnail hash async fn read_thumbnail(ctx: &Context, event: Event) -> IPCResult<()> { let hash = event.data::()?; - let mut reader = { - let data = ctx.data.read().await; - let repo = data.get::().unwrap(); - let thumbnail = repo - .thumbnail_by_hash(&hash) - .await? - .ok_or_else(|| RepoError::from("Thumbnail not found"))?; - thumbnail.get_reader().await? - }; + let repo = get_repo_from_context(ctx).await; + let thumbnail = repo + .thumbnail_by_hash(&hash) + .await? + .ok_or_else(|| RepoError::from("Thumbnail not found"))?; + let mut reader = thumbnail.get_reader().await?; let mut buf = Vec::new(); reader.read_to_end(&mut buf).await?; ctx.emitter @@ -127,9 +116,10 @@ impl FilesNamespace { } } -async fn file_by_identifier(identifier: FileIdentifier, repo: &Repo) -> RepoResult> { - match identifier { +async fn file_by_identifier(identifier: FileIdentifier, repo: &Repo) -> RepoResult { + let file = match identifier { FileIdentifier::ID(id) => repo.file_by_id(id).await, FileIdentifier::Hash(hash) => repo.file_by_hash(hash).await, - } + }?; + file.ok_or_else(|| RepoError::from("Thumbnail not found")) } diff --git a/mediarepo-daemon/mediarepo-socket/src/utils.rs b/mediarepo-daemon/mediarepo-socket/src/utils.rs new file mode 100644 index 0000000..7b29eaa --- /dev/null +++ b/mediarepo-daemon/mediarepo-socket/src/utils.rs @@ -0,0 +1,10 @@ +use mediarepo_core::rmp_ipc::ipc::context::Context; +use mediarepo_model::repo::Repo; +use mediarepo_model::type_keys::RepoKey; +use std::sync::Arc; + +pub async fn get_repo_from_context(ctx: &Context) -> Arc { + let data = ctx.data.read().await; + let repo = data.get::().unwrap(); + Arc::clone(repo) +} diff --git a/mediarepo-daemon/src/main.rs b/mediarepo-daemon/src/main.rs index e9cd34c..e80165a 100644 --- a/mediarepo-daemon/src/main.rs +++ b/mediarepo-daemon/src/main.rs @@ -11,6 +11,7 @@ use mediarepo_model::repo::Repo; use mediarepo_model::type_keys::RepoKey; use mediarepo_socket::get_builder; use std::path::PathBuf; +use std::sync::Arc; use structopt::StructOpt; use tokio::fs; use tokio::runtime; @@ -105,7 +106,7 @@ async fn start_server(opt: Opt) -> RepoResult<()> { get_builder(&settings.listen_address) .insert::(settings) - .insert::(repo) + .insert::(Arc::new(repo)) .build_server() .await?;