Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delayed::Job job name improvement to support ActiveJob #605

Merged

Conversation

agirlnamedsophia
Copy link
Contributor

My team and I are excited to use this library (and DataDog itself) and are happy with so much automatic instrumentation and tagging that comes with it. However we noticed in using this library that all of our delayed jobs were showing up as JobWrapper
instead of the specific job's name, because ActiveJob includes another abstraction around the job class itself.

Before, everything was showing up under the one item at the top. Now you can see the individual jobs populating with their specific names.
screen shot 2018-11-02 at 3 13 23 pm

We also included tests that are slightly less stubby so as to avoid adding a dependency on ActiveJob, but mimic what ActiveJob would send in real life.

Copy link
Contributor

@delner delner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for submitting this! It's always great to see contributions like this to improve the tracer :)

I'll do a more thorough review of this a bit later, but wanted to leave a few thoughts to keep the ball rolling for now. Looking forward to digging deeper into this!

@@ -7,13 +7,22 @@
require_relative 'delayed_job_active_record'

RSpec.describe Datadog::Contrib::DelayedJob::Plugin, :delayed_job_active_record do
let(:sample_job_object) { double('sample_job', perform: nil) }
let(:sample_job_class) { class_double('SampleJob', new: sample_job_object) }
class SampleJob
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should replace these let blocks with constants. The constants are immutable between tests and can cause naming conflicts. I suspect the existing RSpec doubles might not cut it because the changes introduced might actually depend on reflect real constants, however, I think we could convert these blocks to dynamic constants instead which would cover both sets of needs.

Something like:

let(:sample_job_object) do
  stub_const("SampleJob", Class.new do
    def perform; end
  end)
end

@@ -9,7 +9,14 @@ class Plugin < Delayed::Plugin
def self.instrument(job, &block)
return block.call(job) unless tracer && tracer.enabled

tracer.trace(Ext::SPAN_JOB, service: configuration[:service_name], resource: job.name) do |span|
# If DelayedJob is used through ActiveJob, `job.name` is always "ActiveJob::QueueAdapters::DelayedJobAdapter::JobWrapper"
if job.payload_object.respond_to?(:job_data)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The existence of this job_data method appears to be the key here to support ActiveJob.

Can you explain the differences between vanilla DelayedJobs and ones that come through ActiveJob? Specifically, what job is and how its configured? And could you also tell me a little more about the conditions when you expect each of these branches to be executed?

My thoughts behind those questions are that it would be best to avoid any specific configuration for ActiveJob in the DelayedJob integration, since it would introduce a kind of coupling via inversion of dependencies. However, what we have here does look pretty general purpose (which is promising); I'd just like to confirm it's not some kind of defacto coupling.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ActiveJob is another abstraction, it’s the public API in front of any background jobs library. DelayedJob is one backend that executes the code that ActiveJob gives it. Rails uses ActiveJob to support a variety of queueing backends and DelayedJob is just one of them.

I totally understand how creating an ActiveJob specific configuration creates an awkward inversion of dependencies. Knowing about the implementation details of ActiveJob isn't great.

I figured I’d dive down this avenue to see if y’all were amenable to supporting two different job payload objects. This solution already exists for Airbrake for error catching, which is a good indicator that it's not too terrible of an idea — at least there's precedent for this kind of solution in other tools.

Given that ActiveJob is the default framework for Rails 5+, I think it would be great to get this library patched up to work nicely with it for those folks (myself included) that are using ActiveJob with DelayedJob.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, yeah. We're definitely wanting to add ActiveJob support to the library here in the future, and getting this working with DelayedJob would great.

Rails stuff can be a bit demanding of such special treatment, so I think I can appreciate that the change is at least fairly straightforward despite the introduction of coupling. I lean towards accepting it, but just wanted to make sure we're asking and answering the question "is this as simple and durable as it can be?"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confident this is the simplest solution. job will always respond to payload_object because that's how DJ works, so if job_data is a key in payload_object we can be confident that it's an ActiveJob job and take the job_class value from the payload. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can work as is. If we discover some better way of doing this in the future we can always change it, but for now it's good that we're getting some improved behavior out of this.

@delner delner added integrations Involves tracing integrations community Was opened by a community member feature Involves a product feature labels Nov 2, 2018
@delner
Copy link
Contributor

delner commented Nov 6, 2018

@agirlnamedsophia Can you take a look at the build errors? (Rubocop issues?) And then rebase this on the latest master? If we can do that soon, I think we can get this in the next bugfix release (today or tomorrow), else we'll have to move it to the release after that.

@agirlnamedsophia
Copy link
Contributor Author

Awesome!

@delner I'm unsure what the other failures are, but it's been rebased on master and rubocop seems happy (I think)!

@delner
Copy link
Contributor

delner commented Nov 6, 2018

@agirlnamedsophia Yeah I see that build error, too. It just appeared on another PR, so I don't think its because of your changes. In all likelihood, someone released a new version of concurrent_ruby which broke our test suite. I'll probably take a quick look at that; you'll probably need to rebase after that's fixed.

@delner
Copy link
Contributor

delner commented Nov 7, 2018

@agirlnamedsophia We found and fixed the source of the problem; just need CI to rebuild using version 1.1.3 of concurrent-ruby instead of 1.1.2.

If you're able to rebase/force push to change the commit SHAs (or create a new commit), it should hopefully bust the CI gem cache and fix the build.

@agirlnamedsophia agirlnamedsophia force-pushed the sr/master/send-delayed-job-job-names branch from b35e1e9 to 0c7b262 Compare November 7, 2018 16:16
@agirlnamedsophia
Copy link
Contributor Author

@delner everything seems to be working except the prerelease Gem job and maybe that's because I'm on a fork?

@delner
Copy link
Contributor

delner commented Nov 7, 2018

@agirlnamedsophia Yup that's why; this is as good as a passing build.

@delner delner added this to the 0.17.1 milestone Nov 7, 2018
Copy link
Contributor

@delner delner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Thanks for your contribution @agirlnamedsophia ! 💯

@delner delner merged commit 7de7753 into DataDog:master Nov 7, 2018
@agirlnamedsophia
Copy link
Contributor Author

thank you for accepting this suggestion! 🙌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
community Was opened by a community member feature Involves a product feature integrations Involves tracing integrations
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants