Skip to content

Connection pool exhaustion from delivery thread serializing reports #812

Open
@evanlok

Description

@evanlok

Describe the bug

Bugsnag's delivery thread can checkout an ActiveRecord database connection that is never returned to the pool. This causes subsequent connections to time out waiting for a connection from the pool.

Steps to reproduce

  1. An ActiveJob job receives an ActiveRecord instance as a job argument
  2. The job raises an exception
  3. Bugsnag creates a report that contains the serialized job arguments
  4. The ActiveRecord class overrides to_s which is called when it gets serialized by bugsnag. The to_s method contains code that queries the database.
  5. Bugsnag's delivery thread checks out a database connection from the connection pool when the to_s method is invoked by Bugsnag::Cleaner#traverse_object
  6. The connection pool has now permanently lost a connection to the bugsnag delivery thread

Environment

  • Bugsnag version: 6.26.0
  • Ruby version: 3.0.5
  • Bundle version: 2.3.26
  • Integration framework version:
    • Que:
    • Rack 2.2.8
    • Rails: 6.1.6
    • Rake:
    • Sidekiq: 7.1.2
    • Other:

Example code snippet

# Run a single instance of sidekiq worker with concurrency 2

class Foo < ApplicationRecord
  def to_s
    Bar.first # Database query triggered during bugsnag report delivery
    "foo"
  end
end

class Bar < ApplicationRecord
end

class MyJob < ApplicationJob
  def perform(foo)
     Bar.first # Query will time out waiting for connection
     sleep 10
     raise "Fail"
  end
end

Foo.create
Bar.create
10.times { MyJob.perform_later(Foo.first) }
Error messages:

Metadata

Metadata

Assignees

No one assigned

    Labels

    backlogWe hope to fix this feature/bug in the futureneeds discussionRequires internal analysis/discussion

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions