Try to enqueue a value. Returns `Err(BridgeError::Full)` if the ring is full, or `Err(BridgeError::Disconnected)` if the consumer was dropped.
(&mut self, value: T)
| 155 | /// Try to enqueue a value. Returns `Err(BridgeError::Full)` if the ring is full, |
| 156 | /// or `Err(BridgeError::Disconnected)` if the consumer was dropped. |
| 157 | pub fn try_push(&mut self, value: T) -> Result<()> { |
| 158 | if self.shared.disconnected.load(Ordering::Relaxed) { |
| 159 | return Err(BridgeError::Disconnected { side: "consumer" }); |
| 160 | } |
| 161 | |
| 162 | let tail = self.shared.tail.value.load(Ordering::Relaxed); |
| 163 | |
| 164 | // Fast path: check cached head first (avoids atomic load). |
| 165 | if tail.wrapping_sub(self.cached_head) >= self.shared.capacity as u64 { |
| 166 | // Slow path: refresh cached head from the atomic. |
| 167 | self.cached_head = self.shared.head.value.load(Ordering::Acquire); |
| 168 | |
| 169 | if tail.wrapping_sub(self.cached_head) >= self.shared.capacity as u64 { |
| 170 | self.shared.metrics.record_full(); |
| 171 | return Err(BridgeError::Full { |
| 172 | capacity: self.shared.capacity, |
| 173 | pending: (tail.wrapping_sub(self.cached_head)) as usize, |
| 174 | }); |
| 175 | } |
| 176 | } |
| 177 | |
| 178 | let idx = (tail as usize) & self.shared.mask; |
| 179 | |
| 180 | // SAFETY: We have exclusive write access to this slot because: |
| 181 | // 1. We are the only producer (SPSC). |
| 182 | // 2. The consumer's head hasn't reached this slot yet (checked above). |
| 183 | unsafe { |
| 184 | (*self.shared.slots[idx].get()) = Some(value); |
| 185 | } |
| 186 | |
| 187 | // Make the value visible to the consumer. |
| 188 | self.shared |
| 189 | .tail |
| 190 | .value |
| 191 | .store(tail.wrapping_add(1), Ordering::Release); |
| 192 | |
| 193 | self.shared.metrics.record_push(); |
| 194 | Ok(()) |
| 195 | } |
| 196 | |
| 197 | /// Returns the current queue utilization as a percentage (0-100). |
| 198 | pub fn utilization(&self) -> u8 { |