huskies: merge 1009
This commit is contained in:
@@ -44,7 +44,7 @@ pub(super) async fn scan_and_claim(
|
||||
// Only claim stories in execution stages (Coding, Qa, Merge).
|
||||
if !matches!(
|
||||
item.stage(),
|
||||
crate::pipeline_state::Stage::Coding
|
||||
crate::pipeline_state::Stage::Coding { .. }
|
||||
| crate::pipeline_state::Stage::Qa
|
||||
| crate::pipeline_state::Stage::Merge { .. }
|
||||
) {
|
||||
@@ -65,19 +65,25 @@ pub(super) async fn scan_and_claim(
|
||||
continue;
|
||||
}
|
||||
|
||||
let item_claim = match item.stage() {
|
||||
crate::pipeline_state::Stage::Coding { claim } => claim.as_ref(),
|
||||
crate::pipeline_state::Stage::Merge { claim, .. } => claim.as_ref(),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
// If already claimed by us, skip.
|
||||
if item.claim().is_some_and(|c| c.node == our_node) {
|
||||
if item_claim.is_some_and(|c| c.agent.0 == our_node) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If claimed by another node, respect the claim while it is fresh.
|
||||
// Once the TTL expires the claim is considered stale regardless of
|
||||
// whether the holder appears alive — displacement is purely TTL-driven.
|
||||
if let Some(claim) = item.claim()
|
||||
&& claim.node != our_node
|
||||
if let Some(claim) = item_claim
|
||||
&& claim.agent.0 != our_node
|
||||
{
|
||||
let now = chrono::Utc::now().timestamp() as u64;
|
||||
let age = now.saturating_sub(claim.at) as f64;
|
||||
let age = now.saturating_sub(claim.claimed_at.timestamp() as u64) as f64;
|
||||
if age < CLAIM_TIMEOUT_SECS {
|
||||
// Claim is still fresh — respect it.
|
||||
continue;
|
||||
@@ -87,7 +93,7 @@ pub(super) async fn scan_and_claim(
|
||||
"[agent-mode] Displacing stale claim on '{}' held by {:.12}… \
|
||||
(age {}s > TTL {}s)",
|
||||
item.story_id(),
|
||||
claim.node,
|
||||
claim.agent.0,
|
||||
age as u64,
|
||||
CLAIM_TIMEOUT_SECS as u64,
|
||||
);
|
||||
@@ -179,7 +185,7 @@ pub(super) fn reclaim_timed_out_work(_project_root: &Path) {
|
||||
for item in &items {
|
||||
if !matches!(
|
||||
item.stage(),
|
||||
crate::pipeline_state::Stage::Coding
|
||||
crate::pipeline_state::Stage::Coding { .. }
|
||||
| crate::pipeline_state::Stage::Qa
|
||||
| crate::pipeline_state::Stage::Merge { .. }
|
||||
) {
|
||||
@@ -189,13 +195,19 @@ pub(super) fn reclaim_timed_out_work(_project_root: &Path) {
|
||||
// Release the claim if the TTL has expired — regardless of whether the
|
||||
// holder is still alive. A node actively working should refresh its
|
||||
// claim before the TTL window closes.
|
||||
if let Some(claim) = item.claim() {
|
||||
let age = now as u64 - claim.at.min(now as u64);
|
||||
let reclaim_claim = match item.stage() {
|
||||
crate::pipeline_state::Stage::Coding { claim } => claim.as_ref(),
|
||||
crate::pipeline_state::Stage::Merge { claim, .. } => claim.as_ref(),
|
||||
_ => None,
|
||||
};
|
||||
if let Some(claim) = reclaim_claim {
|
||||
let claim_ts = claim.claimed_at.timestamp() as u64;
|
||||
let age = now as u64 - claim_ts.min(now as u64);
|
||||
if age as f64 >= CLAIM_TIMEOUT_SECS {
|
||||
slog!(
|
||||
"[agent-mode] Releasing stale claim on '{}' held by {:.12}… (age {}s)",
|
||||
item.story_id(),
|
||||
claim.node,
|
||||
claim.agent.0,
|
||||
age,
|
||||
);
|
||||
crdt_state::release_claim(item.story_id());
|
||||
|
||||
Reference in New Issue
Block a user