Some checks failed
docker-images / resolve-build-targets (push) Successful in 5s
docker-images / build-and-push (admin) (push) Successful in 30s
docker-images / submit-indexnow (push) Has been cancelled
docker-images / build-and-push (frontend) (push) Has been cancelled
docker-images / build-and-push (backend) (push) Has been cancelled
78 lines
2.8 KiB
Rust
78 lines
2.8 KiB
Rust
use loco_rs::prelude::*;
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use crate::services::{ai, worker_jobs};
|
|
|
|
pub struct AiReindexWorker {
|
|
pub ctx: AppContext,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
|
pub struct AiReindexWorkerArgs {
|
|
#[serde(default)]
|
|
pub job_id: Option<i32>,
|
|
}
|
|
|
|
#[async_trait]
|
|
impl BackgroundWorker<AiReindexWorkerArgs> for AiReindexWorker {
|
|
fn build(ctx: &AppContext) -> Self {
|
|
Self { ctx: ctx.clone() }
|
|
}
|
|
|
|
fn tags() -> Vec<String> {
|
|
vec!["ai".to_string(), "reindex".to_string()]
|
|
}
|
|
|
|
async fn perform(&self, args: AiReindexWorkerArgs) -> Result<()> {
|
|
if let Some(job_id) = args.job_id {
|
|
if !worker_jobs::begin_job_execution(&self.ctx, job_id).await? {
|
|
return Ok(());
|
|
}
|
|
|
|
match ai::rebuild_index(&self.ctx, Some(job_id)).await {
|
|
Ok(summary) => {
|
|
worker_jobs::mark_job_succeeded(
|
|
&self.ctx,
|
|
job_id,
|
|
Some(serde_json::json!({
|
|
"phase": "completed",
|
|
"message": "AI 索引重建完成。",
|
|
"progress": {
|
|
"phase": "completed",
|
|
"message": "AI 索引重建完成。",
|
|
"total_chunks": summary.indexed_chunks,
|
|
"processed_chunks": summary.indexed_chunks,
|
|
"total_batches": summary.indexed_chunks.div_ceil(ai::REINDEX_EMBEDDING_BATCH_SIZE.max(1)),
|
|
"current_batch": summary.indexed_chunks.div_ceil(ai::REINDEX_EMBEDDING_BATCH_SIZE.max(1)),
|
|
"batch_size": ai::REINDEX_EMBEDDING_BATCH_SIZE.max(1),
|
|
"percent": 100,
|
|
},
|
|
"indexed_chunks": summary.indexed_chunks,
|
|
"last_indexed_at": summary.last_indexed_at.map(|value| value.to_rfc3339()),
|
|
})),
|
|
)
|
|
.await?;
|
|
Ok(())
|
|
}
|
|
Err(error) => {
|
|
if worker_jobs::cancel_job_if_requested(
|
|
&self.ctx,
|
|
job_id,
|
|
"job cancelled during reindex",
|
|
)
|
|
.await?
|
|
{
|
|
return Ok(());
|
|
}
|
|
|
|
worker_jobs::mark_job_failed(&self.ctx, job_id, error.to_string()).await?;
|
|
Err(error)
|
|
}
|
|
}
|
|
} else {
|
|
ai::rebuild_index(&self.ctx, None).await?;
|
|
Ok(())
|
|
}
|
|
}
|
|
}
|