poisoned_queue.rs
Overview
This file defines a generic data structure named PoisonedQueue designed for temporarily holding messages or items that could not be dispatched immediately due to the absence of a valid destination. The queue uses a buffer with a fixed capacity and evicts the oldest items when the buffer exceeds this capacity. This ensures that the queue never grows beyond a predefined size, albeit with a simple and potentially inefficient eviction strategy.
Structure and Functionality
PoisonedQueue
A generic struct that internally uses a VecDeque<T> as a buffer to store items of type T. The queue has a fixed capacity and supports adding new items and selectively retaining items based on a predicate.
Fields
buffer: VecDeque<T>
The underlying double-ended queue storing the buffered items.capacity: usize
The maximum number of items that the queue can hold before evicting the oldest entry.
Methods
new(capacity: usize) -> Self
Creates a new PoisonedQueue with the specified capacity.
Parameters:
capacity: Maximum number of items the queue can hold.
Returns:
A new instance ofPoisonedQueue.Usage Example:
let queue: PoisonedQueue<String> = PoisonedQueue::new(100);Implementation Detail:
The internalVecDequeis initialized withcapacity + 1to optimize the push/pop operations without immediate reallocations.
push(&mut self, item: T)
Adds an item to the back of the queue. If the buffer exceeds the configured capacity after insertion, the oldest item (front of the queue) is removed (evicted).
Parameters:
item: The item of typeTto be added to the queue.
Returns:
No return value.Usage Example:
queue.push("message1".to_string());Implementation Detail:
The method pushes the item at the back of theVecDeque. If the queue length exceedscapacity, it pops an item from the front. This eviction strategy is straightforward but acknowledged as inefficient in the comments.
retain<F>(&mut self, f: F) where F: FnMut(&T) -> bool
Retains only the items in the queue that satisfy the predicate function f. All other items are removed.
Parameters:
f: A closure or function that takes a reference to an item and returnstrueif the item should be retained orfalseotherwise.
Returns:
No return value.Usage Example:
queue.retain(|msg| !msg.contains("error"));Implementation Detail:
This method delegates toVecDeque'sretainmethod, allowing for efficient in-place filtering of the buffer.
Implementation Notes
The internal use of
VecDequeprovides efficient push and pop operations at both ends of the queue, a suitable choice for a FIFO buffer.The eviction strategy always removes the oldest item when capacity is exceeded, which is simple but may lead to loss of potentially important messages if the queue is frequently at capacity.
The comment in the source code notes the implementation as "super inefficient" but quick, indicating a trade-off between simplicity and performance that might be improved in future iterations.
Interaction with Other Parts of the System
This queue is intended to be used in message dispatching systems where messages might fail to be delivered immediately. It temporarily stores these "poisoned" or undeliverable messages until a destination becomes available. Other components responsible for dispatching messages can push failed messages into this queue and later attempt to re-dispatch them by applying the retain method or other logic.
Because the queue is generic over type T, it is flexible and can be integrated with various message or event types handled elsewhere in the application.
Diagram
classDiagram
class PoisonedQueue~T~ {
-buffer: VecDeque~T~
-capacity: usize
+new(capacity: usize)
+push(item: T)
+retain(f: FnMut(&T) -> bool)
}
This class diagram shows the PoisonedQueue structure with its two fields and three primary methods, highlighting its encapsulated buffer and capacity management logic.