pinakes-server: integrate plugin system into routes & application state
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: Ib5d482326cae1dcb43603bffb76a6a186a6a6964
This commit is contained in:
parent
f686e8a777
commit
e9c5390c45
6 changed files with 206 additions and 46 deletions
|
|
@ -234,11 +234,57 @@ async fn main() -> Result<()> {
|
|||
))
|
||||
};
|
||||
|
||||
// Initialize plugin manager if plugins are enabled (needed before job queue)
|
||||
let plugin_manager = if config.plugins.enabled {
|
||||
match pinakes_core::plugin::PluginManager::new(
|
||||
config.plugins.data_dir.clone(),
|
||||
config.plugins.cache_dir.clone(),
|
||||
config.plugins.clone().into(),
|
||||
) {
|
||||
Ok(pm) => {
|
||||
tracing::info!("Plugin manager initialized");
|
||||
Some(Arc::new(pm))
|
||||
},
|
||||
Err(e) => {
|
||||
tracing::warn!("Failed to initialize plugin manager: {}", e);
|
||||
None
|
||||
},
|
||||
}
|
||||
} else {
|
||||
tracing::info!("Plugins disabled in configuration");
|
||||
None
|
||||
};
|
||||
|
||||
// Initialize plugin pipeline if plugin manager is available
|
||||
let plugin_pipeline = if let Some(ref pm) = plugin_manager {
|
||||
match pm.discover_and_load_all().await {
|
||||
Ok(loaded) => {
|
||||
tracing::info!(count = loaded.len(), "loaded plugins");
|
||||
let pipeline = Arc::new(pinakes_core::plugin::PluginPipeline::new(
|
||||
Arc::clone(pm),
|
||||
config.plugins.timeouts.clone(),
|
||||
config.plugins.max_consecutive_failures,
|
||||
));
|
||||
if let Err(e) = pipeline.discover_capabilities().await {
|
||||
tracing::warn!(error = %e, "failed to discover plugin capabilities");
|
||||
}
|
||||
Some(pipeline)
|
||||
},
|
||||
Err(e) => {
|
||||
tracing::warn!(error = %e, "plugin discovery failed");
|
||||
None
|
||||
},
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Initialize job queue with executor
|
||||
let job_storage = storage.clone();
|
||||
let job_config = config.clone();
|
||||
let job_transcode = transcode_service.clone();
|
||||
let job_webhooks = webhook_dispatcher.clone();
|
||||
let job_pipeline = plugin_pipeline.clone();
|
||||
let job_queue = pinakes_core::jobs::JobQueue::new(
|
||||
config.jobs.worker_count,
|
||||
config.jobs.job_timeout_secs,
|
||||
|
|
@ -247,31 +293,50 @@ async fn main() -> Result<()> {
|
|||
let config = job_config.clone();
|
||||
let transcode_svc = job_transcode.clone();
|
||||
let webhooks = job_webhooks.clone();
|
||||
let pipeline = job_pipeline.clone();
|
||||
tokio::spawn(async move {
|
||||
use pinakes_core::jobs::{JobKind, JobQueue};
|
||||
match kind {
|
||||
JobKind::Scan { path } => {
|
||||
if let Some(ref pl) = pipeline {
|
||||
pl.emit_event(
|
||||
"ScanStarted",
|
||||
&serde_json::json!({"path": path.as_ref().map(|p| p.display().to_string())}),
|
||||
);
|
||||
}
|
||||
let ignore = config.scanning.ignore_patterns.clone();
|
||||
let res = if let Some(p) = path {
|
||||
pinakes_core::scan::scan_directory(&storage, &p, &ignore).await
|
||||
pinakes_core::scan::scan_directory(
|
||||
&storage,
|
||||
&p,
|
||||
&ignore,
|
||||
pipeline.as_ref(),
|
||||
)
|
||||
.await
|
||||
} else {
|
||||
pinakes_core::scan::scan_all_roots(&storage, &ignore)
|
||||
.await
|
||||
.map(|statuses| {
|
||||
let total_found: usize =
|
||||
statuses.iter().map(|s| s.files_found).sum();
|
||||
let total_processed: usize =
|
||||
statuses.iter().map(|s| s.files_processed).sum();
|
||||
let all_errors: Vec<String> =
|
||||
statuses.into_iter().flat_map(|s| s.errors).collect();
|
||||
pinakes_core::scan::ScanStatus {
|
||||
scanning: false,
|
||||
files_found: total_found,
|
||||
files_processed: total_processed,
|
||||
files_skipped: 0,
|
||||
errors: all_errors,
|
||||
}
|
||||
})
|
||||
pinakes_core::scan::scan_all_roots(
|
||||
&storage,
|
||||
&ignore,
|
||||
pipeline.as_ref(),
|
||||
)
|
||||
.await
|
||||
.map(|statuses| {
|
||||
let total_found: usize =
|
||||
statuses.iter().map(|s| s.files_found).sum();
|
||||
let total_processed: usize =
|
||||
statuses.iter().map(|s| s.files_processed).sum();
|
||||
let total_skipped: usize =
|
||||
statuses.iter().map(|s| s.files_skipped).sum();
|
||||
let all_errors: Vec<String> =
|
||||
statuses.into_iter().flat_map(|s| s.errors).collect();
|
||||
pinakes_core::scan::ScanStatus {
|
||||
scanning: false,
|
||||
files_found: total_found,
|
||||
files_processed: total_processed,
|
||||
files_skipped: total_skipped,
|
||||
errors: all_errors,
|
||||
}
|
||||
})
|
||||
};
|
||||
match res {
|
||||
Ok(status) => {
|
||||
|
|
@ -283,6 +348,15 @@ async fn main() -> Result<()> {
|
|||
},
|
||||
);
|
||||
}
|
||||
if let Some(ref pl) = pipeline {
|
||||
pl.emit_event(
|
||||
"ScanCompleted",
|
||||
&serde_json::json!({
|
||||
"files_found": status.files_found,
|
||||
"files_processed": status.files_processed,
|
||||
}),
|
||||
);
|
||||
}
|
||||
JobQueue::complete(
|
||||
&jobs,
|
||||
job_id,
|
||||
|
|
@ -630,28 +704,6 @@ async fn main() -> Result<()> {
|
|||
config.jobs.cache_ttl_secs,
|
||||
));
|
||||
|
||||
// Initialize plugin manager if plugins are enabled (before moving config into
|
||||
// Arc)
|
||||
let plugin_manager = if config.plugins.enabled {
|
||||
match pinakes_core::plugin::PluginManager::new(
|
||||
config.plugins.data_dir.clone(),
|
||||
config.plugins.cache_dir.clone(),
|
||||
config.plugins.clone().into(),
|
||||
) {
|
||||
Ok(pm) => {
|
||||
tracing::info!("Plugin manager initialized");
|
||||
Some(Arc::new(pm))
|
||||
},
|
||||
Err(e) => {
|
||||
tracing::warn!("Failed to initialize plugin manager: {}", e);
|
||||
None
|
||||
},
|
||||
}
|
||||
} else {
|
||||
tracing::info!("Plugins disabled in configuration");
|
||||
None
|
||||
};
|
||||
|
||||
// Initialize scheduler with cancellation support
|
||||
let shutdown_token = tokio_util::sync::CancellationToken::new();
|
||||
let config_arc = Arc::new(RwLock::new(config));
|
||||
|
|
@ -737,6 +789,7 @@ async fn main() -> Result<()> {
|
|||
cache,
|
||||
scheduler,
|
||||
plugin_manager,
|
||||
plugin_pipeline,
|
||||
transcode_service,
|
||||
managed_storage,
|
||||
chunked_upload_manager,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue