Skip to content

Conversation

@NewtTheWolf
Copy link
Contributor

Summary

This PR implements job ID returns from Worker::perform_later() to enable job status tracking, addressing #1623.

Changes

  • Modified Queue::enqueue() to return Result<Option<String>> instead of Result<()>
  • Modified BackgroundWorker::perform_later() to return Result<Option<String>> instead of Result<()>
  • All queue providers (Redis, PostgreSQL, SQLite) now return their internally tracked job IDs
  • Returns Some(job_id) when using BackgroundQueue mode with a configured provider
  • Returns None for ForegroundBlocking, BackgroundAsync modes, or BackgroundQueue without a provider

Testing

  • Updated all existing enqueue tests to verify job ID returns
  • Added validation in tests to verify that returned job IDs are valid ULIDs
  • Added new test queue_enqueue_returns_job_id to verify behavior for different queue modes
  • All bgworker tests pass successfully with cargo test --features bg_redis,bg_pg,bg_sqlt

Documentation

  • Updated API documentation for Queue::enqueue() method
  • Updated user documentation in docs-site/content/docs/processing/workers.md
  • Added usage example showing how to use the returned job ID
  • Added changelog entry

Notes for Reviewers

  • This is a non-breaking change - existing code that ignores the return value continues to work
  • The implementation follows the approach suggested in the original issue discussion

Implements #1623

@NewtTheWolf
Copy link
Contributor Author

i did not changed anything in the files who failed sanity 🤔

@kaplanelad
Copy link
Contributor

thanks @NewtTheWolf! .
Can you take a look at the conflicts?

@NewtTheWolf
Copy link
Contributor Author

yes, i can take a look this week

@kaplanelad
Copy link
Contributor

Hey @NewtTheWolf,
I tested this and I think there’s an issue.

Steps to Reproduce

  1. Create a clean project:

    ❯ loco new
    ✔ ❯ App name? · myapp
    ✔ ❯ What would you like to build? · Saas App with server side rendering
    ✔ ❯ Select a DB Provider · Sqlite
    ✔ ❯ Select your background worker type · Async (in-process tokio async tasks)
    
  2. Generate a worker:

    cargo loco generate worker test
    
  3. Generate a test controller:

    cargo loco generate controller test --api
    
  4. Add the following code to the controller:

    #[debug_handler]
    pub async fn index(State(ctx): State<AppContext>) -> Result<Response> {
     let job: Option<String> =
         workers::test::Worker::perform_later(&ctx, workers::test::WorkerArgs {}).await?;
     println!("job: {job:#?}",);
    
     format::empty()
    }
    
  5. Run the server with the worker:

    cargo loco start --server-and-worker
    
  6. Open the endpoint in your browser: http://localhost:5150/api/tests

Expected
I should see a job ID in the logs.

Actual i got: job: None

@NewtTheWolf
Copy link
Contributor Author

hey @kaplanelad thats an expected result

a Job ID ONLY gets returned if the Worker Supports it, if it does not Support JobId's it returns None

I saw you used Async Worker and Async Worker dont Return or even Generate Job ID's if i'm right?

i used this comment as Inspiration #1039 (comment)
Espacaliy:

NOTE: if the Redis provider cannot supply a job ID, then we can return a Result, and providers which do not support this return None

Comment on lines 669 to 675
let dx = ctx.clone();
tokio::spawn(async move {
if let Err(err) = Self::build(&dx).perform(args).await {
tracing::error!(err = err.to_string(), "worker failed to perform job");
}
});
None
Copy link
Contributor

@mccormickt mccormickt Nov 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tokio::task::spawn returns a JoinHandle with an Id we could return here if we wanted.

There wouldn't be a real use for it today, but perhaps we could extend this in the future and utilize the handles to build a proper in-process queue provider.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that sounds intresting.

i think i can just implement, then there will no longer be an Option

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants