fix(analysis): reclaim orphaned leases from analysis daemon startup too (0.87.7)
`reclaim_orphaned` previously ran only inside `spawn_crawler_daemon` at startup. A deploy with the crawler disabled and analysis enabled (analysis-only mode) never refunded orphaned `analyze_page` leases — recovery deferred to the lazy lease-expiry path. Wire it into `spawn_analysis_daemon` too. Safe under multi-replica + idempotent against the crawler-side call. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2
backend/Cargo.lock
generated
2
backend/Cargo.lock
generated
@@ -1517,7 +1517,7 @@ checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
|
||||
|
||||
[[package]]
|
||||
name = "mangalord"
|
||||
version = "0.87.6"
|
||||
version = "0.87.7"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"argon2",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "mangalord"
|
||||
version = "0.87.6"
|
||||
version = "0.87.7"
|
||||
edition = "2021"
|
||||
default-run = "mangalord"
|
||||
|
||||
|
||||
@@ -266,7 +266,8 @@ impl DaemonReloader for Supervisors {
|
||||
Arc::clone(&self.storage),
|
||||
&cfg,
|
||||
Arc::clone(&self.analysis_events),
|
||||
)?;
|
||||
)
|
||||
.await?;
|
||||
*guard = Some(handle);
|
||||
tracing::info!(model = %cfg.model, "analysis daemon (re)started from settings");
|
||||
} else {
|
||||
@@ -405,12 +406,29 @@ async fn load_effective_analysis(
|
||||
/// Spawn the AI content-analysis worker daemon with the given config. Returns
|
||||
/// its handle. Independent of the crawler daemon (works for uploads with the
|
||||
/// crawler off). Uses a plain reqwest client — no cookie jar / proxy.
|
||||
fn spawn_analysis_daemon(
|
||||
async fn spawn_analysis_daemon(
|
||||
db: PgPool,
|
||||
storage: Arc<dyn Storage>,
|
||||
cfg: &AnalysisConfig,
|
||||
events: Arc<crate::analysis::events::AnalysisEvents>,
|
||||
) -> anyhow::Result<crate::analysis::daemon::AnalysisDaemonHandle> {
|
||||
// Reclaim jobs orphaned by a previous crash/kill. `crawler::jobs::reclaim_orphaned`
|
||||
// is keyed only on `state='running' AND leased_until < now()`, so it
|
||||
// covers any kind that uses the table — including this daemon's
|
||||
// `analyze_page` jobs. Previously this ran only inside
|
||||
// `spawn_crawler_daemon`, which meant a deploy with the crawler off
|
||||
// (analysis-only) never refunded orphaned analysis leases until the
|
||||
// lease expiry path lazily picked them up. Safe under multi-replica
|
||||
// (only expired leases are touched) and idempotent (the crawler-side
|
||||
// call happens-before this if both are running).
|
||||
match crate::crawler::jobs::reclaim_orphaned(&db).await {
|
||||
Ok(0) => {}
|
||||
Ok(n) => tracing::info!(
|
||||
reclaimed = n,
|
||||
"analysis: reclaimed orphaned in-flight jobs at startup"
|
||||
),
|
||||
Err(e) => tracing::warn!(?e, "analysis: reclaim_orphaned at startup failed"),
|
||||
}
|
||||
let http = reqwest::Client::builder()
|
||||
.timeout(cfg.request_timeout)
|
||||
// Refuse to honour ambient HTTP_PROXY / HTTPS_PROXY container env.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mangalord-frontend",
|
||||
"version": "0.87.6",
|
||||
"version": "0.87.7",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
Reference in New Issue
Block a user