### Install sidekiq-throttled Gem Source: https://github.com/ixti/sidekiq-throttled/blob/main/README.adoc Instructions for installing the sidekiq-throttled gem using Bundler or directly via RubyGems. ```ruby gem "sidekiq-throttled" ``` ```bash $ bundle $ gem install sidekiq-throttled ``` -------------------------------- ### Basic Job Throttling Configuration Source: https://github.com/ixti/sidekiq-throttled/blob/main/README.adoc Example of how to include Sidekiq::Throttled::Job in a Sidekiq job class and configure concurrency and threshold limits. ```ruby require "sidekiq/throttled" class MyJob include Sidekiq::Job include Sidekiq::Throttled::Job sidekiq_options :queue => :my_queue sidekiq_throttle( # Allow maximum 10 concurrent jobs of this class at a time. concurrency: { limit: 10 }, # Allow maximum 1K jobs being processed within one hour window. threshold: { limit: 1_000, period: 1.hour } ) def perform # ... end end ``` -------------------------------- ### Concurrency TTL Configuration (Ruby) Source: https://context7.com/ixti/sidekiq-throttled/llms.txt Sets the Time-To-Live (TTL) for concurrency locks. The default is 15 minutes. This is useful for long-running jobs to prevent premature lock release. An example with advanced concurrency tuning is also provided. ```ruby class LongRunningJob include Sidekiq::Job include Sidekiq::Throttled::Job sidekiq_options queue: :long_running sidekiq_throttle( concurrency: { limit: 5, # Job takes up to 2 hours, set TTL accordingly ttl: 2.hours.to_i } ) def perform(report_id) # Long-running report generation generate_large_report(report_id) end end # Advanced concurrency tuning with schedule requeue strategy class TunedConcurrencyJob include Sidekiq::Job include Sidekiq::Throttled::Job sidekiq_throttle( concurrency: { limit: 10, # Jobs finish in about 30 seconds avg_job_duration: 30, # Consider job lost after 2 minutes lost_job_threshold: 120, # Max delay when throttled max_delay: 300 }, requeue: { with: :schedule } ) def perform(id) quick_api_call(id) end end ``` -------------------------------- ### Manually Prepending Server Middleware Source: https://github.com/ixti/sidekiq-throttled/blob/main/README.adoc Demonstrates how to manually prepend the `Sidekiq::Throttled::Middlewares::Server` to the server middleware chain if automatic injection causes issues. ```ruby Sidekiq.configure_server do |config| # ... config.server_middleware do |chain| chain.prepend(Sidekiq::Throttled::Middlewares::Server) end end ``` -------------------------------- ### Basic Job Throttling with Observer Source: https://github.com/ixti/sidekiq-throttled/blob/main/README.adoc Demonstrates basic job throttling using concurrency and threshold limits, along with a custom observer lambda. The observer receives strategy and arguments, allowing custom actions based on throttling events. ```ruby include Sidekiq::Throttled::Job MY_OBSERVER = lambda do |strategy, *args| # do something end sidekiq_options queue: :my_queue sidekiq_throttle( concurrency: { limit: 10 }, threshold: { limit: 100, period: 1.hour }, observer: MY_OBSERVER ) def perform(*args) # ... end ``` -------------------------------- ### Dynamic Limits and Periods for Throttling Source: https://github.com/ixti/sidekiq-throttled/blob/main/README.adoc Illustrates how to set dynamic limits and periods for both concurrency and threshold throttling using procs. These procs are evaluated when the job is fetched, allowing for context-aware throttling based on job arguments like user roles (VIP vs. standard). ```ruby include Sidekiq::Job include Sidekiq::Throttled::Job sidekiq_options queue: :my_queue sidekiq_throttle( # Allow maximum 1000 concurrent jobs of this class at a time for VIPs and 10 for all other users. concurrency: { limit: ->(user_id) { User.vip?(user_id) ? 1_000 : 10 }, key_suffix: ->(user_id) { User.vip?(user_id) ? "vip" : "std" } }, # Allow 1000 jobs/hour to be processed for VIPs and 10/day for all others threshold: { limit: ->(user_id) { User.vip?(user_id) ? 1_000 : 10 }, period: ->(user_id) { User.vip?(user_id) ? 1.hour : 1.day }, key_suffix: ->(user_id) { User.vip?(user_id) ? "vip" : "std" } } ) def perform(user_id) # ... end ``` -------------------------------- ### Include Sidekiq::Throttled::Web UI Source: https://github.com/ixti/sidekiq-throttled/blob/main/README.adoc Instructions to require `sidekiq/throttled/web` during application initialization to add a Throttled tab to the Sidekiq Web UI. ```ruby require "sidekiq/throttled/web" ``` -------------------------------- ### Multiple Keys for Throttling a Single Worker Source: https://github.com/ixti/sidekiq-throttled/blob/main/README.adoc Demonstrates how to apply multiple throttling rules to a single worker using different keys. This allows for complex throttling scenarios, such as limiting concurrency per project and per user simultaneously. ```ruby include Sidekiq::Job include Sidekiq::Throttled::Job sidekiq_options queue: :my_queue sidekiq_throttle( # Allow maximum 10 concurrent jobs per project at a time and maximum 2 jobs per user concurrency: [ { limit: 10, key_suffix: -> (project_id, user_id) { "project_id:#{project_id}" } }, { limit: 2, key_suffix: -> (project_id, user_id) { "user_id:#{user_id}" } } ] # For :threshold it works the same ) def perform(project_id, user_id) # ... end ``` -------------------------------- ### Multiple Threshold Limits with String Key Suffixes Source: https://github.com/ixti/sidekiq-throttled/blob/main/README.adoc Shows how to configure multiple threshold limits for a single worker, each with a distinct time period and a static string key suffix. This is useful for setting different rate limits (e.g., per minute, per hour, per day) with clear identifiers. ```ruby include Sidekiq::Job include Sidekiq::Throttled::Job sidekiq_options queue: :my_queue sidekiq_throttle( # Allow 500 jobs per minute, 5,000 per hour, and 50,000 per day: threshold: [ { limit: 500, period: 1.minute, key_suffix: "minutely" }, { limit: 5_000, period: 1.hour, key_suffix: "hourly" }, { limit: 50_000, period: 1.day, key_suffix: "daily" }, ] ) def perform(project_id, user_id) # ... end ``` -------------------------------- ### Using Sidekiq::Throttled::Worker Alias Source: https://github.com/ixti/sidekiq-throttled/blob/main/README.adoc Demonstrates using the `Sidekiq::Throttled::Worker` alias for consistency with Sidekiq's naming conventions. ```ruby class MyWorker include Sidekiq::Worker include Sidekiq::Throttled::Worker # ... end ``` -------------------------------- ### Dynamic Throttling with Key Suffix for Sidekiq Jobs Source: https://context7.com/ixti/sidekiq-throttled/llms.txt Implements dynamic throttling using `key_suffix` to create separate throttle buckets based on job arguments, enabling per-user or per-resource rate limiting. Both concurrency and threshold throttling can be configured with dynamic keys. ```ruby class UserApiJob include Sidekiq::Job include Sidekiq::Throttled::Job sidekiq_options queue: :api_calls sidekiq_throttle( # Allow maximum 10 concurrent jobs per user at a time concurrency: { limit: 10, key_suffix: ->(user_id) { user_id } }, # Allow maximum 100 jobs per user per hour threshold: { limit: 100, period: 1.hour, key_suffix: ->(user_id) { user_id } } ) def perform(user_id) # Each user_id gets their own throttle bucket ExternalApi.fetch_data(user_id) end end # User 123 and user 456 each get their own rate limits UserApiJob.perform_async(123) UserApiJob.perform_async(456) ``` -------------------------------- ### Execute Demo Jobs with Sidekiq::Throttled (Ruby) Source: https://github.com/ixti/sidekiq-throttled/blob/main/demo/README.adoc This snippet shows how to execute demo jobs using Sidekiq::Throttled. It utilizes the `perform_bulk` method to enqueue multiple instances of `FirstJob` and `SecondJob`. Ensure Sidekiq and Puma are running before executing. ```ruby ThrottledDemo::FirstJob.perform_bulk(Array.new(100) { |n| [n] }) ThrottledDemo::SecondJob.perform_bulk(Array.new(100) { |n| [n] }) ``` -------------------------------- ### Dynamic Concurrency Throttling with Key Suffix Source: https://github.com/ixti/sidekiq-throttled/blob/main/README.adoc Shows how to dynamically throttle jobs based on a key suffix, such as a user ID. This allows for per-user concurrency limits, ensuring a specific user doesn't exceed a set number of concurrent jobs. ```ruby include Sidekiq::Throttled::Job sidekiq_options queue: :my_queue sidekiq_throttle( # Allow maximum 10 concurrent jobs per user at a time. concurrency: { limit: 10, key_suffix: -> (user_id) { user_id } } ) def perform(user_id) # ... end ``` -------------------------------- ### Multiple Throttle Strategies for Sidekiq Jobs Source: https://context7.com/ixti/sidekiq-throttled/llms.txt Applies multiple throttling strategies to a single job by passing an array to `sidekiq_throttle`. This is useful for tiered rate limits (per-minute, per-hour, per-day) and multiple concurrency limits based on different keys. ```ruby class MultiTierThrottleJob include Sidekiq::Job include Sidekiq::Throttled::Job sidekiq_options queue: :multi_tier sidekiq_throttle( concurrency: { limit: 10 }, # Multiple threshold limits with different time windows threshold: [ { limit: 500, period: 1.minute, key_suffix: "minutely" }, { limit: 5_000, period: 1.hour, key_suffix: "hourly" }, { limit: 50_000, period: 1.day, key_suffix: "daily" } ] ) def perform(project_id, user_id) sync_data(project_id, user_id) end end # Also supports multiple concurrency strategies class MultiKeyThrottleJob include Sidekiq::Job include Sidekiq::Throttled::Job sidekiq_throttle( concurrency: [ { limit: 10, key_suffix: ->(project_id, user_id) { "project:#{project_id}" } }, { limit: 2, key_suffix: ->(project_id, user_id) { "user:#{user_id}" } } ] ) def perform(project_id, user_id) # Max 10 concurrent per project AND max 2 concurrent per user end end ``` -------------------------------- ### Configuring Requeue Strategy (Global) Source: https://github.com/ixti/sidekiq-throttled/blob/main/README.adoc Globally configures the default requeue strategy to `:schedule` for jobs that are throttled. ```ruby Sidekiq::Throttled.configure do |config| config.default_requeue_options = { with: :schedule } end ``` -------------------------------- ### Requeue Strategy Configuration (Ruby) Source: https://context7.com/ixti/sidekiq-throttled/llms.txt Configures how throttled jobs are requeued. Options include immediate requeue (`:enqueue`) or scheduling for later execution (`:schedule`), which can reduce Redis CPU load. Global and per-job configurations are shown. ```ruby # Global configuration Sidekiq::Throttled.configure do |config| config.default_requeue_options = { with: :schedule } end # Per-job configuration class ScheduledRequeueJob include Sidekiq::Job include Sidekiq::Throttled::Job sidekiq_options queue: :default sidekiq_throttle( threshold: { limit: 5, period: 1.minute, # Schedule throttled jobs for later instead of immediate requeue requeue: { with: :schedule } } ) def perform(id) process(id) end end # Requeue to a different queue class CrossQueueRequeueJob include Sidekiq::Job include Sidekiq::Throttled::Job sidekiq_options queue: :priority sidekiq_throttle( threshold: { limit: 10, period: 1.minute, # Throttled jobs go to low_priority queue requeue: { to: :low_priority, with: :schedule } } ) def perform(id) process(id) end end ``` -------------------------------- ### Global Configuration for Throttling Source: https://github.com/ixti/sidekiq-throttled/blob/main/README.adoc Configures global settings for the cooldown period and threshold for throttling, affecting how queues are managed when jobs are repeatedly throttled. ```ruby Sidekiq::Throttled.configure do |config| # Period in seconds to exclude queue from polling in case it returned # {config.cooldown_threshold} amount of throttled jobs in a row. Set # this value to `nil` to disable cooldown manager completely. # Default: 1.0 config.cooldown_period = 1.0 # Exclude queue from polling after it returned given amount of throttled # jobs in a row. # Default: 100 (cooldown after hundredth throttled job in a row) config.cooldown_threshold = 100 end ``` -------------------------------- ### Observer for Throttling Events Source: https://github.com/ixti/sidekiq-throttled/blob/main/README.adoc Shows how to specify an observer object that will be called when a job is throttled, allowing for custom event handling. ```ruby class MyJob include Sidekiq::Job # ... sidekiq_throttle( # ... observer: MyObserver.new ) # ... end ``` -------------------------------- ### Dynamic Limits Based on Job Arguments in Sidekiq Source: https://context7.com/ixti/sidekiq-throttled/llms.txt Allows dynamic throttling limits and periods based on job arguments using Procs. This enables conditional throttling, such as higher limits for VIP users. It also supports dynamic `key_suffix` for different user tiers. ```ruby class TieredRateLimitJob include Sidekiq::Job include Sidekiq::Throttled::Job sidekiq_options queue: :tiered sidekiq_throttle( concurrency: { # VIP users get 1000 concurrent jobs, standard users get 10 limit: ->(user_id) { User.vip?(user_id) ? 1_000 : 10 }, key_suffix: ->(user_id) { User.vip?(user_id) ? "vip" : "std" } }, threshold: { # VIP: 1000/hour, Standard: 10/day limit: ->(user_id) { User.vip?(user_id) ? 1_000 : 10 }, period: ->(user_id) { User.vip?(user_id) ? 1.hour : 1.day }, key_suffix: ->(user_id) { User.vip?(user_id) ? "vip" : "std" } } ) def perform(user_id) process_request(user_id) end end ``` -------------------------------- ### Configuring Requeue Strategy (Per Job) Source: https://github.com/ixti/sidekiq-throttled/blob/main/README.adoc Configures a specific job to use the `:schedule` requeue strategy for its threshold throttling. ```ruby class MyJob # ... sidekiq_throttle( threshold: { limit: 5, period: 1.minute, requeue: {with: :schedule} } ) # ... end ``` -------------------------------- ### Tuning Concurrency Lock TTL Source: https://github.com/ixti/sidekiq-throttled/blob/main/README.adoc Explains how to adjust the Time To Live (TTL) for distributed locks used in concurrency throttling. This is crucial for jobs that may take longer than the default 15 minutes to complete, preventing premature lock release and ensuring accurate concurrency control. ```ruby include Sidekiq::Job include Sidekiq::Throttled::Job sidekiq_options queue: :my_queue sidekiq_throttle( concurrency: { limit: 10, ttl: 900 } # TTL in seconds, default is 900 (15 minutes) ) def perform(project_id, user_id) # ... end ``` -------------------------------- ### Basic Throttle Configuration for Sidekiq Jobs Source: https://context7.com/ixti/sidekiq-throttled/llms.txt Configures basic concurrency and threshold throttling for a Sidekiq job class using `sidekiq_throttle`. It sets limits on the number of simultaneous jobs and jobs processed within a time window. Jobs are enqueued normally. ```ruby class MyJob include Sidekiq::Job include Sidekiq::Throttled::Job sidekiq_options queue: :my_queue sidekiq_throttle( # Allow maximum 10 concurrent jobs of this class at a time concurrency: { limit: 10 }, # Allow maximum 1000 jobs being processed within one hour window threshold: { limit: 1_000, period: 1.hour } ) def perform(user_id) # Process user data puts "Processing user #{user_id}" end end # Enqueue jobs as normal MyJob.perform_async(123) MyJob.perform_async(456) ``` -------------------------------- ### Sidekiq Web UI Integration (Ruby) Source: https://context7.com/ixti/sidekiq-throttled/llms.txt Enables the Sidekiq Web UI extension for Sidekiq Throttled, allowing users to view and manage throttle strategies directly from the dashboard. This includes viewing current counts, limits, and resetting counters. ```ruby # config/initializers/sidekiq.rb require "sidekiq/throttled" require "sidekiq/throttled/web" # Adds "Throttled" tab to Sidekiq Web UI # config/routes.rb (Rails) require "sidekiq/web" Rails.application.routes.draw do mount Sidekiq::Web => "/sidekiq" end # The Web UI provides: # - View all registered throttle strategies # - See current count vs. limit for each strategy # - Reset throttle counters via POST /throttled/:id/reset ``` -------------------------------- ### Shared Throttle Pool for Multiple Jobs (Ruby) Source: https://context7.com/ixti/sidekiq-throttled/llms.txt Demonstrates how multiple Sidekiq job classes can share a common throttle pool, identified by a symbol. This allows for combined rate limiting across different job types. ```ruby class FetchGoogleProfileJob include Sidekiq::Job include Sidekiq::Throttled::Job sidekiq_throttle_as :google_api def perform(user_id) GoogleApi.fetch_profile(user_id) end end class FetchGoogleContactsJob include Sidekiq::Job include Sidekiq::Throttled::Job sidekiq_throttle_as :google_api def perform(user_id) GoogleApi.fetch_contacts(user_id) end end # Combined limit: max 10 concurrent + 100/minute across BOTH job types FetchGoogleProfileJob.perform_async(1) FetchGoogleContactsJob.perform_async(1) ``` -------------------------------- ### Configure Scheduling-Based Concurrency Tuning Source: https://github.com/ixti/sidekiq-throttled/blob/main/README.adoc Implements a scheduling-based concurrency tuning strategy for Sidekiq jobs. This strategy aims to reduce churn by delaying the requeueing of throttled jobs until they are likely to be runnable. It requires specifying the concurrency limit, average job duration, and a threshold for considering a job lost. ```ruby sidekiq_throttle( concurrency: { # only run 10 of this job at a time limit: 10, # these jobs finish in less than 30 seconds avg_job_duration: 30, # if it doesn't release its lease in 2 minutes it's considered lost lost_job_threshold: 120, # maximum delay allowed when throttled max_delay: 300 }, # requeue using Sidekiq's scheduler requeue: { with: :schedule } ) ``` -------------------------------- ### Global Configuration for Sidekiq Throttled (Ruby) Source: https://context7.com/ixti/sidekiq-throttled/llms.txt Configures global settings for Sidekiq Throttled, including the cooldown period for polling throttled queues and the default requeue behavior. These settings are applied across all jobs unless overridden. ```ruby # config/initializers/sidekiq.rb require "sidekiq/throttled" Sidekiq::Throttled.configure do |config| # Period in seconds to exclude queue from polling after hitting threshold # Set to nil to disable cooldown completely config.cooldown_period = 1.0 # default: 1.0 # Number of consecutive throttled jobs before cooldown kicks in config.cooldown_threshold = 100 # default: 100 # Default requeue strategy for all throttled jobs # :enqueue = put back on queue immediately # :schedule = schedule for future execution config.default_requeue_options = { with: :enqueue } end ``` -------------------------------- ### Registering and Sharing Throttle Strategies in Sidekiq Source: https://context7.com/ixti/sidekiq-throttled/llms.txt Registers a named throttling strategy using `Sidekiq::Throttled::Registry.add` and shares it across multiple job classes with `sidekiq_throttle_as`. This allows jobs to share the same throttle pool, ensuring coordinated rate limiting. ```ruby # config/initializers/sidekiq.rb require "sidekiq/throttled" # Create shared throttling strategy for Google API calls Sidekiq::Throttled::Registry.add(:google_api, { threshold: { limit: 100, period: 1.minute }, concurrency: { limit: 10 } }) ``` -------------------------------- ### Configuring Requeue to Another Queue Source: https://github.com/ixti/sidekiq-throttled/blob/main/README.adoc Configures a job to requeue throttled jobs to a different specified queue using the `:schedule` strategy. ```ruby class MyJob # ... sidekiq_throttle( threshold: { limit: 5, period: 1.minute, requeue: {to: :other_queue, with: :schedule} } ) # ... end ``` -------------------------------- ### Observer for Throttle Events (Ruby) Source: https://context7.com/ixti/sidekiq-throttled/llms.txt Registers an observer callback to receive notifications when jobs are throttled. This is useful for monitoring, alerting, and custom metrics. The observer receives the strategy type and job arguments. ```ruby class ObservedJob include Sidekiq::Job include Sidekiq::Throttled::Job # Observer receives (strategy_type, *job_args) THROTTLE_OBSERVER = lambda do |strategy, *args| case strategy when :concurrency Rails.logger.warn("Job throttled by concurrency: args=#{args}") StatsD.increment("jobs.throttled.concurrency") when :threshold Rails.logger.warn("Job throttled by threshold: args=#{args}") StatsD.increment("jobs.throttled.threshold") end end sidekiq_options queue: :observed sidekiq_throttle( concurrency: { limit: 5 }, threshold: { limit: 100, period: 1.hour }, observer: THROTTLE_OBSERVER ) def perform(user_id, action) process_action(user_id, action) end end ``` -------------------------------- ### Check Sidekiq Job Throttle Status Programmatically (Ruby) Source: https://context7.com/ixti/sidekiq-throttled/llms.txt Checks if a Sidekiq job message would be throttled without processing it. It also shows how to retrieve and iterate through registered throttling strategies. ```ruby message = { "class" => "MyJob", "jid" => SecureRandom.hex(12), "args" => [123] }.to_json if Sidekiq::Throttled.throttled?(message) puts "Job would be throttled" else puts "Job can proceed" end strategy = Sidekiq::Throttled::Registry.get("MyJob") if strategy puts "Concurrency count: #{strategy.concurrency&.count}" puts "Threshold count: #{strategy.threshold&.count}" end Sidekiq::Throttled::Registry.each do |name, strategy| puts "Strategy: #{name}, Dynamic: #{strategy.dynamic?}" end ``` -------------------------------- ### Set Concurrency Lock TTL to 1 Hour Source: https://github.com/ixti/sidekiq-throttled/blob/main/README.adoc Configures the concurrency strategy for a Sidekiq job, setting the limit to 20 concurrent jobs and a time-to-live (TTL) of 1 hour for the lock. This ensures that no more than 20 instances of the job run simultaneously and locks are released after an hour if not explicitly released. ```ruby sidekiq_throttle(concurrency: { limit: 20, ttl: 1.hour.to_i }) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.