Replies: 7 comments 7 replies
-
Where are you experiencing the pain points? apalis/examples/rest-api/src/main.rs Lines 136 to 148 in d8ed4c9
Unless you mean You might also find using an enum helpful eg: enum DynamicJob {
Job1(Job1),
Job2(Job2)
}
let job1 = service_fn(|req: JobRequest<Job1>| async move {
Ok::<_, JobError>(())
});
let job1 = BoxService::new(job1);
let job2 = service_fn(|req: JobRequest<Job2>| async move {
Ok::<_, JobError>(())
});
let job2 = BoxService::new(job2);
let mut svc = Steer::new(
// All services we steer to
vec![job1, job2],
// How we pick which service to send the request to
|req: &JobRequest<DynamicJob>, _services: &[_]| {
match req.inner() {
Job1(...) => 0,
Job2(...) => 1
}
},
); Learn more about steer here, https://docs.rs/tower/latest/tower/steer/index.html Let me know if that helps |
Beta Was this translation helpful? Give feedback.
-
I think the use of the term |
Beta Was this translation helpful? Give feedback.
-
See an example here: https://github.com/IgnisDa/ryot/blob/22d3505bb3ade0be6ae3b7a48f6c4a13166c437d/apps/backend/src/background.rs#L92 |
Beta Was this translation helpful? Give feedback.
-
@geofmureithi Sorry for my lately reply. My problem is, I want to build a seperate dashboard service, which do not know the job name during compilation time. I want it to dynamically discover all job names (or namespaces). But in the example, nearly all API requires a async fn get_jobs<J, S>(storage: web::Data<S>, filter: web::Query<Filter>) -> HttpResponse
where
J: Job + Serialize + DeserializeOwned + 'static,
S: Storage<Output=J> + JobStreamExt<J> + Send,
{
let storage = &*storage.into_inner();
let mut storage = storage.clone();
let counts = storage.counts().await.unwrap();
let jobs = storage.list_jobs(&filter.status, filter.page).await;
match jobs {
Ok(jobs) => HttpResponse::Ok().json(JobsResult { jobs, counts }),
Err(e) => HttpResponse::InternalServerError().body(format!("{e}")),
}
} For example, in this code snippet, I want to call impl<J: 'static + Job + Serialize + DeserializeOwned + Send + Sync + Unpin> JobStreamExt<J>
for PostgresStorage<J>
{
async fn list_jobs(
&mut self,
status: &JobState,
page: i32,
) -> Result<Vec<JobRequest<J>>, JobError> {
// ...
}
} Seems these API (trait trait DynamicJob {
fn name() -> &str
}
impl<J: DynamicJob> JobStreamExt<J>
for PostgresStorage<J> {
// ...
} |
Beta Was this translation helpful? Give feedback.
-
I have been thinking about this while working on #234. |
Beta Was this translation helpful? Give feedback.
-
@geofmureithi I think the static name is required for worker, but not for dashboard. In micro service scenario, it's very common to have many different service (worker) do their own jobs and have their own job types. But when using a separate dashboard (like a manage/monitor service), it's very useful to dynamically discover all job types from all kinds of services (workers). |
Beta Was this translation helpful? Give feedback.
-
@ImSingee You will be happy to know that this has been fixed in v0.6. |
Beta Was this translation helpful? Give feedback.
-
I want to use apalis-dashboard, and try to implement an API server.
However, I find that the storage is binding to a specific
Job
type which contains a const name. But I want to list all job names and construct theJob
andStorage
dynamically (rather than hard-code all job names inside API code).Is there any plan to change the
Job
trait? For example, maybe changeconst Name
tofn name()
?Beta Was this translation helpful? Give feedback.
All reactions