Repository: meilisearch/meilisearch
File: meilisearch-lib/src/dump/handler.rs (Rust)

Code before:
        pub async fn run(&self, uid: String) -> Result<()> {
            trace!("Performing dump.");

            create_dir_all(&self.dump_path).await?;

            let temp_dump_dir = tokio::task::spawn_blocking(tempfile::TempDir::new).await??;
            let temp_dump_path = temp_dump_dir.path().to_owned();

            let meta = MetadataVersion::new_v5(self.index_db_size, self.task_store_size);
            let meta_path = temp_dump_path.join(META_FILE_NAME);

            let meta_bytes = serde_json::to_vec(&meta)?;
            let mut meta_file = tokio::fs::File::create(&meta_path).await?;
            meta_file.write_all(&meta_bytes).await?;

            analytics::copy_user_id(&self.db_path, &temp_dump_path);

            create_dir_all(&temp_dump_path.join("indexes")).await?;

            let db_path = self.db_path.clone();
            let temp_dump_path_clone = temp_dump_path.clone();
            tokio::task::spawn_blocking(move || -> Result<()> {
                AuthController::dump(db_path, temp_dump_path_clone)?;
                Ok(())
            })
            .await??;
            TaskStore::dump(
                self.env.clone(),
                &temp_dump_path,
                self.update_file_store.clone(),
            )
            .await?;
            self.index_resolver.dump(&temp_dump_path).await?;

            let dump_path = self.dump_path.clone();
            let dump_path = tokio::task::spawn_blocking(move || -> Result<PathBuf> {
                // for now we simply copy the updates/updates_files
                // FIXME: We may copy more files than necessary, if new files are added while we are
                // performing the dump. We need a way to filter them out.

                let temp_dump_file = tempfile::NamedTempFile::new_in(&dump_path)?;
                to_tar_gz(temp_dump_path, temp_dump_file.path())
                    .map_err(|e| DumpError::Internal(e.into()))?;

                let dump_path = dump_path.join(uid).with_extension("dump");
                temp_dump_file.persist(&dump_path)?;

                Ok(dump_path)
            })
            .await??;


Review comment (security):
As the task store below, shouldn't we put the `spawn_blocking` in `AuthController::dump` and make it async?


Code after:

        pub async fn run(&self, uid: String) -> Result<()> {
            trace!("Performing dump.");

            create_dir_all(&self.dump_path).await?;

            let temp_dump_dir = tokio::task::spawn_blocking(tempfile::TempDir::new).await??;
            let temp_dump_path = temp_dump_dir.path().to_owned();

            let meta = MetadataVersion::new_v5(self.index_db_size, self.task_store_size);
            let meta_path = temp_dump_path.join(META_FILE_NAME);

            let meta_bytes = serde_json::to_vec(&meta)?;
            let mut meta_file = tokio::fs::File::create(&meta_path).await?;
            meta_file.write_all(&meta_bytes).await?;

            analytics::copy_user_id(&self.db_path, &temp_dump_path);

            create_dir_all(&temp_dump_path.join("indexes")).await?;

            let db_path = self.db_path.clone();
            let temp_dump_path_clone = temp_dump_path.clone();
            tokio::task::spawn_blocking(move || -> Result<()> {
                AuthController::dump(db_path, temp_dump_path_clone)?;
                Ok(())
            })
            .await??;
            TaskStore::dump(
                self.env.clone(),
                &temp_dump_path,
                self.update_file_store.clone(),
            )
            .await?;
            self.index_resolver.dump(&temp_dump_path).await?;

            let dump_path = self.dump_path.clone();
            let dump_path = tokio::task::spawn_blocking(move || -> Result<PathBuf> {
                // for now we simply copy the updates/updates_files
                // FIXME: We may copy more files than necessary, if new files are added while we are
                // performing the dump. We need a way to filter them out.

                let temp_dump_file = tempfile::NamedTempFile::new_in(&dump_path)?;
                to_tar_gz(temp_dump_path, temp_dump_file.path())
                    .map_err(|e| DumpError::Internal(e.into()))?;

                let dump_path = dump_path.join(uid).with_extension("dump");
                temp_dump_file.persist(&dump_path)?;

                Ok(dump_path)
            })
            .await??;