Reputation: 10215
We're seeing occasional timeouts in our application that appear to trace to Redis, though I'm not entirely sure. We have a module that we include in some of our jobs to reduce duplication of heavier work:
module UniqueEnqueable
require 'sidekiq/api'
extend ActiveSupport::Concern
included do
before_enqueue do |job|
throw(:abort) if already_queued_or_scheduled?(job.queue_name, job.arguments)
end
end
private
def already_queued_or_scheduled?(queue_name, arguments)
serialized_args = ActiveJob::Arguments.serialize(arguments)
queued_jobs(queue_name).any? { |job| matches?(job, serialized_args) } ||
scheduled_jobs.any? { |job| matches?(job, serialized_args) }
end
def matches?(job, serialized_args)
active_job?(job) && class_and_args(job) == [self.class.to_s, serialized_args]
end
def active_job?(job)
job.item['class'] == 'ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper'
end
def class_and_args(job)
job.args[0].slice('job_class', 'arguments').values
end
def queued_jobs(queue_name)
Sidekiq::Queue.new(queue_name)
end
def scheduled_jobs
Sidekiq::ScheduledSet.new
end
end
And we're seeing timeout errors coming from inside of redis where it appears to be taking a long time synchronizing requests:
[GEM_ROOT]/gems/redis-4.0.3/lib/redis/connection/ruby.rb:68 :in `select`
[GEM_ROOT]/gems/redis-4.0.3/lib/redis/connection/ruby.rb:68 :in `rescue in _read_from_socket`
[GEM_ROOT]/gems/redis-4.0.3/lib/redis/connection/ruby.rb:64 :in `_read_from_socket`
[GEM_ROOT]/gems/redis-4.0.3/lib/redis/connection/ruby.rb:56 :in `gets`
[GEM_ROOT]/gems/redis-4.0.3/lib/redis/connection/ruby.rb:363 :in `read`
[GEM_ROOT]/gems/redis-4.0.3/lib/redis/client.rb:265 :in `block in read`
[GEM_ROOT]/gems/redis-4.0.3/lib/redis/client.rb:253 :in `io`
[GEM_ROOT]/gems/redis-4.0.3/lib/redis/client.rb:264 :in `read`
[GEM_ROOT]/gems/redis-4.0.3/lib/redis/client.rb:123 :in `block in call`
[GEM_ROOT]/gems/redis-4.0.3/lib/redis/client.rb:234 :in `block (2 levels) in process`
[GEM_ROOT]/gems/redis-4.0.3/lib/redis/client.rb:372 :in `ensure_connected`
[GEM_ROOT]/gems/redis-4.0.3/lib/redis/client.rb:224 :in `block in process`
[GEM_ROOT]/gems/redis-4.0.3/lib/redis/client.rb:309 :in `logging`
[GEM_ROOT]/gems/redis-4.0.3/lib/redis/client.rb:223 :in `process`
[GEM_ROOT]/gems/redis-4.0.3/lib/redis/client.rb:123 :in `call`
[GEM_ROOT]/gems/scout_apm-2.4.20/lib/scout_apm/instruments/redis.rb:32 :in `block in call_with_scout_instruments`
[GEM_ROOT]/gems/scout_apm-2.4.20/lib/scout_apm/tracer.rb:34 :in `instrument`
[GEM_ROOT]/gems/scout_apm-2.4.20/lib/scout_apm/tracer.rb:44 :in `instrument`
[GEM_ROOT]/gems/scout_apm-2.4.20/lib/scout_apm/instruments/redis.rb:31 :in `call_with_scout_instruments`
[GEM_ROOT]/gems/redis-4.0.3/lib/redis.rb:1075 :in `block in llen`
[GEM_ROOT]/gems/redis-4.0.3/lib/redis.rb:50 :in `block in synchronize`
[PROJECT_ROOT]/vendor/ruby-2.5.1/lib/ruby/2.5.0/monitor.rb:226 :in `mon_synchronize`
[GEM_ROOT]/gems/redis-4.0.3/lib/redis.rb:50 :in `synchronize`
[GEM_ROOT]/gems/redis-4.0.3/lib/redis.rb:1074 :in `llen`
[GEM_ROOT]/gems/sidekiq-5.2.3/lib/sidekiq/api.rb:242 :in `block in size`
[GEM_ROOT]/gems/sidekiq-5.2.3/lib/sidekiq.rb:95 :in `block in redis`
[GEM_ROOT]/gems/connection_pool-2.2.2/lib/connection_pool.rb:65 :in `block (2 levels) in with`
[GEM_ROOT]/gems/connection_pool-2.2.2/lib/connection_pool.rb:64 :in `handle_interrupt`
[GEM_ROOT]/gems/connection_pool-2.2.2/lib/connection_pool.rb:64 :in `block in with`
[GEM_ROOT]/gems/connection_pool-2.2.2/lib/connection_pool.rb:61 :in `handle_interrupt`
[GEM_ROOT]/gems/connection_pool-2.2.2/lib/connection_pool.rb:61 :in `with`
[GEM_ROOT]/gems/sidekiq-5.2.3/lib/sidekiq.rb:92 :in `redis`
[GEM_ROOT]/gems/sidekiq-5.2.3/lib/sidekiq/api.rb:242 :in `size`
[GEM_ROOT]/gems/sidekiq-5.2.3/lib/sidekiq/api.rb:283 :in `each`
[PROJECT_ROOT]/app/jobs/concerns/unique_enqueable.rb:17 :in `any?`
[PROJECT_ROOT]/app/jobs/concerns/unique_enqueable.rb:17 :in `already_queued_or_scheduled?`
[PROJECT_ROOT]/app/jobs/concerns/unique_enqueable.rb:8 :in `block (2 levels) in <module:UniqueEnqueable>`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:413 :in `instance_exec`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:413 :in `block in make_lambda`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:197 :in `block (2 levels) in halting`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:601 :in `block (2 levels) in default_terminator`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:600 :in `catch`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:600 :in `block in default_terminator`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:198 :in `block in halting`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:507 :in `block in invoke_before`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:507 :in `each`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:507 :in `invoke_before`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:106 :in `block in run_callbacks`
[GEM_ROOT]/gems/activejob-5.1.6/lib/active_job/logging.rb:15 :in `block (3 levels) in <module:Logging>`
[GEM_ROOT]/gems/activejob-5.1.6/lib/active_job/logging.rb:44 :in `block in tag_logger`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/tagged_logging.rb:69 :in `block in tagged`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/tagged_logging.rb:26 :in `tagged`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/tagged_logging.rb:69 :in `tagged`
[GEM_ROOT]/gems/activejob-5.1.6/lib/active_job/logging.rb:44 :in `tag_logger`
[GEM_ROOT]/gems/activejob-5.1.6/lib/active_job/logging.rb:14 :in `block (2 levels) in <module:Logging>`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:117 :in `instance_exec`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:117 :in `block in run_callbacks`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:135 :in `run_callbacks`
[GEM_ROOT]/gems/activejob-5.1.6/lib/active_job/enqueuing.rb:47 :in `enqueue`
[GEM_ROOT]/gems/activejob-5.1.6/lib/active_job/enqueuing.rb:18 :in `perform_later`
[PROJECT_ROOT]/app/domains/responses/creator.rb:66 :in `call`
[PROJECT_ROOT]/app/controllers/responses_controller.rb:68 :in `create`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/action_controller/metal/basic_implicit_render.rb:4 :in `send_action`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/abstract_controller/base.rb:186 :in `process_action`
[GEM_ROOT]/gems/scout_apm-2.4.20/lib/scout_apm/instruments/action_controller_rails_3_rails4.rb:72 :in `process_action`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/action_controller/metal/rendering.rb:30 :in `process_action`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/abstract_controller/callbacks.rb:20 :in `block in process_action`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:108 :in `block in run_callbacks`
[GEM_ROOT]/gems/react-rails-2.4.7/lib/react/rails/controller_lifecycle.rb:31 :in `use_react_component_helper`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:117 :in `block in run_callbacks`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:135 :in `run_callbacks`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/abstract_controller/callbacks.rb:19 :in `process_action`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/action_controller/metal/rescue.rb:20 :in `process_action`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/action_controller/metal/instrumentation.rb:32 :in `block in process_action`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/notifications.rb:166 :in `block in instrument`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/notifications/instrumenter.rb:21 :in `instrument`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/notifications.rb:166 :in `instrument`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/action_controller/metal/instrumentation.rb:30 :in `process_action`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/action_controller/metal/params_wrapper.rb:252 :in `process_action`
[GEM_ROOT]/gems/activerecord-5.1.6/lib/active_record/railties/controller_runtime.rb:22 :in `process_action`
[GEM_ROOT]/gems/scout_apm-2.4.20/lib/scout_apm/instruments/action_controller_rails_3_rails4.rb:83 :in `process_action`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/abstract_controller/base.rb:124 :in `process`
[GEM_ROOT]/gems/actionview-5.1.6/lib/action_view/rendering.rb:30 :in `process`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/action_controller/metal.rb:189 :in `dispatch`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/action_controller/metal.rb:253 :in `dispatch`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/action_dispatch/routing/route_set.rb:49 :in `dispatch`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/action_dispatch/routing/route_set.rb:31 :in `serve`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/action_dispatch/journey/router.rb:50 :in `block in serve`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/action_dispatch/journey/router.rb:33 :in `each`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/action_dispatch/journey/router.rb:33 :in `serve`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/action_dispatch/routing/route_set.rb:844 :in `call`
[GEM_ROOT]/gems/scout_apm-2.4.20/lib/scout_apm/instruments/rails_router.rb:29 :in `call_with_scout_instruments`
[GEM_ROOT]/gems/scout_apm-2.4.20/lib/scout_apm/middleware.rb:17 :in `call`
[GEM_ROOT]/gems/rack-attack-5.4.2/lib/rack/attack.rb:182 :in `call`
[GEM_ROOT]/gems/rack-2.0.6/lib/rack/etag.rb:25 :in `call`
[GEM_ROOT]/gems/rack-2.0.6/lib/rack/conditional_get.rb:38 :in `call`
[GEM_ROOT]/gems/rack-2.0.6/lib/rack/head.rb:12 :in `call`
[GEM_ROOT]/gems/rack-2.0.6/lib/rack/session/abstract/id.rb:232 :in `context`
[GEM_ROOT]/gems/rack-2.0.6/lib/rack/session/abstract/id.rb:226 :in `call`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/action_dispatch/middleware/cookies.rb:613 :in `call`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/action_dispatch/middleware/callbacks.rb:26 :in `block in call`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/callbacks.rb:97 :in `run_callbacks`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/action_dispatch/middleware/callbacks.rb:24 :in `call`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/action_dispatch/middleware/debug_exceptions.rb:59 :in `call`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/action_dispatch/middleware/show_exceptions.rb:31 :in `call`
[GEM_ROOT]/gems/railties-5.1.6/lib/rails/rack/logger.rb:36 :in `call_app`
[GEM_ROOT]/gems/railties-5.1.6/lib/rails/rack/logger.rb:24 :in `block in call`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/tagged_logging.rb:69 :in `block in tagged`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/tagged_logging.rb:26 :in `tagged`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/tagged_logging.rb:69 :in `tagged`
[GEM_ROOT]/gems/railties-5.1.6/lib/rails/rack/logger.rb:24 :in `call`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/action_dispatch/middleware/remote_ip.rb:79 :in `call`
[GEM_ROOT]/gems/request_store-1.4.1/lib/request_store/middleware.rb:19 :in `call`
[GEM_ROOT]/gems/rack-timeout-0.5.1/lib/rack/timeout/core.rb:123 :in `block in call`
[GEM_ROOT]/gems/rack-timeout-0.5.1/lib/rack/timeout/support/timeout.rb:19 :in `timeout`
[GEM_ROOT]/gems/rack-timeout-0.5.1/lib/rack/timeout/core.rb:122 :in `call`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/action_dispatch/middleware/request_id.rb:25 :in `call`
[GEM_ROOT]/gems/rack-2.0.6/lib/rack/method_override.rb:22 :in `call`
[GEM_ROOT]/gems/rack-2.0.6/lib/rack/runtime.rb:22 :in `call`
[GEM_ROOT]/gems/activesupport-5.1.6/lib/active_support/cache/strategy/local_cache_middleware.rb:27 :in `call`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/action_dispatch/middleware/executor.rb:12 :in `call`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/action_dispatch/middleware/static.rb:125 :in `call`
[GEM_ROOT]/gems/font_assets-0.1.14/lib/font_assets/middleware.rb:17 :in `block in call`
[GEM_ROOT]/gems/font_assets-0.1.14/lib/font_assets/middleware.rb:40 :in `do_request`
[GEM_ROOT]/gems/font_assets-0.1.14/lib/font_assets/middleware.rb:16 :in `call`
[GEM_ROOT]/gems/rack-2.0.6/lib/rack/sendfile.rb:111 :in `call`
[GEM_ROOT]/gems/actionpack-5.1.6/lib/action_dispatch/middleware/ssl.rb:68 :in `call`
[PROJECT_ROOT]/config/middleware/null_byte_sanitizer.rb:9 :in `call`
[GEM_ROOT]/gems/rack-utf8_sanitizer-1.6.0/lib/rack/utf8_sanitizer.rb:22 :in `call`
[GEM_ROOT]/gems/scout_apm-2.4.20/lib/scout_apm/instruments/middleware_summary.rb:58 :in `call`
[GEM_ROOT]/gems/railties-5.1.6/lib/rails/engine.rb:522 :in `call`
[GEM_ROOT]/gems/railties-5.1.6/lib/rails/railtie.rb:185 :in `public_send`
[GEM_ROOT]/gems/railties-5.1.6/lib/rails/railtie.rb:185 :in `method_missing`
[GEM_ROOT]/gems/rack-2.0.6/lib/rack/static.rb:149 :in `call`
[GEM_ROOT]/gems/puma-3.12.0/lib/puma/configuration.rb:225 :in `call`
[GEM_ROOT]/gems/puma-3.12.0/lib/puma/server.rb:658 :in `handle_request`
[GEM_ROOT]/gems/puma-3.12.0/lib/puma/server.rb:472 :in `process_client`
[GEM_ROOT]/gems/puma-3.12.0/lib/puma/server.rb:332 :in `block in run`
[GEM_ROOT]/gems/puma-3.12.0/lib/puma/thread_pool.rb:133 :in `block in spawn_thread`
Any tips as to why this might be happening? Happy to add more information as needed.
Upvotes: 1
Views: 366
Reputation: 22208
The API page says this:
WARNING the API exposes some operations which are not scalable and should not be used in an automated fashion or in bulk as part of your application functionality. You should not be scanning through queues/sets and deleting jobs unless something has gone wrong and you need to repair data manually.
You want this: https://github.com/mperham/sidekiq/wiki/Ent-Unique-Jobs
Upvotes: 2