You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Documentation around 4 -> 5 upgrade; ArgumentError: Start sender first #274
I'm unsure what I need to do to make the 4 to 5 upgrade work. I see the README file has some detail:
Using a singleton instance of the DogStatsD client instead of creating a new instance whenever you need one; this will let the buffering mechanism flush metrics regularly
Or properly disposing of the DogStatsD client instance when it is not needed anymore using the method Datadog::Statsd#close
but I thought we were using a singleton instance, and I don't think we want to be sprinkling #close around the code. The current way we're creating the instance is in an initialiser:
Deployed on Heroku using Puma, we're getting an error #<ArgumentError: Start sender first> that is crashing the Rails (6.1.7.3) process on boot. Is there something else we should be doing?
Sorry for the delay, I'm happy to help you figure this out.
What you're seeing appears to be some kind of forking-related error, could you provide some more details on how your Puma server is configured? Particularly anything related to "Workers" as this appears to be how Puma creates new processes.
To give you a bit more insight, when the statsd client is forked (I'm guessing this is the case as the rails initializer probably runs once at startup, and then puma forks the process), we should be starting a new sender thread in the new process, but it appears that is not happening in your case, which is leading to this error.
# frozen_string_literal: truerequire'datadog/statsd'# set up statsd monitoringunlessRails.configuration.respond_to?(:statsd)statsd=Datadog::Statsd.new(tags: {env: Rails.env},disable_telemetry: Rails.env != 'production')Rails.configuration.statsd=statsdend
The Puma config:
# frozen_string_literal: truerequire'puma_worker_killer'require'barnes'workersInteger(ENV.fetch('WEB_CONCURRENCY',1))threads_count=Integer(ENV.fetch('PUMA_MAX_THREADS',1))threads(threads_count,threads_count)preload_app!rackupDefaultRackupenvironmentENV.fetch('RACK_ENV','development')worker_timeout15worker_shutdown_timeout8on_worker_bootdo# Worker specific setup for Rails 4.1+# See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-bootMakara::Context.release_allActiveRecord::Base.establish_connectionSemanticLogger.reopenend# Puma worker killer. Bandaid for memory issues.before_forkdoPumaWorkerKiller.enable_rolling_restart(3600)# Overriding 6 hour default to do it every hour to kill off memory-hungry workers that hang around.Barnes.start# see https://devcenter.heroku.com/articles/language-runtime-metrics-rubyend
Env for the staging environment where we were trying this out:
WEB_CONCURRENCY: 2PUMA_MAX_THREADS: 5
I figure the same as you, I'm probably missing some config but don't know what that would be.
Thanks for the extra details, I'm unfortunately still not able to reproduce this.
I have a few questions that can hopefully help us get to the bottom of this:
Can you confirm that changing only the version of dogstatsd-ruby causes the issue you're seeing? From which version to which other version are you changing?
Could you also provide your ruby version and any relevant gem versions (puma, barnes, puma_worker_killer, anything that may have anything to do with threads/forking really)
Do both workers emit this error? Or does one continue running okay?
Does this error happen immediately on application startup? Or after some amount of time (maybe the same interval as puma_worker_killer?)
Do you have any logs you can share with a stack trace and any relevant events that happen before this error?
Without a reproduction I'm stuck reading through the code and I'm unfortunately not having much luck figuring out how you'd get into this state.
As a workaround, you could try setting single_thread: true in the statsd constructor, which may help? If it does help that may help us narrow down what's going on here.
Can you confirm that changing only the version of dogstatsd-ruby causes the issue you're seeing? From which version to which other version are you changing?
Yes, it's only dogstatsd-ruby changing.
Could you also provide your ruby version and any relevant gem versions (puma, barnes, puma_worker_killer, anything that may have anything to do with threads/forking really)
Ruby 2.7.5
barnes (0.0.9)
puma (5.6.4)
puma_worker_killer (0.3.1) https://github.com/wjessop/oas_agent (master, starts a background reporting thread but doesn't interact with datadog in it)
Do both workers emit this error? Or does one continue running okay?
I don't think anything remains up, but I've only seen one instance of the error in the logs.
Do you have any logs you can share with a stack trace and any relevant events that happen before this error?
There's no stack trace, just the log, I don't have the log output to hand, but I recall it wasn't particularly useful.
As a workaround, you could try setting single_thread: true in the statsd constructor, which may help?
We could try this but I think we'd still want to solve the issue with the error.
I think what would help would be if you could provide a canonical example of what a datadog config looks like when using Puma in pre-forking mode (probably the most common Rails app server and configuration). Saying "Using a singleton instance of the DogStatsD client instead of creating a new instance whenever you need one; this will let the buffering mechanism flush metrics regularly" in the docs is somewhat abstract, a concrete example would be really helpful to compare to what we're currently doing.
Activity
wjessop commentedon May 23, 2023
Is there anyone who could take a look at this?
scottopell commentedon May 24, 2023
Hi @wjessop
Sorry for the delay, I'm happy to help you figure this out.
What you're seeing appears to be some kind of forking-related error, could you provide some more details on how your Puma server is configured? Particularly anything related to "Workers" as this appears to be how Puma creates new processes.
Here's my repro attempt if its helpful to compare (this is just
rails newplus a scaffold and a bit of datadog configuration)https://github.com/scottopell/demo-app-rails6
To give you a bit more insight, when the statsd client is forked (I'm guessing this is the case as the rails initializer probably runs once at startup, and then puma forks the process), we should be starting a new sender thread in the new process, but it appears that is not happening in your case, which is leading to this error.
wjessop commentedon May 25, 2023
Here's our current datadog initialiser:
The Puma config:
Env for the staging environment where we were trying this out:
I figure the same as you, I'm probably missing some config but don't know what that would be.
scottopell commentedon May 26, 2023
Thanks for the extra details, I'm unfortunately still not able to reproduce this.
I have a few questions that can hopefully help us get to the bottom of this:
Without a reproduction I'm stuck reading through the code and I'm unfortunately not having much luck figuring out how you'd get into this state.
As a workaround, you could try setting
single_thread: truein the statsd constructor, which may help? If it does help that may help us narrow down what's going on here.scottopell commentedon Jun 8, 2023
ping @wjessop in case you missed the above
wjessop commentedon Jun 12, 2023
Sorry @scottopell, was on vacation! Will try to take a look at this this week.
scottopell commentedon Jul 5, 2023
@wjessop one more ping if you still need help
wjessop commentedon Jul 5, 2023
Sorry Scott, lots going on!
Yes, it's only dogstatsd-ruby changing.
Ruby 2.7.5
barnes (0.0.9)
puma (5.6.4)
puma_worker_killer (0.3.1)
https://github.com/wjessop/oas_agent (master, starts a background reporting thread but doesn't interact with datadog in it)
I don't think anything remains up, but I've only seen one instance of the error in the logs.
There's no stack trace, just the log, I don't have the log output to hand, but I recall it wasn't particularly useful.
We could try this but I think we'd still want to solve the issue with the error.
I think what would help would be if you could provide a canonical example of what a datadog config looks like when using Puma in pre-forking mode (probably the most common Rails app server and configuration). Saying "Using a singleton instance of the DogStatsD client instead of creating a new instance whenever you need one; this will let the buffering mechanism flush metrics regularly" in the docs is somewhat abstract, a concrete example would be really helpful to compare to what we're currently doing.
wjessop commentedon Sep 20, 2023
Hey Scott, if you've got it a canonical example of what a datadog config looks like when using Puma in pre-forking mode would be really helpful here.
wjessop commentedon Nov 6, 2023
@scottopell Any chance you could give an example?
agustinv commentedon Feb 18, 2025
@wjessop did you end up figuring out a good working example here? Thank you
wjessop commentedon Feb 18, 2025
Sorry @agustinv, we didn't.