Kernel: read what the table has before letting kept routes go
Once every peer had sent all its routes, the kernel task let go of the routes kept from the earlier run that the table did not have, at once. But "the table has" and "the kernel task has read" are not the same moment: a route a peer sent just before its End-of-RIB could still be unread in the table's journal, in which case it was taken out of the kernel and put back a moment later. The interop lab saw this now and then as "N routes were taken out of the kernel over the restart". The task now reads the table to the end before it decides what is unconfirmed; follow() says whether the reader is caught up. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
175a13d506
commit
724bb99f11
1 file changed
+11
-4
@@ -746,11 +746,12 @@ impl Task {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Takes the next changes of best route from the routing table and
|
/// Takes the next changes of best route from the routing table and
|
||||||
/// hands over what brings the kernel in step with them.
|
/// hands over what brings the kernel in step with them. Returns whether
|
||||||
async fn follow(&mut self, reader: &mut Reader) -> Result<(), FibError> {
|
/// the reader has read everything the table has for it.
|
||||||
|
async fn follow(&mut self, reader: &mut Reader) -> Result<bool, FibError> {
|
||||||
let mut news = Vec::with_capacity(BATCH);
|
let mut news = Vec::with_capacity(BATCH);
|
||||||
// Only what is needed is taken while the table is held.
|
// Only what is needed is taken while the table is held.
|
||||||
reader.poll(BATCH, |event| {
|
let progress = reader.poll(BATCH, |event| {
|
||||||
news.push(match event {
|
news.push(match event {
|
||||||
Event::Reset => News::Reset,
|
Event::Reset => News::Reset,
|
||||||
Event::Synced => News::Synced,
|
Event::Synced => News::Synced,
|
||||||
@@ -822,7 +823,8 @@ impl Task {
|
|||||||
News::Withdrawn(prefix) => ops.extend(self.plan.withdrawn(prefix)),
|
News::Withdrawn(prefix) => ops.extend(self.plan.withdrawn(prefix)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.send(ops, whole_table).await
|
self.send(ops, whole_table).await?;
|
||||||
|
Ok(progress.caught_up)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Takes in what the writer says became of what it was given.
|
/// Takes in what the writer says became of what it was given.
|
||||||
@@ -1130,6 +1132,11 @@ pub(crate) async fn run(
|
|||||||
}
|
}
|
||||||
}, if release_at.is_some() => {
|
}, if release_at.is_some() => {
|
||||||
release_at = None;
|
release_at = None;
|
||||||
|
// What the table has by now, the kernel is to have before
|
||||||
|
// anything is let go of: a route a peer sent just before
|
||||||
|
// its End-of-RIB may not have been read yet, and would be
|
||||||
|
// taken out only to be put back.
|
||||||
|
while !task.follow(&mut reader).await? {}
|
||||||
task.keeping = false;
|
task.keeping = false;
|
||||||
let stale = task.plan.release();
|
let stale = task.plan.release();
|
||||||
info!(
|
info!(
|
||||||
|
|||||||
Reference in new issue
Block a user