fix(executor-core): F-Q-002 promote sdk::bridge::block_on, migrate 9 SDK modules
Replace ten near-identical `block_on` helpers (one per SDK module) with a single shared `sdk::bridge::block_on(service: &str, fut)`. The helper takes a service-prefix string and a future whose error implements Display, so each module's `KvError`/`DocsError`/etc. still self-formats. Migrated: - kv, docs, pubsub, users, dead_letters, secrets, files, email - queue.rs has two helpers; the inline-shaped enqueue path and the block_on_u64 (u64→i64) wrapper are left in place — the latter could use the shared helper but the local form is one less call site per finding overlap. Will revisit on a later pass if needed. - http.rs is intentionally NOT migrated: it has per-variant error mapping via `map_http_err` that the generic helper can't express. Net: -218 / +97 lines across the 9 migrated files. Single source of truth for the runtime-handle lookup and error wrapping. AUDIT.md anchor: F-Q-002. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -44,11 +44,10 @@ use std::sync::Arc;
|
||||
|
||||
use picloud_shared::{
|
||||
AppUser, AppUserId, CreateUserInput, EmailTemplateOpts, GeneratedAccept, GeneratedSession,
|
||||
InviteOpts, SdkCallCx, Services, UpdateUserInput, UsersError, UsersListOpts, UsersListPage,
|
||||
UsersService,
|
||||
InviteOpts, SdkCallCx, Services, UpdateUserInput, UsersListOpts, UsersListPage, UsersService,
|
||||
};
|
||||
use rhai::{Array, Dynamic, Engine as RhaiEngine, EvalAltResult, Map, Module};
|
||||
use tokio::runtime::Handle as TokioHandle;
|
||||
use super::bridge::block_on;
|
||||
|
||||
pub(super) fn register(engine: &mut RhaiEngine, services: &Services, cx: Arc<SdkCallCx>) {
|
||||
let svc = services.users.clone();
|
||||
@@ -91,7 +90,7 @@ fn bind_create(module: &mut Module, svc: &Arc<dyn UsersService>, cx: &Arc<SdkCal
|
||||
let display_name = optional_string(&opts, "display_name");
|
||||
let svc = svc.clone();
|
||||
let cx = cx.clone();
|
||||
let user = block_on(async move {
|
||||
let user = block_on("users", async move {
|
||||
svc.create(
|
||||
&cx,
|
||||
CreateUserInput {
|
||||
@@ -116,7 +115,7 @@ fn bind_get(module: &mut Module, svc: &Arc<dyn UsersService>, cx: &Arc<SdkCallCx
|
||||
let id = parse_user_id(id, "users::get")?;
|
||||
let svc = svc.clone();
|
||||
let cx = cx.clone();
|
||||
let user_opt = block_on(async move { svc.get(&cx, id).await })?;
|
||||
let user_opt = block_on("users", async move { svc.get(&cx, id).await })?;
|
||||
Ok(user_opt.map_or(Dynamic::UNIT, |u| Dynamic::from(user_to_map(&u))))
|
||||
},
|
||||
);
|
||||
@@ -131,7 +130,7 @@ fn bind_find_by_email(module: &mut Module, svc: &Arc<dyn UsersService>, cx: &Arc
|
||||
let email = email.to_string();
|
||||
let svc = svc.clone();
|
||||
let cx = cx.clone();
|
||||
let user_opt = block_on(async move { svc.find_by_email(&cx, &email).await })?;
|
||||
let user_opt = block_on("users", async move { svc.find_by_email(&cx, &email).await })?;
|
||||
Ok(user_opt.map_or(Dynamic::UNIT, |u| Dynamic::from(user_to_map(&u))))
|
||||
},
|
||||
);
|
||||
@@ -154,7 +153,7 @@ fn bind_update(module: &mut Module, svc: &Arc<dyn UsersService>, cx: &Arc<SdkCal
|
||||
let patch = UpdateUserInput { display_name };
|
||||
let svc = svc.clone();
|
||||
let cx = cx.clone();
|
||||
let user = block_on(async move { svc.update(&cx, id, patch).await })?;
|
||||
let user = block_on("users", async move { svc.update(&cx, id, patch).await })?;
|
||||
Ok(user_to_map(&user))
|
||||
},
|
||||
);
|
||||
@@ -169,7 +168,7 @@ fn bind_delete(module: &mut Module, svc: &Arc<dyn UsersService>, cx: &Arc<SdkCal
|
||||
let id = parse_user_id(id, "users::delete")?;
|
||||
let svc = svc.clone();
|
||||
let cx = cx.clone();
|
||||
block_on(async move { svc.delete(&cx, id).await })
|
||||
block_on("users", async move { svc.delete(&cx, id).await })
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -200,7 +199,7 @@ fn bind_list(module: &mut Module, svc: &Arc<dyn UsersService>, cx: &Arc<SdkCallC
|
||||
let svc = svc.clone();
|
||||
let cx = cx.clone();
|
||||
let page: UsersListPage =
|
||||
block_on(async move { svc.list(&cx, UsersListOpts { cursor, limit }).await })?;
|
||||
block_on("users", async move { svc.list(&cx, UsersListOpts { cursor, limit }).await })?;
|
||||
Ok(list_page_to_map(&page))
|
||||
},
|
||||
);
|
||||
@@ -221,7 +220,7 @@ fn bind_login(module: &mut Module, svc: &Arc<dyn UsersService>, cx: &Arc<SdkCall
|
||||
let svc = svc.clone();
|
||||
let cx = cx.clone();
|
||||
let session_opt: Option<GeneratedSession> =
|
||||
block_on(async move { svc.login(&cx, &email, &password).await })?;
|
||||
block_on("users", async move { svc.login(&cx, &email, &password).await })?;
|
||||
Ok(session_opt.map_or(Dynamic::UNIT, |s| Dynamic::from(s.token)))
|
||||
},
|
||||
);
|
||||
@@ -236,7 +235,7 @@ fn bind_verify(module: &mut Module, svc: &Arc<dyn UsersService>, cx: &Arc<SdkCal
|
||||
let token = token.to_string();
|
||||
let svc = svc.clone();
|
||||
let cx = cx.clone();
|
||||
let user_opt = block_on(async move { svc.verify(&cx, &token).await })?;
|
||||
let user_opt = block_on("users", async move { svc.verify(&cx, &token).await })?;
|
||||
Ok(user_opt.map_or(Dynamic::UNIT, |u| Dynamic::from(user_to_map(&u))))
|
||||
},
|
||||
);
|
||||
@@ -251,7 +250,7 @@ fn bind_logout(module: &mut Module, svc: &Arc<dyn UsersService>, cx: &Arc<SdkCal
|
||||
let token = token.to_string();
|
||||
let svc = svc.clone();
|
||||
let cx = cx.clone();
|
||||
block_on(async move { svc.logout(&cx, &token).await })
|
||||
block_on("users", async move { svc.logout(&cx, &token).await })
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -274,7 +273,7 @@ fn bind_send_verification_email(
|
||||
let opts = parse_email_template(&opts, "users::send_verification_email")?;
|
||||
let svc = svc.clone();
|
||||
let cx = cx.clone();
|
||||
block_on(async move { svc.send_verification_email(&cx, id, opts).await })
|
||||
block_on("users", async move { svc.send_verification_email(&cx, id, opts).await })
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -288,7 +287,7 @@ fn bind_verify_email(module: &mut Module, svc: &Arc<dyn UsersService>, cx: &Arc<
|
||||
let token = token.to_string();
|
||||
let svc = svc.clone();
|
||||
let cx = cx.clone();
|
||||
let user_opt = block_on(async move { svc.verify_email(&cx, &token).await })?;
|
||||
let user_opt = block_on("users", async move { svc.verify_email(&cx, &token).await })?;
|
||||
Ok(user_opt.map_or(Dynamic::UNIT, |u| Dynamic::from(user_to_map(&u))))
|
||||
},
|
||||
);
|
||||
@@ -308,7 +307,7 @@ fn bind_request_password_reset(
|
||||
let opts = parse_email_template(&opts, "users::request_password_reset")?;
|
||||
let svc = svc.clone();
|
||||
let cx = cx.clone();
|
||||
block_on(async move { svc.request_password_reset(&cx, &email, opts).await })
|
||||
block_on("users", async move { svc.request_password_reset(&cx, &email, opts).await })
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -327,7 +326,7 @@ fn bind_complete_password_reset(
|
||||
let new_password = new_password.to_string();
|
||||
let svc = svc.clone();
|
||||
let cx = cx.clone();
|
||||
let user_opt = block_on(async move {
|
||||
let user_opt = block_on("users", async move {
|
||||
svc.complete_password_reset(&cx, &token, &new_password)
|
||||
.await
|
||||
})?;
|
||||
@@ -346,7 +345,7 @@ fn bind_invite(module: &mut Module, svc: &Arc<dyn UsersService>, cx: &Arc<SdkCal
|
||||
let opts = parse_invite_opts(&opts)?;
|
||||
let svc = svc.clone();
|
||||
let cx = cx.clone();
|
||||
block_on(async move { svc.invite(&cx, &email, opts).await })
|
||||
block_on("users", async move { svc.invite(&cx, &email, opts).await })
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -367,7 +366,7 @@ fn bind_accept_invite(module: &mut Module, svc: &Arc<dyn UsersService>, cx: &Arc
|
||||
let svc = svc.clone();
|
||||
let cx = cx.clone();
|
||||
let accept_opt: Option<GeneratedAccept> =
|
||||
block_on(async move { svc.accept_invite(&cx, &token, &password, None).await })?;
|
||||
block_on("users", async move { svc.accept_invite(&cx, &token, &password, None).await })?;
|
||||
Ok(accept_opt.map_or(Dynamic::UNIT, |a| Dynamic::from(a.session.token)))
|
||||
},
|
||||
);
|
||||
@@ -390,7 +389,7 @@ fn bind_accept_invite(module: &mut Module, svc: &Arc<dyn UsersService>, cx: &Arc
|
||||
};
|
||||
let svc = svc.clone();
|
||||
let cx = cx.clone();
|
||||
let accept_opt: Option<GeneratedAccept> = block_on(async move {
|
||||
let accept_opt: Option<GeneratedAccept> = block_on("users", async move {
|
||||
svc.accept_invite(&cx, &token, &password, display_name)
|
||||
.await
|
||||
})?;
|
||||
@@ -414,7 +413,7 @@ fn bind_add_role(module: &mut Module, svc: &Arc<dyn UsersService>, cx: &Arc<SdkC
|
||||
let role = role.to_string();
|
||||
let svc = svc.clone();
|
||||
let cx = cx.clone();
|
||||
block_on(async move { svc.add_role(&cx, id, &role).await })
|
||||
block_on("users", async move { svc.add_role(&cx, id, &role).await })
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -429,7 +428,7 @@ fn bind_remove_role(module: &mut Module, svc: &Arc<dyn UsersService>, cx: &Arc<S
|
||||
let role = role.to_string();
|
||||
let svc = svc.clone();
|
||||
let cx = cx.clone();
|
||||
block_on(async move { svc.remove_role(&cx, id, &role).await })
|
||||
block_on("users", async move { svc.remove_role(&cx, id, &role).await })
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -444,7 +443,7 @@ fn bind_has_role(module: &mut Module, svc: &Arc<dyn UsersService>, cx: &Arc<SdkC
|
||||
let role = role.to_string();
|
||||
let svc = svc.clone();
|
||||
let cx = cx.clone();
|
||||
block_on(async move { svc.has_role(&cx, id, &role).await })
|
||||
block_on("users", async move { svc.has_role(&cx, id, &role).await })
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -588,21 +587,3 @@ fn runtime_err(msg: &str) -> Box<EvalAltResult> {
|
||||
EvalAltResult::ErrorRuntime(msg.into(), rhai::Position::NONE).into()
|
||||
}
|
||||
|
||||
/// Run a `UsersService` future inside the synchronous Rhai context.
|
||||
/// Mirrors `kv::block_on` / `email::block_on`.
|
||||
fn block_on<T, F>(fut: F) -> Result<T, Box<EvalAltResult>>
|
||||
where
|
||||
F: std::future::Future<Output = Result<T, UsersError>> + Send,
|
||||
T: Send,
|
||||
{
|
||||
let handle = TokioHandle::try_current().map_err(|e| -> Box<EvalAltResult> {
|
||||
EvalAltResult::ErrorRuntime(
|
||||
format!("users: no tokio runtime available: {e}").into(),
|
||||
rhai::Position::NONE,
|
||||
)
|
||||
.into()
|
||||
})?;
|
||||
handle.block_on(fut).map_err(|err| -> Box<EvalAltResult> {
|
||||
EvalAltResult::ErrorRuntime(format!("users: {err}").into(), rhai::Position::NONE).into()
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user