Skip to content

UDPSockets leaked under load #34

@raykrueger

Description

@raykrueger

Ran into some issues today with our Sidekiq/Statsd setup. We have a nice sidekiq middleware component that wraps each job in a "time" block; it works great.

The problem is that, under load, garbage collection does not get to run and all of the UDPSockets attached to threads are left behind.

To remedy this I added a tweak to the middleware to clean up the UDPSocket after the job finishes.

class StatsdMiddleware
  def call(worker, msg, queue)
    statsd = #get statsd however
    statsd.time("#{worker.class}.perform") do
      yield
    end
  ensure
    socket = Thread.current[:statsd_socket]
    socket.close if socket
    Thread.current[:statsd_socket] = nil
  end
end

This is then added into Sidekiq as a server middleware...

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

This may be applicable to other threading/forking situations like unicorn and passenger as well.

I could package this up as an optional class or something, not sure if that's going too far. If nothing else, a wiki page might be good.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions