pub struct Bulkhead { /* private fields */ }Expand description
A concurrency limiter: a counting semaphore that caps in-flight operations.
Bulkhead is a small, Copy value holding a fixed capacity and the number
of permits currently held (in_flight). try_acquire
takes permits when room exists and reports whether it succeeded;
release returns them.
The capacity is clamped to at least 1 at construction, so a bulkhead can
always admit one operation. The invariant in_flight <= capacity holds on
every public path, so available never underflows.
Implementations§
Source§impl Bulkhead
impl Bulkhead
Sourcepub const fn new(capacity: usize) -> Self
pub const fn new(capacity: usize) -> Self
Creates a bulkhead allowing at most capacity concurrent permits.
capacity is clamped to a minimum of 1: a bulkhead always admits at
least one operation, so a 0 would only ever reject and is treated as
1.
Examples found in repository?
13fn main() {
14 // Allow at most three concurrent calls to a downstream service.
15 let mut bulkhead = Bulkhead::new(3);
16
17 // Six requests arrive while none have finished yet.
18 println!("capacity: {}", bulkhead.capacity());
19 for request in 0..6 {
20 if bulkhead.try_acquire_one() {
21 println!(
22 "request {request}: admitted ({} in flight)",
23 bulkhead.in_flight()
24 );
25 // ... start the work; release the permit when it completes ...
26 } else {
27 println!("request {request}: rejected (bulkhead full), shed load");
28 }
29 }
30
31 // Two of the in-flight operations finish and return their permits.
32 bulkhead.release(2);
33 println!(
34 "\nafter two completions: {} available",
35 bulkhead.available()
36 );
37
38 // Room exists again, so the next request is admitted.
39 if bulkhead.try_acquire_one() {
40 println!("retry: admitted ({} in flight)", bulkhead.in_flight());
41 }
42}Sourcepub const fn capacity(&self) -> usize
pub const fn capacity(&self) -> usize
Returns the maximum number of concurrent permits.
Examples found in repository?
13fn main() {
14 // Allow at most three concurrent calls to a downstream service.
15 let mut bulkhead = Bulkhead::new(3);
16
17 // Six requests arrive while none have finished yet.
18 println!("capacity: {}", bulkhead.capacity());
19 for request in 0..6 {
20 if bulkhead.try_acquire_one() {
21 println!(
22 "request {request}: admitted ({} in flight)",
23 bulkhead.in_flight()
24 );
25 // ... start the work; release the permit when it completes ...
26 } else {
27 println!("request {request}: rejected (bulkhead full), shed load");
28 }
29 }
30
31 // Two of the in-flight operations finish and return their permits.
32 bulkhead.release(2);
33 println!(
34 "\nafter two completions: {} available",
35 bulkhead.available()
36 );
37
38 // Room exists again, so the next request is admitted.
39 if bulkhead.try_acquire_one() {
40 println!("retry: admitted ({} in flight)", bulkhead.in_flight());
41 }
42}Sourcepub const fn in_flight(&self) -> usize
pub const fn in_flight(&self) -> usize
Returns the number of permits currently held.
Examples found in repository?
13fn main() {
14 // Allow at most three concurrent calls to a downstream service.
15 let mut bulkhead = Bulkhead::new(3);
16
17 // Six requests arrive while none have finished yet.
18 println!("capacity: {}", bulkhead.capacity());
19 for request in 0..6 {
20 if bulkhead.try_acquire_one() {
21 println!(
22 "request {request}: admitted ({} in flight)",
23 bulkhead.in_flight()
24 );
25 // ... start the work; release the permit when it completes ...
26 } else {
27 println!("request {request}: rejected (bulkhead full), shed load");
28 }
29 }
30
31 // Two of the in-flight operations finish and return their permits.
32 bulkhead.release(2);
33 println!(
34 "\nafter two completions: {} available",
35 bulkhead.available()
36 );
37
38 // Room exists again, so the next request is admitted.
39 if bulkhead.try_acquire_one() {
40 println!("retry: admitted ({} in flight)", bulkhead.in_flight());
41 }
42}Sourcepub const fn available(&self) -> usize
pub const fn available(&self) -> usize
Returns how many more permits can be acquired right now.
Examples found in repository?
13fn main() {
14 // Allow at most three concurrent calls to a downstream service.
15 let mut bulkhead = Bulkhead::new(3);
16
17 // Six requests arrive while none have finished yet.
18 println!("capacity: {}", bulkhead.capacity());
19 for request in 0..6 {
20 if bulkhead.try_acquire_one() {
21 println!(
22 "request {request}: admitted ({} in flight)",
23 bulkhead.in_flight()
24 );
25 // ... start the work; release the permit when it completes ...
26 } else {
27 println!("request {request}: rejected (bulkhead full), shed load");
28 }
29 }
30
31 // Two of the in-flight operations finish and return their permits.
32 bulkhead.release(2);
33 println!(
34 "\nafter two completions: {} available",
35 bulkhead.available()
36 );
37
38 // Room exists again, so the next request is admitted.
39 if bulkhead.try_acquire_one() {
40 println!("retry: admitted ({} in flight)", bulkhead.in_flight());
41 }
42}Sourcepub fn try_acquire(&mut self, permits: usize) -> bool
pub fn try_acquire(&mut self, permits: usize) -> bool
Tries to acquire permits permits at once.
Returns true and reserves them if at least permits are available;
otherwise returns false and changes nothing (no partial acquire). A
request for more than capacity always fails.
Acquiring 0 permits always succeeds and reserves nothing.
Sourcepub fn try_acquire_one(&mut self) -> bool
pub fn try_acquire_one(&mut self) -> bool
Tries to acquire a single permit. See try_acquire.
Examples found in repository?
13fn main() {
14 // Allow at most three concurrent calls to a downstream service.
15 let mut bulkhead = Bulkhead::new(3);
16
17 // Six requests arrive while none have finished yet.
18 println!("capacity: {}", bulkhead.capacity());
19 for request in 0..6 {
20 if bulkhead.try_acquire_one() {
21 println!(
22 "request {request}: admitted ({} in flight)",
23 bulkhead.in_flight()
24 );
25 // ... start the work; release the permit when it completes ...
26 } else {
27 println!("request {request}: rejected (bulkhead full), shed load");
28 }
29 }
30
31 // Two of the in-flight operations finish and return their permits.
32 bulkhead.release(2);
33 println!(
34 "\nafter two completions: {} available",
35 bulkhead.available()
36 );
37
38 // Room exists again, so the next request is admitted.
39 if bulkhead.try_acquire_one() {
40 println!("retry: admitted ({} in flight)", bulkhead.in_flight());
41 }
42}Sourcepub fn release(&mut self, permits: usize)
pub fn release(&mut self, permits: usize)
Releases permits permits back to the bulkhead.
Saturates at zero, so releasing more than are held simply empties the
bulkhead rather than underflowing — a release without a matching acquire
cannot drive in_flight negative or panic.
Examples found in repository?
13fn main() {
14 // Allow at most three concurrent calls to a downstream service.
15 let mut bulkhead = Bulkhead::new(3);
16
17 // Six requests arrive while none have finished yet.
18 println!("capacity: {}", bulkhead.capacity());
19 for request in 0..6 {
20 if bulkhead.try_acquire_one() {
21 println!(
22 "request {request}: admitted ({} in flight)",
23 bulkhead.in_flight()
24 );
25 // ... start the work; release the permit when it completes ...
26 } else {
27 println!("request {request}: rejected (bulkhead full), shed load");
28 }
29 }
30
31 // Two of the in-flight operations finish and return their permits.
32 bulkhead.release(2);
33 println!(
34 "\nafter two completions: {} available",
35 bulkhead.available()
36 );
37
38 // Room exists again, so the next request is admitted.
39 if bulkhead.try_acquire_one() {
40 println!("retry: admitted ({} in flight)", bulkhead.in_flight());
41 }
42}Sourcepub fn release_one(&mut self)
pub fn release_one(&mut self)
Releases a single permit. See release.