From dccb93c1db3e02928cbadd22c32571b73e828450 Mon Sep 17 00:00:00 2001
From: Kubat <maelle.martin@proton.me>
Date: Wed, 14 May 2025 20:58:17 +0200
Subject: [PATCH] NKDB: Get ride of the sync functions, so that an async worker
 will never call a sync function

---
 amadeus/src/config.rs                 |  6 +++---
 lektor_nkdb/src/playlists/mod.rs      |  4 ++--
 lektor_nkdb/src/playlists/playlist.rs |  8 --------
 lektor_nkdb/src/strings.rs            | 19 +++++--------------
 lektord/src/app/routes.rs             |  8 ++++----
 5 files changed, 14 insertions(+), 31 deletions(-)

diff --git a/amadeus/src/config.rs b/amadeus/src/config.rs
index 4c79d76e..1a4e5c71 100644
--- a/amadeus/src/config.rs
+++ b/amadeus/src/config.rs
@@ -1,8 +1,8 @@
-use cosmic::cosmic_config::{self, cosmic_config_derive::CosmicConfigEntry, CosmicConfigEntry};
-use derive_more::{AsRef, Display, From, Into};
+use cosmic::cosmic_config::{self, CosmicConfigEntry, cosmic_config_derive::CosmicConfigEntry};
+use derive_more::{Display, From, Into};
 use lektor_lib::ConnectConfig;
 use lektor_utils::config::{SocketScheme, UserConfig};
-use serde::{de::Visitor, Deserialize, Serialize};
+use serde::{Deserialize, Serialize, de::Visitor};
 use std::{
     net::{IpAddr, Ipv4Addr, SocketAddr},
     time::Duration,
diff --git a/lektor_nkdb/src/playlists/mod.rs b/lektor_nkdb/src/playlists/mod.rs
index fd5a0b5c..350ac076 100644
--- a/lektor_nkdb/src/playlists/mod.rs
+++ b/lektor_nkdb/src/playlists/mod.rs
@@ -84,11 +84,11 @@ impl<'a, Storage: DatabaseStorage + Sized> PlaylistsHandle<'a, Storage> {
     pub async fn create(
         &self,
         name: impl ToString,
-        settings: impl FnOnce(Playlist) -> Playlist,
+        settings: impl AsyncFnOnce(Playlist) -> Playlist,
     ) -> Result<KId> {
         let mut this = self.playlists.content.write().await;
         let next_id = KId(this.keys().map(|KId(id)| id + 1).max().unwrap_or(1));
-        let plt = settings(Playlist::new(next_id, name)).updated_now();
+        let plt = settings(Playlist::new(next_id, name)).await.updated_now();
         self.playlists.epoch.fetch_add(1, Ordering::AcqRel);
         self.storage.write_playlist(&plt).await?;
         this.insert(next_id, plt);
diff --git a/lektor_nkdb/src/playlists/playlist.rs b/lektor_nkdb/src/playlists/playlist.rs
index b720c82b..9f23ed56 100644
--- a/lektor_nkdb/src/playlists/playlist.rs
+++ b/lektor_nkdb/src/playlists/playlist.rs
@@ -56,14 +56,6 @@ impl Playlist {
         }
     }
 
-    /// Add an owner to the playlist, in a sync way. This function may block.
-    pub fn with_owner_sync(mut self, user: impl AsRef<str>) -> Self {
-        if !(self.owners.iter()).any(|owner| owner.as_ref() == user.as_ref()) {
-            self.owners.push(strings::CACHE.get_sync(user.as_ref()));
-        }
-        self.updated_now()
-    }
-
     /// Add an owner to the playlist, in an async way. This function may yield.
     pub async fn with_owner(mut self, user: impl AsRef<str>) -> Self {
         if !(self.owners.iter()).any(|owner| owner.as_ref() == user.as_ref()) {
diff --git a/lektor_nkdb/src/strings.rs b/lektor_nkdb/src/strings.rs
index d5892eeb..f3fda353 100644
--- a/lektor_nkdb/src/strings.rs
+++ b/lektor_nkdb/src/strings.rs
@@ -14,21 +14,12 @@ pub(crate) struct StringCache(RwLock<HashSet<Arc<str>>>);
 impl StringCache {
     /// Get a string, in an async way.
     pub async fn get(&self, str: impl AsRef<str>) -> Arc<str> {
-        match self.0.read().await.get(str.as_ref()).cloned() {
-            Some(str) => str,
-            None => (self.0.write().await)
-                .get_or_insert_with(str.as_ref(), |str| Arc::from(str))
-                .clone(),
+        if let Some(str) = self.0.read().await.get(str.as_ref()).cloned() {
+            return str;
         }
-    }
 
-    /// Get a string, in a sync way.
-    pub fn get_sync(&self, str: impl AsRef<str>) -> Arc<str> {
-        match self.0.blocking_read().get(str.as_ref()).cloned() {
-            Some(str) => str,
-            None => (self.0.blocking_write())
-                .get_or_insert_with(str.as_ref(), |str| Arc::from(str))
-                .clone(),
-        }
+        (self.0.write().await)
+            .get_or_insert_with(str.as_ref(), |str| Arc::from(str))
+            .clone()
     }
 }
diff --git a/lektord/src/app/routes.rs b/lektord/src/app/routes.rs
index a6953bbc..e96a093e 100644
--- a/lektord/src/app/routes.rs
+++ b/lektord/src/app/routes.rs
@@ -9,10 +9,10 @@ use crate::*;
 use anyhow::anyhow;
 use app::search_adaptors;
 use axum::{
+    Json,
     extract::{Path, State},
-    http::{header::CONTENT_TYPE, HeaderValue},
+    http::{HeaderValue, header::CONTENT_TYPE},
     response::{IntoResponse, Response},
-    Json,
 };
 use lektor_nkdb::*;
 use lektor_payloads::*;
@@ -252,8 +252,8 @@ pub(crate) async fn create_playlist(
         .maybe_user()
         .map(|user| user.into_parts().0);
     let id = (state.database.playlists())
-        .create(name, |plt| match user {
-            Ok(user) => plt.with_owner_sync(user),
+        .create(name, async |plt| match user {
+            Ok(user) => plt.with_owner(user).await,
             _ => plt,
         })
         .await?;
-- 
GitLab