mirror of
https://github.com/Yuyi-Oak/BlueArchiveToolkit.git
synced 2026-09-18 10:54:55 +08:00
@@ -1217,6 +1217,27 @@ impl SqliteTranslationTaskRepository {
|
||||
status: TranslationTaskStatus,
|
||||
failure_reason: Option<String>,
|
||||
provider_run_id: Option<String>,
|
||||
) -> Result<PersistedTranslationTask> {
|
||||
self.update_status_with_results(
|
||||
task_id,
|
||||
status,
|
||||
failure_reason,
|
||||
provider_run_id,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Updates provider state and optionally replaces durable TextUnit results.
|
||||
pub async fn update_status_with_results(
|
||||
&self,
|
||||
task_id: &str,
|
||||
status: TranslationTaskStatus,
|
||||
failure_reason: Option<String>,
|
||||
provider_run_id: Option<String>,
|
||||
provider: Option<String>,
|
||||
translation_results: Option<&[TranslationTaskUnitResult]>,
|
||||
) -> Result<PersistedTranslationTask> {
|
||||
let current = self.find(task_id).await?;
|
||||
let now = unix_seconds_now_i64();
|
||||
@@ -1228,6 +1249,13 @@ impl SqliteTranslationTaskRepository {
|
||||
current.attempt_count
|
||||
};
|
||||
let normalized_reason = failure_reason.filter(|reason| !reason.trim().is_empty());
|
||||
let provider_run_id = provider_run_id.filter(|value| !value.trim().is_empty());
|
||||
let provider = provider.filter(|value| !value.trim().is_empty());
|
||||
let translation_results_json =
|
||||
translation_results
|
||||
.map(serde_json::to_string)
|
||||
.transpose()
|
||||
.map_err(|error| bat_core::Error::Serialization(error.to_string()))?;
|
||||
let completed = (status == TranslationTaskStatus::Completed).then_some(now);
|
||||
sqlx::query(
|
||||
r#"
|
||||
@@ -1235,6 +1263,8 @@ impl SqliteTranslationTaskRepository {
|
||||
SET worker_status = ?2, failure_reason = ?3, attempt_count = ?4,
|
||||
updated_unix_seconds = ?5, completed_unix_seconds = ?6,
|
||||
provider_run_id = COALESCE(?7, provider_run_id),
|
||||
provider = COALESCE(?8, provider),
|
||||
translation_results_json = COALESCE(?9, translation_results_json),
|
||||
lease_owner = NULL, lease_expires_unix_seconds = NULL,
|
||||
failure_class = NULL, failure_retryable = 0,
|
||||
next_attempt_unix_seconds = NULL
|
||||
@@ -1248,6 +1278,8 @@ impl SqliteTranslationTaskRepository {
|
||||
.bind(now)
|
||||
.bind(completed)
|
||||
.bind(provider_run_id)
|
||||
.bind(provider)
|
||||
.bind(translation_results_json)
|
||||
.execute(&self.pool)
|
||||
.await
|
||||
.map_err(db_error)?;
|
||||
@@ -1696,6 +1728,52 @@ mod tests {
|
||||
assert_eq!(retrievable[0].attempt_count, 1);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn sqlite_translation_tasks_persist_manual_results_without_worker_lease() {
|
||||
let temp = tempfile::TempDir::new().unwrap();
|
||||
let repository =
|
||||
SqliteTranslationTaskRepository::new(temp.path().join("translation-tasks.sqlite"))
|
||||
.await
|
||||
.unwrap();
|
||||
let queue = queue(vec![task(
|
||||
"task-a",
|
||||
"Bundles/a.bundle",
|
||||
OfficialTextUnitTaskStatus::QueuedOffline,
|
||||
Some(OfficialParseStatus::Parsed),
|
||||
None,
|
||||
)]);
|
||||
repository.sync_queue(&queue).await.unwrap();
|
||||
let result = TranslationTaskUnitResult {
|
||||
unit_id: "unit-a".to_string(),
|
||||
source_text: "source".to_string(),
|
||||
translated_text: "manual translation".to_string(),
|
||||
provider: "manual".to_string(),
|
||||
provider_run_id: "manual-run-1".to_string(),
|
||||
translated_unix_seconds: 321,
|
||||
};
|
||||
|
||||
let updated = repository
|
||||
.update_status_with_results(
|
||||
"task-a",
|
||||
TranslationTaskStatus::Completed,
|
||||
None,
|
||||
Some("manual-run-1".to_string()),
|
||||
Some("manual".to_string()),
|
||||
Some(std::slice::from_ref(&result)),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(updated.task_status, TranslationTaskStatus::Completed);
|
||||
assert_eq!(updated.provider.as_deref(), Some("manual"));
|
||||
assert_eq!(updated.provider_run_id.as_deref(), Some("manual-run-1"));
|
||||
assert_eq!(updated.translation_results, vec![result.clone()]);
|
||||
assert_eq!(
|
||||
repository.find("task-a").await.unwrap().translation_results,
|
||||
vec![result]
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn sqlite_translation_tasks_recover_expired_leases_for_retry() {
|
||||
let temp = tempfile::TempDir::new().unwrap();
|
||||
|
||||
Reference in New Issue
Block a user