1use std::collections::HashMap;
7use std::sync::Arc;
8
9use anyhow::Result;
10use async_trait::async_trait;
11use bytes::Bytes;
12use folk_api::{RpcHandler, RpcRegistrar};
13use tokio::sync::RwLock;
14use tracing::debug;
15
16#[derive(Clone)]
19pub struct InProcessRegistry {
20 handlers: Arc<RwLock<HashMap<String, RpcHandler>>>,
21}
22
23impl InProcessRegistry {
24 pub fn new() -> Arc<Self> {
25 Arc::new(Self {
26 handlers: Arc::new(RwLock::new(HashMap::new())),
27 })
28 }
29
30 pub async fn call(&self, method: &str, payload: Bytes) -> Result<Bytes> {
32 let handlers = self.handlers.read().await;
33 let handler = handlers
34 .get(method)
35 .ok_or_else(|| anyhow::anyhow!("method not found: {method}"))?
36 .clone();
37 drop(handlers);
38
39 handler(payload).await
40 }
41
42 pub async fn methods(&self) -> Vec<String> {
44 self.handlers.read().await.keys().cloned().collect()
45 }
46}
47
48#[async_trait]
49impl RpcRegistrar for InProcessRegistry {
50 async fn register_raw(&self, name: String, handler: RpcHandler) {
51 debug!(method = %name, "registered plugin method");
52 self.handlers.write().await.insert(name, handler);
53 }
54}