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

Sidekiq任务中默认传递current_user的实现方案咨询

Injecting current_user into Sidekiq Jobs Automatically

Great approach using Sidekiq middleware to handle this! You're halfway there with the server middleware—let's fill in the gaps and add a client middleware to automatically inject the user info so you don't have to pass it every time.

Step 1: Complete the Server Middleware

First, let's finish your server middleware to properly set Thread.current[:current_user] from the job args. Assuming you're passing a user ID (or a serialized user reference), here's how to refine it:

# app/middleware/sidekiq_server_middleware.rb
class SidekiqServerMiddleware
  def call(_worker, job, _queue)
    set_current_user(job['args'])
    yield
  ensure
    # Critical: Clear thread-local data after job runs to prevent cross-job contamination
    Thread.current[:current_user] = nil
  end

  private

  def set_current_user(args)
    last_arg = args.last
    return unless last_arg.is_a?(Hash) && last_arg[:current_user_id]

    # Fetch the user from the database using the stored ID
    Thread.current[:current_user] = User.find_by(id: last_arg[:current_user_id])
  end
end

The ensure block is non-negotiable here—it guarantees we clean up the thread-local variable, so subsequent jobs don't accidentally inherit the previous user's context.

Step 2: Add a Client Middleware to Auto-Inject current_user

Now, let's create a client middleware that automatically adds the current user's ID to job args whenever you enqueue a job (but only if current_user exists in the request context):

# app/middleware/sidekiq_client_middleware.rb
class SidekiqClientMiddleware
  def call(_worker_class, job, _queue, _redis_pool)
    # Check if we're in a context where current_user is available (like a Rails controller)
    if defined?(current_user) && current_user.present?
      # Append the user ID as a hash to make it easy to identify in the server middleware
      job['args'] << { current_user_id: current_user.id }
    end
    yield
  end
end

This runs when you call perform_async—it detects if current_user exists and tacks their ID onto the job's arguments automatically, no extra code needed when enqueuing.

Step 3: Configure Sidekiq to Use the Middlewares

Add this to your config/initializers/sidekiq.rb to register both middlewares:

Sidekiq.configure_server do |config|
  config.server_middleware do |chain|
    chain.add SidekiqServerMiddleware
  end
end

Sidekiq.configure_client do |config|
  config.client_middleware do |chain|
    chain.add SidekiqClientMiddleware
  end
end

Step 4: Access current_user in Your Jobs

Now, in any Sidekiq job, you can grab the current user directly from the thread-local storage:

class MyWorker
  include Sidekiq::Worker

  def perform(some_arg, another_arg)
    user = Thread.current[:current_user]
    return unless user.present?

    # Use the user context as needed—e.g., log actions, filter data, or associate records
    puts "Executing job triggered by: #{user.email}"
  end
end

You don't need to pass the user ID when enqueuing anymore—just call MyWorker.perform_async(some_arg, another_arg) from your controller, and the middleware handles the rest.

Edge Cases to Keep in Mind

  • Jobs enqueued outside a request context: If you enqueue a job from a rake task or script where current_user isn't available, the middleware won't add anything—make sure your job handles user.nil? gracefully.
  • Jobs that don't need current_user: This setup won't interfere—your job's perform method doesn't need to accept the extra arg explicitly, since we're appending it.
  • User deletion: If a user is deleted before the job runs, User.find_by will return nil—add checks to handle this scenario (e.g., skip the job or log a warning).

This setup keeps your job enqueues clean and eliminates repetitive current_user passes across your app—perfect for cases where most jobs need to know the triggering user!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:38:33