From fac097d995275018201582ca796c24c08a6b96f4 Mon Sep 17 00:00:00 2001
From: Pavel Kirilin <win10@list.ru>
Date: Mon, 28 Feb 2022 23:20:17 +0400
Subject: [PATCH] Synchronization moved to reactor. (#47)

Signed-off-by: Pavel Kirilin <win10@list.ru>
---
 src/info_storages/file_info_storage.rs  |  8 ++------
 src/info_storages/models/file_info.rs   | 14 ++++++++++++++
 src/info_storages/redis_info_storage.rs |  2 +-
 src/storages/file_storage.rs            |  9 +++++----
 4 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/src/info_storages/file_info_storage.rs b/src/info_storages/file_info_storage.rs
index fad265b..51f5567 100644
--- a/src/info_storages/file_info_storage.rs
+++ b/src/info_storages/file_info_storage.rs
@@ -45,12 +45,8 @@ impl InfoStorage for FileInfoStorage {
                 error!("{:?}", err);
                 RustusError::UnableToWrite(err.to_string())
             })?;
-        let data = serde_json::to_string(&file_info).map_err(|err| {
-            error!("{:#?}", err);
-            err
-        })?;
-        copy(&mut data.as_bytes(), &mut file).await?;
-        file.sync_data().await?;
+        copy(&mut file_info.json().await?.as_bytes(), &mut file).await?;
+        tokio::task::spawn(async move { file.sync_data().await });
         Ok(())
     }
 
diff --git a/src/info_storages/models/file_info.rs b/src/info_storages/models/file_info.rs
index bace48b..5202706 100644
--- a/src/info_storages/models/file_info.rs
+++ b/src/info_storages/models/file_info.rs
@@ -1,7 +1,10 @@
 use std::collections::HashMap;
 
+use crate::errors::RustusError;
+use crate::RustusResult;
 use chrono::serde::ts_seconds;
 use chrono::{DateTime, Utc};
+use log::error;
 use serde::{Deserialize, Serialize};
 
 /// Information about file.
@@ -88,6 +91,17 @@ impl FileInfo {
         }
     }
 
+    pub async fn json(&self) -> RustusResult<String> {
+        let info_clone = self.clone();
+        let data = tokio::task::spawn_blocking(move || serde_json::to_string(&info_clone))
+            .await
+            .map_err(|err| {
+                error!("{}", err);
+                RustusError::UnableToWrite("Can't serialize info".into())
+            })??;
+        Ok(data)
+    }
+
     #[cfg(test)]
     pub fn new_test() -> Self {
         FileInfo::new(
diff --git a/src/info_storages/redis_info_storage.rs b/src/info_storages/redis_info_storage.rs
index b9e0b3b..5e412a0 100644
--- a/src/info_storages/redis_info_storage.rs
+++ b/src/info_storages/redis_info_storage.rs
@@ -30,7 +30,7 @@ impl InfoStorage for RedisStorage {
         let mut conn = self.pool.get().await?;
         redis::cmd("SET")
             .arg(file_info.id.as_str())
-            .arg(serde_json::to_string(file_info)?.as_str())
+            .arg(file_info.json().await?.as_str())
             .query_async::<Connection, String>(&mut conn)
             .await
             .map_err(RustusError::from)?;
diff --git a/src/storages/file_storage.rs b/src/storages/file_storage.rs
index 2653412..b2a850b 100644
--- a/src/storages/file_storage.rs
+++ b/src/storages/file_storage.rs
@@ -4,7 +4,7 @@ use actix_files::NamedFile;
 use async_trait::async_trait;
 use log::error;
 use tokio::fs::{remove_file, DirBuilder, OpenOptions};
-use tokio::io::{copy, BufReader};
+use tokio::io::copy;
 
 use crate::errors::{RustusError, RustusResult};
 use crate::info_storages::FileInfo;
@@ -95,9 +95,10 @@ impl Storage for FileStorage {
                 error!("{:?}", err);
                 RustusError::UnableToWrite(err.to_string())
             })?;
-        let mut reader = BufReader::new(bytes);
-        copy(&mut reader, &mut file).await?;
-        file.sync_data().await?;
+        #[allow(clippy::clone_double_ref)]
+        let mut buffer = bytes.clone();
+        copy(&mut buffer, &mut file).await?;
+        tokio::task::spawn(async move { file.sync_data().await });
         Ok(())
     }
 
-- 
GitLab