use std::sync::Arc;
use corium_authz::source::{PolicySource, SourceError};
use corium_db::Db;
use crate::node::TransactorNode;
pub struct NodePolicySource {
node: Arc<TransactorNode>,
db: String,
}
impl NodePolicySource {
pub fn new(node: Arc<TransactorNode>, db: impl Into<String>) -> Self {
Self {
node,
db: db.into(),
}
}
}
#[tonic::async_trait]
impl PolicySource for NodePolicySource {
fn name(&self) -> &str {
&self.db
}
async fn snapshot(&self) -> Result<Db, SourceError> {
match self.node.db_state(&self.db).await {
Ok(state) => Ok(state.db()),
Err(crate::node::NodeError::UnknownDb(name)) => Err(SourceError::Unavailable(name)),
Err(error) => Err(SourceError::Failed {
db: self.db.clone(),
reason: error.to_string(),
}),
}
}
async fn changed(&self, basis_t: u64) {
let Ok(state) = self.node.db_state(&self.db).await else {
tokio::time::sleep(corium_authz::source::DEFAULT_POLL_INTERVAL).await;
return;
};
let mut basis = state.basis_watch();
let _ = basis.wait_for(|current| *current > basis_t).await;
}
}