You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails中如何通过API从前端获取Sidekiq任务进度信息?

Fetching Sidekiq Job Progress via API for Frontend

Hey there! Let me break down how to get individual job progress from your Sidekiq workers (using the sidekiq-status gem) into your frontend—since the /sidekiq/stats endpoint only gives you global Sidekiq metrics, not per-job details.

Step 1: Expose a Custom API Endpoint

The sidekiq-status gem doesn’t automatically expose an API for fetching job statuses, so you’ll need to create a small controller in your Rails app to bridge the gap:

Create app/controllers/api/job_statuses_controller.rb:

class Api::JobStatusesController < ApplicationController
  # Skip CSRF verification if your frontend is making cross-origin requests or using an API-only setup
  skip_before_action :verify_authenticity_token, only: [:show]

  def show
    job_id = params[:id]
    # Fetch the basic status (e.g., 'queued', 'working', 'complete', 'failed')
    status = Sidekiq::Status::get(job_id)

    if status
      # Fetch all metadata associated with the job (including progress)
      job_metadata = Sidekiq::Status::get_all(job_id)
      render json: {
        job_id: job_id,
        status: status,
        progress: job_metadata['progress'] || 0,
        message: job_metadata['message'] || '',
        # Add any other custom metadata you stored in the worker
        result: job_metadata['result']
      }
    else
      render json: { error: "Job not found or has completed/expired" }, status: :not_found
    end
  end
end

Step 2: Add a Route for the API

Update your config/routes.rb to map the endpoint:

namespace :api do
  get '/job_statuses/:id', to: 'job_statuses#show'
end

Step 3: Update Your Worker to Track Progress

Make sure your worker includes the sidekiq-status module and updates progress during execution:

class MyWorker
  include Sidekiq::Worker
  include Sidekiq::Status::Worker # Required to track status/progress

  def perform(some_task_arg)
    total_steps = 100
    # Initialize progress with total steps and a starting message
    progress(0, total_steps, "Initializing task...")

    total_steps.times do |step|
      # Your actual task logic goes here
      sleep(0.1) # Simulate work

      # Update progress after each step
      progress(step + 1, total_steps, "Completed step #{step + 1}/#{total_steps}")
    end

    # Optional: Store a custom result when the job finishes
    store({ result: "Task completed successfully!" })
  end
end

Step 4: Fetch Progress from the Frontend

Use fetch or a library like Axios to poll the API endpoint (since progress updates over time):

// Fetch a single job status
async function fetchJobStatus(jobId) {
  try {
    const response = await fetch(`/api/job_statuses/${jobId}`);
    if (!response.ok) throw new Error("Failed to fetch job status");
    return await response.json();
  } catch (error) {
    console.error("Error fetching job status:", error);
    return null;
  }
}

// Poll the status at intervals until the job finishes
function pollJobProgress(jobId, intervalMs = 2000) {
  const intervalId = setInterval(async () => {
    const status = await fetchJobStatus(jobId);
    if (!status) {
      clearInterval(intervalId);
      return;
    }

    // Update your frontend UI here (e.g., progress bar, status message)
    console.log(`Progress: ${status.progress}% | Status: ${status.status}`);

    // Stop polling when the job is done or failed
    if (status.status === "complete" || status.status === "failed") {
      clearInterval(intervalId);
      console.log("Job finished:", status.result || status.status);
    }
  }, intervalMs);

  return intervalId;
}

// Usage: Start polling when you have the job ID (returned when enqueuing the worker)
const jobId = "your-job-id-here";
pollJobProgress(jobId);

Why /sidekiq/stats Doesn’t Work for This

The /sidekiq/stats endpoint returns global Sidekiq metrics (total processed jobs, busy workers, etc.)—it doesn’t have any data about individual job progress. The sidekiq-status gem stores per-job metadata in Redis, so we need to use its helper methods (Sidekiq::Status::get, Sidekiq::Status::get_all) to retrieve that data and expose it via our custom API.

内容的提问来源于stack exchange,提问作者user5639287

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:35:54