use crate::worker::{Worker, WorkerError};
use pyo3::prelude::*;
use std::sync::Arc;
#[derive(Clone)]
pub struct PyWorker {
pub(crate) name: String,
pub(crate) callable: Arc<Py<PyAny>>,
}
#[async_trait::async_trait]
impl Worker for PyWorker {
type Error = WorkerError;
async fn run(&mut self) -> Result<(), Self::Error> {
let callable = self.callable.clone();
let name = self.name.clone();
let handle = std::thread::spawn(move || {
Python::attach(|py| {
callable
.call0(py)
.map(|_| ()) .map_err(|e| WorkerError::WorkerFailed(format!("Worker '{name}' failed: {e}")))
})
});
tokio::task::spawn_blocking(move || {
handle
.join()
.map_err(|e| WorkerError::WorkerFailed(format!("Worker thread panicked: {e:?}")))
})
.await
.map_err(|e| WorkerError::WorkerFailed(format!("Failed to join worker task: {e}")))??
}
async fn initialize(&mut self) -> Result<(), Self::Error> {
Ok(())
}
async fn shutdown(&mut self) -> Result<(), Self::Error> {
Ok(())
}
}