ensure sufficient number of tickets before performing testrun assignment
This commit is contained in:
Generated
+1
-1
@@ -7768,7 +7768,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-node-status-api"
|
||||
version = "4.6.1"
|
||||
version = "4.6.2-rc"
|
||||
dependencies = [
|
||||
"ammonia",
|
||||
"anyhow",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "nym-node-status-api"
|
||||
version = "4.6.1"
|
||||
version = "4.6.2-rc"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
@@ -58,6 +58,31 @@ async fn request_testrun(
|
||||
return Err(HttpError::no_testruns_available());
|
||||
}
|
||||
|
||||
// 1. guard against other agents attempting to get testruns so that we would be able to check
|
||||
// for ticketbook count without cross-interaction
|
||||
let _guard = state.lock_testrun_assignment().await;
|
||||
|
||||
// 2. check if we have enough ticketbooks of ALL types before assigning the run
|
||||
match state
|
||||
.ticketbook_manager_state()
|
||||
.has_enough_ticketbooks()
|
||||
.await
|
||||
{
|
||||
Err(err) => {
|
||||
return Err(HttpError::internal_with_logging(format!(
|
||||
"failed to check ticketbook storage: {err}"
|
||||
)));
|
||||
}
|
||||
Ok(false) => {
|
||||
tracing::warn!("not enough ticketbooks available, rejecting testrun assignment");
|
||||
return Err(HttpError::internal_with_logging(
|
||||
"not enough ticketbooks available to assign a testrun",
|
||||
));
|
||||
}
|
||||
Ok(true) => (),
|
||||
}
|
||||
|
||||
// 3. attempt to assign the testrun itself
|
||||
match db::queries::testruns::assign_oldest_testrun(&mut conn).await {
|
||||
Ok(res) => {
|
||||
let Some(assignment) = res else {
|
||||
@@ -71,6 +96,7 @@ async fn request_testrun(
|
||||
assignment.gateway_identity_key,
|
||||
);
|
||||
|
||||
// 4. retrieve required ticketbooks (we should always have sufficient number as we hold an exclusive lock)
|
||||
let materials = state
|
||||
.ticketbook_manager_state()
|
||||
.attempt_assign_ticket_materials(assignment.testrun_id)
|
||||
|
||||
@@ -11,7 +11,7 @@ use semver::Version;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{collections::HashMap, sync::Arc, time::Duration};
|
||||
use time::UtcDateTime;
|
||||
use tokio::sync::RwLock;
|
||||
use tokio::sync::{Mutex, MutexGuard, RwLock};
|
||||
use tracing::{error, instrument, trace, warn};
|
||||
use utoipa::ToSchema;
|
||||
|
||||
@@ -42,6 +42,7 @@ pub(crate) struct AppState {
|
||||
node_delegations: Arc<RwLock<DelegationsCache>>,
|
||||
bin_info: BinaryInfo,
|
||||
ticketbook_manager_state: TicketbookManagerState,
|
||||
testrun_assignment_guard: Arc<Mutex<()>>,
|
||||
}
|
||||
|
||||
impl AppState {
|
||||
@@ -66,6 +67,7 @@ impl AppState {
|
||||
node_delegations,
|
||||
bin_info: BinaryInfo::new(),
|
||||
ticketbook_manager_state,
|
||||
testrun_assignment_guard: Arc::new(Default::default()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,6 +83,10 @@ impl AppState {
|
||||
self.agent_key_list.contains(agent_pubkey)
|
||||
}
|
||||
|
||||
pub(crate) async fn lock_testrun_assignment(&self) -> MutexGuard<'_, ()> {
|
||||
self.testrun_assignment_guard.lock().await
|
||||
}
|
||||
|
||||
pub(crate) fn agent_max_count(&self) -> i64 {
|
||||
self.agent_max_count
|
||||
}
|
||||
|
||||
@@ -53,6 +53,26 @@ impl TicketbookManagerState {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn has_enough_ticketbooks(&self) -> anyhow::Result<bool> {
|
||||
let mut required = HashMap::new();
|
||||
for typ in &self.buffered_ticket_types {
|
||||
let count = required.entry(*typ).or_insert(0);
|
||||
*count += 1;
|
||||
}
|
||||
|
||||
for (typ, required_count) in required {
|
||||
let available = self.storage.available_tickets_of_type(typ).await?;
|
||||
if available < required_count {
|
||||
warn!(
|
||||
"not enough tickets of type {typ} available in storage, required {required_count}, available {available}"
|
||||
);
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
pub async fn attempt_assign_ticket_materials(
|
||||
&self,
|
||||
testrun_id: i32,
|
||||
|
||||
Reference in New Issue
Block a user