jonhoo / faktory-rs

Rust bindings for Faktory clients and workers

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Is there a way to implement async handlers?

tobymurray opened this issue · comments

Is it possible to register async handlers? I want to do some work in a handler that ultimately invokes a function that calls await. Currently my code that looks like:

let mut c = ConsumerBuilder::default();
c.register("job_type", &async_handler);

...

async fn async_handler(job: Job) -> io::Result<()> {
	// here I would do stuff and .await
	Ok(())
}

produces:

error[E0271]: expected `&fn(Job) -> impl Future<Output = Result<(), Error>> {async_handler}` to be a reference that returns `Result<(), Error>`, but it returns `impl Future<Output = Result<(), Error>>`
   --> src/main.rs:48:22
    |
48  |     c.register("job_type", &async_handler);
    |       --------          ^^^^^^^^^^^^ expected `Result<(), Error>`, found future
    |       |
    |       required by a bound introduced by this call

I'm using Tokio, so I guess I can do e.g.:

	c.register("job_type", |job| -> io::Result<()> {
		let runtime = Runtime::new()?;
		runtime.block_on(async_handler(job));
		Ok(())
	});

The answer at the moment is unfortunately no. You can start a runtime as you indicate, though that's going to slow things down a fair amount since each new such runtime will have a startup cost. You could probably launch one in main and pass a Handler to the runtime into each job type you register, though that'll still be somewhat painful.

Realistically, I think the right path forward here is to make this whole library async, including all the job handler callbacks. Unfortunately, I don't use the library myself any more, so won't have the time it'd take to make such a change, but if someone wants to pick up this project and assume long-term ownership of it, I'd be happy to work with them to make that happen!