active_uuid_registry/
raii.rs1use std::sync::atomic::{AtomicBool, Ordering};
4use std::sync::Arc;
5
6use uuid::Uuid;
7
8use crate::registry::{self, OwnedNamespaceSignature, WriteAccess};
9use crate::{ContextString, NamespaceString, UuidPoolError};
10
11struct OwnedNamespaceInner {
12 namespace: parking_lot::Mutex<NamespaceString>,
13 signature: OwnedNamespaceSignature,
14 invalidated: AtomicBool,
18}
19
20impl Drop for OwnedNamespaceInner {
21 fn drop(&mut self) {
22 if self.invalidated.load(Ordering::Acquire) {
24 return;
25 }
26 let namespace = self.namespace.get_mut().clone();
27 let _ = registry::release_owned_namespace(&namespace, &self.signature);
30 }
31}
32
33pub struct OwnedNamespace {
45 inner: Arc<OwnedNamespaceInner>,
46}
47
48impl Clone for OwnedNamespace {
49 fn clone(&self) -> Self {
50 Self { inner: self.inner.clone() }
51 }
52}
53
54impl OwnedNamespace {
55 pub(crate) fn new(namespace: NamespaceString, signature: OwnedNamespaceSignature) -> Self {
56 Self {
57 inner: Arc::new(OwnedNamespaceInner {
58 namespace: parking_lot::Mutex::new(namespace),
59 signature,
60 invalidated: AtomicBool::new(false),
61 }),
62 }
63 }
64
65 fn access(&self) -> WriteAccess<'_> {
66 WriteAccess::owned(&self.inner.signature)
67 }
68
69 fn current_namespace(&self) -> NamespaceString {
70 self.inner.namespace.lock().clone()
71 }
72
73 fn ensure_active(&self) -> Result<(), UuidPoolError> {
74 if self.inner.invalidated.load(Ordering::Acquire) {
75 return Err(UuidPoolError::UnauthorizedNamespaceWriteAccessError(format!(
76 "Namespace '{}' ownership has already been released",
77 self.current_namespace()
78 )));
79 }
80 Ok(())
81 }
82
83 pub fn namespace(&self) -> NamespaceString {
85 self.current_namespace()
86 }
87
88 pub fn reserve_id(&self, context: &str) -> Result<Uuid, UuidPoolError> {
91 self.reserve_id_with(context, crate::interface::DEFAULT_UUID_BASE, crate::interface::DEFAULT_MAX_RETRIES)
92 }
93
94 pub fn reserve_id_with_base(&self, context: &str, base: u32) -> Result<Uuid, UuidPoolError> {
96 self.reserve_id_with(context, base, crate::interface::DEFAULT_MAX_RETRIES)
97 }
98
99 pub fn reserve_id_with(&self, context: &str, base: u32, max_retries: usize) -> Result<Uuid, UuidPoolError> {
101 self.ensure_active()?;
102 registry::random_uuid(&self.current_namespace(), context, base, max_retries, 0, self.access())
103 }
104
105 pub fn add_id(&self, context: &str, uuid: Uuid) -> Result<(), UuidPoolError> {
107 self.ensure_active()?;
108 registry::add_uuid_to_pool(&self.current_namespace(), context, &uuid, self.access())
109 }
110
111 pub fn remove_id(&self, context: &str, uuid: Uuid) -> Result<(), UuidPoolError> {
113 self.ensure_active()?;
114 registry::remove_uuid_from_pool(&self.current_namespace(), context, &uuid, self.access())
115 }
116
117 pub fn replace_id(&self, context: &str, old_uuid: Uuid, new_uuid: Uuid) -> Result<(), UuidPoolError> {
119 self.ensure_active()?;
120 registry::replace_uuid_in_pool(&self.current_namespace(), context, &old_uuid, &new_uuid, self.access())
121 }
122
123 pub fn clear_context(&self, context: &str) -> Result<(), UuidPoolError> {
125 self.ensure_active()?;
126 registry::clear_context(&self.current_namespace(), context, self.access())
127 }
128
129 pub fn clear_all_contexts(&self) -> Result<(), UuidPoolError> {
131 self.ensure_active()?;
132 registry::clear_all_contexts(&self.current_namespace(), self.access())
133 }
134
135 pub fn drain_context(&self, context: &str) -> Result<Vec<(ContextString, Uuid)>, UuidPoolError> {
137 self.ensure_active()?;
138 registry::drain_context(&self.current_namespace(), context, self.access())
139 }
140
141 pub fn drain_all_contexts(&self) -> Result<Vec<(NamespaceString, ContextString, Uuid)>, UuidPoolError> {
143 self.ensure_active()?;
144 registry::drain_all_contexts(&self.current_namespace(), self.access())
145 }
146
147 pub fn rename(&self, new_namespace: &str) -> Result<(), UuidPoolError> {
150 self.ensure_active()?;
151 let mut guard = self.inner.namespace.lock();
152 registry::replace_namespace(&guard, new_namespace, self.access())?;
153 *guard = new_namespace.to_string();
154 Ok(())
155 }
156
157 pub fn remove(self) -> Result<(), UuidPoolError> {
163 self.ensure_active()?;
164 let namespace = self.current_namespace();
165 registry::release_owned_namespace(&namespace, &self.inner.signature)?;
166 self.inner.invalidated.store(true, Ordering::Release);
167 Ok(())
168 }
169}