A small queue can apply backpressure by accepting work only while capacity remains.

Program

Play the program to choose capacity and see how many jobs stay queued.

capacity
queue_capacity_guard.rs
Replay: real traced execution (multi-file project)
use std::collections::VecDeque;

fn main() {
    let capacity = 2;
    let mut queue = VecDeque::new();
    let accepted = push_jobs(&mut queue, capacity);
    println!("accepted={accepted} queued={}", queue.len());
}

fn push_jobs(queue: &mut VecDeque<&'static str>, capacity: usize) -> usize {
    let jobs = ["parse", "build", "publish"];
    let mut accepted = 0;
    for job in jobs {
        if queue.len() < capacity {
            queue.push_back(job);
            accepted += 1;
        }
    }
    accepted
}
use std::collections::VecDeque;

fn main() {
    let capacity = 1;
    let mut queue = VecDeque::new();
    let accepted = push_jobs(&mut queue, capacity);
    println!("accepted={accepted} queued={}", queue.len());
}

fn push_jobs(queue: &mut VecDeque<&'static str>, capacity: usize) -> usize {
    let jobs = ["parse", "build", "publish"];
    let mut accepted = 0;
    for job in jobs {
        if queue.len() < capacity {
            queue.push_back(job);
            accepted += 1;
        }
    }
    accepted
}
use std::collections::VecDeque;

fn main() {
    let capacity = 3;
    let mut queue = VecDeque::new();
    let accepted = push_jobs(&mut queue, capacity);
    println!("accepted={accepted} queued={}", queue.len());
}

fn push_jobs(queue: &mut VecDeque<&'static str>, capacity: usize) -> usize {
    let jobs = ["parse", "build", "publish"];
    let mut accepted = 0;
    for job in jobs {
        if queue.len() < capacity {
            queue.push_back(job);
            accepted += 1;
        }
    }
    accepted
}
  1. capacity ← 2, queue ← []

    3fn main() {4    let capacit→ 2y = 2; //@capacity=2, 1, 35    let mut queu→ []e = VecDeque::new();6    let accepted = push_jobs(&mut queu[]e, capacit2y);7    println!("accepted={accepted} queued={}", queue.len());
  2. jobs ← ["parse", "build", "publish"], accepted ← 0

    10fn push_jobs(queue: &mut VecDeque<&'static str>, capacity: usize) -> usize {11    let job→ ["parse", "build", "publish"]s = ["parse", "build", "publish"];12    let mut accepte→ 0d = 0;13    for job in jobs {
  3. for job in jobs

    pass 1 of 3
    12let mut accepted = 0;13for jo"parse"b in job["parse", "build", "publish"]s {14    if queue.len() < capacity {
    All 3 passes — pass 1 is the card above
    passjobcapacityaccepted
    1"parse"20 1
    2"build"21 2
    3"publish"
  4. accepted ← 1

    pass 1 of 2
    13for job in jobs {14    if queue.len() < capacit2y {15        queue.push_back(job);16        accepte→ 1d += 1;17    }
  5. accepted ← 2

    pass 2 of 2
    13for job in jobs {14    if queue.len() < capacit2y {15        queue.push_back(job);16        accepte→ 2d += 1;17    }
  6. accepted

    18    }19    accepte2d20}
  7. queue ← ["parse", "build"], accepted ← 2

    5    let mut queue = VecDeque::new();6    let accepte→ 2d = push_jobs(&mut queu→ ["parse", "build"]e, capacit2y);7    println!("accepted={accepted} queued={}", queue.len());8}
    outputaccepted=2 queued=2
  1. capacity ← 1, queue ← []

    3fn main() {4    let capacit→ 1y = 1;5    let mut queu→ []e = VecDeque::new();6    let accepted = push_jobs(&mut queu[]e, capacit1y);7    println!("accepted={accepted} queued={}", queue.len());
  2. jobs ← ["parse", "build", "publish"], accepted ← 0

    10fn push_jobs(queue: &mut VecDeque<&'static str>, capacity: usize) -> usize {11    let job→ ["parse", "build", "publish"]s = ["parse", "build", "publish"];12    let mut accepte→ 0d = 0;13    for job in jobs {
  3. for job in jobs

    pass 1 of 3
    12let mut accepted = 0;13for jo"parse"b in job["parse", "build", "publish"]s {14    if queue.len() < capacity {
    All 3 passes — pass 1 is the card above
    passjobcapacityaccepted
    1"parse"10 1
    2"build"
    3"publish"
  4. accepted ← 1

    13for job in jobs {14    if queue.len() < capacit1y {15        queue.push_back(job);16        accepte→ 1d += 1;17    }
  5. accepted

    18    }19    accepte1d20}
  6. queue ← ["parse"], accepted ← 1

    5    let mut queue = VecDeque::new();6    let accepte→ 1d = push_jobs(&mut queu→ ["parse"]e, capacit1y);7    println!("accepted={accepted} queued={}", queue.len());8}
    outputaccepted=1 queued=1
  1. capacity ← 3, queue ← []

    3fn main() {4    let capacit→ 3y = 3;5    let mut queu→ []e = VecDeque::new();6    let accepted = push_jobs(&mut queu[]e, capacit3y);7    println!("accepted={accepted} queued={}", queue.len());
  2. jobs ← ["parse", "build", "publish"], accepted ← 0

    10fn push_jobs(queue: &mut VecDeque<&'static str>, capacity: usize) -> usize {11    let job→ ["parse", "build", "publish"]s = ["parse", "build", "publish"];12    let mut accepte→ 0d = 0;13    for job in jobs {
  3. for job in jobs

    pass 1 of 3
    12let mut accepted = 0;13for jo"parse"b in job["parse", "build", "publish"]s {14    if queue.len() < capacity {
    All 3 passes — pass 1 is the card above
    passjob
    1"parse"
    2"build"
    3"publish"
  4. accepted ← 1

    pass 1 of 3
    13for job in jobs {14    if queue.len() < capacit3y {15        queue.push_back(job);16        accepte→ 1d += 1;17    }
    All 3 passes — pass 1 is the card above
    passaccepted
    10 1
    21 2
    32 3
  5. accepted

    18    }19    accepte3d20}
  6. queue ← ["parse", "build", "publish"], accepted ← 3

    5    let mut queue = VecDeque::new();6    let accepte→ 3d = push_jobs(&mut queu→ ["parse", "build", "publish"]e, capacit3y);7    println!("accepted={accepted} queued={}", queue.len());8}
    outputaccepted=3 queued=3
capacity The capacity value is a simple bound on queued work.
backpressure The third job is skipped when the queue is already full.
summary The final print reports both accepted work and current queue length.