2026-04-07 02:50:19 +08:00
|
|
|
use aether_data_contracts::repository::video_tasks::VideoTaskLookupKey;
|
|
|
|
|
use aether_usage_runtime::build_locally_actionable_report_context_from_video_task;
|
2026-04-05 20:23:16 +08:00
|
|
|
use serde_json::Value;
|
2026-04-22 21:09:29 +08:00
|
|
|
use tokio::time::{sleep, Duration};
|
2026-04-03 14:59:58 +08:00
|
|
|
|
2026-04-07 02:50:19 +08:00
|
|
|
use crate::request_candidate_runtime::resolve_locally_actionable_request_candidate_report_context;
|
2026-04-05 20:23:16 +08:00
|
|
|
use crate::video_tasks::{resolve_video_task_report_lookup, VideoTaskReportLookup};
|
|
|
|
|
use crate::AppState;
|
2026-04-03 14:59:58 +08:00
|
|
|
|
2026-04-05 20:23:16 +08:00
|
|
|
pub(crate) use aether_usage_runtime::report_context_is_locally_actionable;
|
2026-04-03 14:59:58 +08:00
|
|
|
|
2026-04-22 21:09:29 +08:00
|
|
|
const REQUEST_CANDIDATE_REPORT_CONTEXT_RETRY_ATTEMPTS: usize = 5;
|
|
|
|
|
const REQUEST_CANDIDATE_REPORT_CONTEXT_RETRY_DELAY_MS: u64 = 50;
|
|
|
|
|
|
2026-04-03 14:59:58 +08:00
|
|
|
pub(crate) async fn resolve_locally_actionable_report_context(
|
|
|
|
|
state: &AppState,
|
|
|
|
|
report_context: Option<&Value>,
|
|
|
|
|
) -> Option<Value> {
|
|
|
|
|
let context = report_context?.clone();
|
|
|
|
|
if report_context_is_locally_actionable(Some(&context)) {
|
|
|
|
|
return Some(context);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if let Some(resolved) =
|
2026-04-22 21:09:29 +08:00
|
|
|
resolve_locally_actionable_request_candidate_report_context_with_retry(state, &context)
|
|
|
|
|
.await
|
2026-04-03 14:59:58 +08:00
|
|
|
{
|
|
|
|
|
return Some(resolved);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let context = resolve_locally_actionable_report_context_from_video_task(state, &context)
|
|
|
|
|
.await
|
|
|
|
|
.unwrap_or(context);
|
|
|
|
|
|
|
|
|
|
if let Some(resolved) =
|
2026-04-22 21:09:29 +08:00
|
|
|
resolve_locally_actionable_request_candidate_report_context_with_retry(state, &context)
|
|
|
|
|
.await
|
2026-04-03 14:59:58 +08:00
|
|
|
{
|
|
|
|
|
return Some(resolved);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
report_context_is_locally_actionable(Some(&context)).then_some(context)
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-22 21:09:29 +08:00
|
|
|
async fn resolve_locally_actionable_request_candidate_report_context_with_retry(
|
|
|
|
|
state: &AppState,
|
|
|
|
|
context: &Value,
|
|
|
|
|
) -> Option<Value> {
|
|
|
|
|
if context
|
|
|
|
|
.get("request_id")
|
|
|
|
|
.and_then(Value::as_str)
|
|
|
|
|
.map(str::trim)
|
|
|
|
|
.filter(|value| !value.is_empty())
|
|
|
|
|
.is_none()
|
|
|
|
|
{
|
|
|
|
|
return None;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for attempt in 0..=REQUEST_CANDIDATE_REPORT_CONTEXT_RETRY_ATTEMPTS {
|
|
|
|
|
if let Some(resolved) =
|
|
|
|
|
resolve_locally_actionable_request_candidate_report_context(state, context).await
|
|
|
|
|
{
|
|
|
|
|
return Some(resolved);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if attempt < REQUEST_CANDIDATE_REPORT_CONTEXT_RETRY_ATTEMPTS {
|
|
|
|
|
sleep(Duration::from_millis(
|
|
|
|
|
REQUEST_CANDIDATE_REPORT_CONTEXT_RETRY_DELAY_MS,
|
|
|
|
|
))
|
|
|
|
|
.await;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-03 14:59:58 +08:00
|
|
|
async fn resolve_locally_actionable_report_context_from_video_task(
|
|
|
|
|
state: &AppState,
|
|
|
|
|
context: &Value,
|
|
|
|
|
) -> Option<Value> {
|
2026-04-05 20:23:16 +08:00
|
|
|
let task = match resolve_video_task_report_lookup(context)? {
|
|
|
|
|
VideoTaskReportLookup::Lookup(lookup) => {
|
|
|
|
|
state.data.find_video_task(lookup).await.ok()??
|
|
|
|
|
}
|
|
|
|
|
VideoTaskReportLookup::TaskIdOrExternal { task_id, user_id } => {
|
|
|
|
|
if let Some(task) = state
|
2026-04-03 14:59:58 +08:00
|
|
|
.data
|
2026-04-05 20:23:16 +08:00
|
|
|
.find_video_task(VideoTaskLookupKey::Id(task_id))
|
2026-04-03 14:59:58 +08:00
|
|
|
.await
|
2026-04-05 20:23:16 +08:00
|
|
|
.ok()?
|
|
|
|
|
{
|
|
|
|
|
task
|
|
|
|
|
} else {
|
|
|
|
|
let user_id = user_id?;
|
|
|
|
|
state
|
|
|
|
|
.data
|
|
|
|
|
.find_video_task(VideoTaskLookupKey::UserExternal {
|
|
|
|
|
user_id,
|
|
|
|
|
external_task_id: task_id,
|
|
|
|
|
})
|
|
|
|
|
.await
|
|
|
|
|
.ok()??
|
|
|
|
|
}
|
2026-04-03 14:59:58 +08:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2026-04-05 20:23:16 +08:00
|
|
|
build_locally_actionable_report_context_from_video_task(context, &task)
|
2026-04-03 14:59:58 +08:00
|
|
|
}
|