pub struct Container { /* private fields */ }Expand description
A cloneable handle to a continuous-quantity resource (e.g., a tank of liquid, a battery, an inventory of medication).
put(amount) adds material; get(amount) removes it. Both operations
suspend the calling process when they cannot immediately complete:
getsuspends when the current level is below the requested amount.putsuspends when adding the amount would exceed the container’s capacity.
Waiters are served in strict head-of-line FIFO within each queue: a
freshly-arriving request never takes level/space ahead of an already-queued
waiter, even when the current level would let it complete immediately. A
blocked head-of-queue request therefore holds the line for everyone behind
it (matching SimPy’s Container). All clones share the same internal state
(cheap Rc clone). Container is !Send + !Sync, consistent with SimEnv.
A fuel tank: the car needs more than is in stock, so it waits for the tanker truck’s delivery:
use simu::{SimEnv, Container};
let mut env = SimEnv::with_seed(0);
let tank = Container::new(100.0, 20.0); // capacity 100, starts at 20
// A truck delivers 80 units at t = 5.
let h = env.handle();
let t = tank.clone();
env.spawn(async move {
h.timeout(5.0).await;
t.put(80.0).await; // fits (20 + 80 ≤ 100), resolves immediately
});
// A car wants 50 units — more than the current level, so it suspends.
let h2 = env.handle();
let t2 = tank.clone();
env.spawn(async move {
t2.get(50.0).await; // woken by the delivery
assert_eq!(h2.now(), 5.0);
});
env.run();
assert_eq!(tank.level(), 50.0); // 20 + 80 − 50Implementations§
Source§impl Container
impl Container
Sourcepub fn new(capacity: f64, initial_level: f64) -> Self
pub fn new(capacity: f64, initial_level: f64) -> Self
Create a container with the given capacity and initial level.
§Panics
Panics if capacity <= 0, initial_level < 0, or
initial_level > capacity.
Sourcepub fn get_queue_len(&self) -> usize
pub fn get_queue_len(&self) -> usize
Number of consumers currently blocked in the get queue (waiting for
enough material). Excludes abandoned (canceled) requests.
Sourcepub fn put_queue_len(&self) -> usize
pub fn put_queue_len(&self) -> usize
Number of producers currently blocked in the put queue (waiting for
enough free space). Excludes abandoned (canceled) requests.
Sourcepub fn put(&self, amount: f64) -> ContainerPutRequest ⓘ
pub fn put(&self, amount: f64) -> ContainerPutRequest ⓘ
Add amount to the container.
Resolves immediately if level + amount <= capacity; otherwise
suspends until enough space is available.
§Panics
Panics if amount <= 0, or if amount > capacity — the latter could
never complete and, under strict head-of-line FIFO, would block every
later waiter behind it, so it is treated as a programming error. (SimPy
blocks forever here instead; diverging is deliberate.)
Sourcepub fn get(&self, amount: f64) -> ContainerGetRequest ⓘ
pub fn get(&self, amount: f64) -> ContainerGetRequest ⓘ
Remove amount from the container.
Resolves immediately if level >= amount; otherwise suspends until
enough material is available.
§Panics
Panics if amount <= 0, or if amount > capacity — the latter could
never complete and, under strict head-of-line FIFO, would block every
later waiter behind it, so it is treated as a programming error. (SimPy
blocks forever here instead; diverging is deliberate.)
Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for Container
impl !Send for Container
impl !Sync for Container
impl !UnwindSafe for Container
impl Freeze for Container
impl Unpin for Container
impl UnsafeUnpin for Container
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more