use crate::TryLock;
use pdk_core::classy::extract::context::ConfigureContext;
use pdk_core::classy::extract::{Extract, FromContext};
use pdk_core::classy::{Clock, SharedData};
use pdk_core::policy_context::api::Metadata;
use std::convert::Infallible;
use std::rc::Rc;
use std::time::Duration;
const DEFAULT_EXPIRATION: Duration = Duration::from_secs(60);
pub struct LockBuilder {
clock: Rc<dyn Clock>,
shared_data: Rc<dyn SharedData>,
expiration: Duration,
prefix: String,
}
impl FromContext<ConfigureContext> for LockBuilder {
type Error = Infallible;
fn from_context(context: &ConfigureContext) -> Result<Self, Self::Error> {
let clock: Rc<dyn Clock> = context.extract()?;
let shared_data: Rc<dyn SharedData> = context.extract()?;
let metadata: Metadata = context.extract()?;
Ok(LockBuilder {
clock,
shared_data,
expiration: DEFAULT_EXPIRATION,
prefix: format!(
"isolated-lock-{}-{}",
metadata.policy_metadata.policy_name, metadata.policy_metadata.policy_namespace
),
})
}
}
impl LockBuilder {
#[allow(clippy::new_ret_no_self)]
pub fn new(&self, lock_id: String) -> LockBuilderInstance {
LockBuilderInstance {
clock: Rc::clone(&self.clock),
shared_data: Rc::clone(&self.shared_data),
expiration: self.expiration,
prefix: self.prefix.clone(),
key: lock_id,
}
}
}
pub struct LockBuilderInstance {
clock: Rc<dyn Clock>,
shared_data: Rc<dyn SharedData>,
expiration: Duration,
prefix: String,
key: String,
}
impl LockBuilderInstance {
pub fn expiration(mut self, expiration: Duration) -> Self {
self.expiration = expiration;
self
}
pub fn shared(mut self) -> Self {
self.prefix = "shared-lock".to_string();
self
}
pub fn build(self) -> TryLock {
TryLock::new(
format!("{}-{}", self.prefix, self.key),
self.expiration,
self.clock,
self.shared_data,
)
}
}