feat(incremental): a scheduler runs sub-circuits on a worker pool; the aggregate and grid stages placed on two units

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
This commit is contained in:
Claude (dbsp-threads)
2026-10-10 21:00:10 -07:00
committed by Edward Langley
parent c2598f0c60
commit 4ba0cf196e
11 changed files with 843 additions and 1 deletions
+21 -1
View File
@@ -144,6 +144,7 @@ pub struct EdgeSink<K, C, P> {
waiting: Delta<K>,
owes_correction: bool,
closed: bool,
traffic: u64,
}
impl<K: Ord + Clone, C: EdgeCodec<K>, P: Pipe<C::Wire>> EdgeSink<K, C, P> {
@@ -169,6 +170,7 @@ impl<K: Ord + Clone, C: EdgeCodec<K>, P: Pipe<C::Wire>> EdgeSink<K, C, P> {
},
owes_correction: false,
closed: false,
traffic: 0,
}
}
@@ -179,6 +181,11 @@ impl<K: Ord + Clone, C: EdgeCodec<K>, P: Pipe<C::Wire>> EdgeSink<K, C, P> {
}
}
/// Frames sent and requests read so far: a host sees progress when it moves.
pub fn traffic(&self) -> u64 {
self.traffic
}
/// Whether any committed command has not been sent.
pub fn backlog(&self) -> bool {
self.waiting.to > self.waiting.from || self.owes_correction
@@ -217,6 +224,7 @@ impl<K: Ord + Clone, C: EdgeCodec<K>, P: Pipe<C::Wire>> EdgeSink<K, C, P> {
while !self.closed {
match self.pipe.try_recv() {
Ok(wire) => {
self.traffic += 1;
if let Ok(Frame::Request(_)) = self.codec.decode(wire) {
self.owes_correction = true;
}
@@ -241,6 +249,7 @@ impl<K: Ord + Clone, C: EdgeCodec<K>, P: Pipe<C::Wire>> EdgeSink<K, C, P> {
};
match self.pipe.try_send(self.codec.encode(&frame)) {
Ok(()) => {
self.traffic += 1;
self.owes_correction = false;
self.waiting = Delta {
epoch: self.epoch,
@@ -275,6 +284,7 @@ pub struct EdgeSource<K, C, P> {
stale: bool,
asked: bool,
closed: bool,
traffic: u64,
}
impl<K: Ord + Clone + Send + 'static, C: EdgeCodec<K>, P: Pipe<C::Wire>> EdgeSource<K, C, P> {
@@ -291,6 +301,7 @@ impl<K: Ord + Clone + Send + 'static, C: EdgeCodec<K>, P: Pipe<C::Wire>> EdgeSou
stale: true,
asked: false,
closed: false,
traffic: 0,
}
}
@@ -302,6 +313,11 @@ impl<K: Ord + Clone + Send + 'static, C: EdgeCodec<K>, P: Pipe<C::Wire>> EdgeSou
})
}
/// Frames read and requests sent so far: a host sees progress when it moves.
pub fn traffic(&self) -> u64 {
self.traffic
}
/// Whether a correction is wanted and has not arrived.
pub fn stale(&self) -> bool {
self.stale
@@ -326,6 +342,7 @@ impl<K: Ord + Clone + Send + 'static, C: EdgeCodec<K>, P: Pipe<C::Wire>> EdgeSou
match self.pipe.try_recv() {
Ok(wire) => {
read += 1;
self.traffic += 1;
match self.codec.decode(wire) {
Ok(Frame::Delta(d)) => self.on_delta(circuit, d),
Ok(Frame::Correction(c)) => self.on_correction(circuit, c),
@@ -396,7 +413,10 @@ impl<K: Ord + Clone + Send + 'static, C: EdgeCodec<K>, P: Pipe<C::Wire>> EdgeSou
.codec
.encode(&Frame::Request(Request { have: self.stamp() }));
match self.pipe.try_send(wire) {
Ok(()) => self.asked = true,
Ok(()) => {
self.asked = true;
self.traffic += 1;
}
Err(Refused::Full(_)) => {}
Err(Refused::Closed) => self.closed = true,
}
+21
View File
@@ -702,3 +702,24 @@ fn a_circuit_on_each_of_two_threads_equals_one_circuit() {
"[threads] the consumer after the producer thread finishes"
);
}
#[test]
fn a_poll_reads_at_most_the_frames_it_is_given() {
let (a, mut b) = channel_pipes::<Frame<u8>>(8);
let mut c = Circuit::new();
let (i, _) = c.input::<u8>();
let mut src = EdgeSource::new(Direct, a, i);
for through in 0..3 {
let target = Z::new();
let frame = Frame::Correction(Correction {
epoch: 1,
through,
target,
});
b.try_send(frame).unwrap();
}
assert_eq!(src.poll(&mut c, 2), 2, "[budget] two of three");
assert_eq!(src.stamp(), Some(Stamp { epoch: 1, seq: 1 }));
assert_eq!(src.poll(&mut c, 2), 1, "[budget] the rest");
assert_eq!(src.stamp(), Some(Stamp { epoch: 1, seq: 2 }));
}