Skip to content

Commit

Permalink
Adds retriers to WTClient and updates code and tests accordingly
Browse files Browse the repository at this point in the history
Adds a map in the `WTClient` containing the active retriers and their state.
Retriers are active only if they are running or idle.

Adaps the plugin logic to get advantage of this data to better handle retries.
Also adapts tests to check this is consistent.
  • Loading branch information
sr-gi committed Dec 29, 2022
1 parent ad7fa06 commit 2aae5d8
Show file tree
Hide file tree
Showing 3 changed files with 298 additions and 90 deletions.
57 changes: 33 additions & 24 deletions watchtower-plugin/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,36 +293,45 @@ async fn retry_tower(
) -> Result<serde_json::Value, Error> {
let tower_id = TowerId::try_from(v).map_err(|e| anyhow!(e))?;
let state = plugin.state().lock().unwrap();
if let Some(status) = state.get_tower_status(&tower_id) {
if status.is_temporary_unreachable() {
return Err(anyhow!("{} is already being retried", tower_id));
} else if !status.is_retryable() {
if let Some(tower_status) = state.get_tower_status(&tower_id) {
if let Some(retrier_status) = state.retriers.get(&tower_id) {
if retrier_status.is_idle() {
// We don't send any associated data in this case given the idle retrier already has it all.
state
.unreachable_towers
.send((tower_id, RevocationData::None))
.map_err(|e| anyhow!(e))?;
} else {
// Status can only be running or idle for data in the retriers map.
return Err(anyhow!("{} is already being retried", tower_id));
}
} else if tower_status.is_retryable() {
// We do send associated data here given there is no retrier associated to this tower.
state
.unreachable_towers
.send((
tower_id,
RevocationData::Stale(
state
.towers
.get(&tower_id)
.unwrap()
.pending_appointments
.iter()
.cloned()
.collect(),
),
))
.map_err(|e| anyhow!(e))?;
} else {
return Err(anyhow!(
"Tower status must be unreachable or have a subscription issue to manually retry",
));
}

state
.unreachable_towers
.send((
tower_id,
RevocationData::Stale(
state
.towers
.get(&tower_id)
.unwrap()
.pending_appointments
.iter()
.cloned()
.collect(),
),
))
.map_err(|e| anyhow!(e))?;

Ok(json!(format!("Retrying {}", tower_id)))
} else {
Err(anyhow!("Unknown tower {}", tower_id))
return Err(anyhow!("Unknown tower {}", tower_id));
}
Ok(json!(format!("Retrying {}", tower_id)))
}

/// Forgets about a tower wiping out all local data associated to it.
Expand Down
Loading

0 comments on commit 2aae5d8

Please sign in to comment.