Skip to content

AP-513 improving order of operations#21

Open
jason-raitz wants to merge 3 commits intomainfrom
AP-513_log_tracing_part_deux
Open

AP-513 improving order of operations#21
jason-raitz wants to merge 3 commits intomainfrom
AP-513_log_tracing_part_deux

Conversation

@jason-raitz
Copy link
Contributor

  • co-authored with @danschmidt5189
  • some logs were still not getting request_id logged
  • we believe there an issue with when the two around_performs were called
  • this commit should eliminate that problem

- co-authored with @danschmidt5189
- some logs were still not getting request_id logged
- we believe there an issue with when the two around_performs were
  called
- this commit should eliminate that problem
Copy link
Member

@danschmidt5189 danschmidt5189 left a comment

Choose a reason for hiding this comment

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

Curious about the test failures.

around_perform :log_job_metadata
def request_id
if !defined? @request_id
if arguments.last.is_a?(Hash) && arguments.last.key?(:request_id)
Copy link
Member

Choose a reason for hiding this comment

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

Since it came up on our call, I'll just note you could use find to make this more robust to argument order:

@request_id = args.select { |arg| arg.is_a? Hash }
  .find(-> {{}}) { |arg| arg.key?(:request_id) }
  .fetch(:request_id)

I'm sure there's a more syntactically sugary way to write that, too, but you get the gist. (And yes, it's inefficient to select -> find, I've just done that for clarity.)

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 meant to post this as a reply to your comment.

- replaces the positional removal with a destructuring and reassignment.
Comment on lines 12 to 17
def request_id
r_id_hash, rest = arguments.partition { |arg| arg.is_a?(Hash) && arg.key?(:request_id) } unless defined? @request_id
self.arguments = rest if rest.any?
@request_id = r_id_hash.first[:request_id] if r_id_hash.any?
@request_id
end
Copy link
Contributor Author

@jason-raitz jason-raitz Feb 17, 2026

Choose a reason for hiding this comment

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

I went with a destructering and reassignment.

Copy link
Member

Choose a reason for hiding this comment

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

FWIW I found it hard to parse the intention here, so I'd recommend refactoring for clarity. There's also a subtle bug in that if r_id_hash.any? is false, then @request_id remains undefined.

Off the dome I came up with:

def request_id
  if !defined? @request_id
    request_id_arg, other_args = arguments.partition { |arg| arg.is_a?(Hash) && arg.key?(:request_id) }
    @request_id = request_id_arg.first[:request_id] rescue nil
    self.arguments = other_args if other_args.any?
  end
  @request_id
end

This retains the usual if/end/return pattern and should fix the nil assignment bug.

Copy link
Member

@danschmidt5189 danschmidt5189 Feb 17, 2026

Choose a reason for hiding this comment

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

Also maybe this is more along the lines of what @awilfox suggested, but I wonder if we need to use arguments here at all? We should be able to just set a request_id attribute directly on the job object using a callback. Only question there would be making sure it gets serialized/deserialized properly.

CurrentAttributes should be of help here.

@jason-raitz jason-raitz marked this pull request as ready for review February 17, 2026 16:39
Copy link
Member

@awilfox awilfox left a comment

Choose a reason for hiding this comment

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

This is good, but I am a bit concerned that the mutation of arguments is done in a method. If we change how or when (or if) that method is called, suddenly the arguments will change too. I think it's better to do this in a dedicated callback, i.e. before_perform :set_request_id or something.

Copy link
Member

@anarchivist anarchivist left a comment

Choose a reason for hiding this comment

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

looks good. one clarificatory question about your docs in comments, but otherwise r+.

edit: this might be related to @awilfox's concern, too.

attr_reader :request_id
# This is a little unorthodox, but we want the request_id to be available as an instance variable on the job,
# so we add it to the arguments before the job is enqueued and then pull it out in a before_perform callback.
# Admittedly, the request_id method mutates the arguments as a side effect of pulling the request_id out.
Copy link
Member

Choose a reason for hiding this comment

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

does this comment still apply with the restructuring you did?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah. I'll fix things to go with something more like @awilfox's suggestion.

@jason-raitz
Copy link
Contributor Author

This is good, but I am a bit concerned that the mutation of arguments is done in a method. If we change how or when (or if) that method is called, suddenly the arguments will change too. I think it's better to do this in a dedicated callback, i.e. before_perform :set_request_id or something.

I think you're right. I'll redo it. I think the reason some of the jobs are not getting the request_id right now is possibly because of multiple before_performs and around_performs making it a race condition? I'll try something different in a bit.

@jason-raitz jason-raitz marked this pull request as draft February 17, 2026 20:14
Comment on lines 12 to 17
def request_id
r_id_hash, rest = arguments.partition { |arg| arg.is_a?(Hash) && arg.key?(:request_id) } unless defined? @request_id
self.arguments = rest if rest.any?
@request_id = r_id_hash.first[:request_id] if r_id_hash.any?
@request_id
end
Copy link
Member

Choose a reason for hiding this comment

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

FWIW I found it hard to parse the intention here, so I'd recommend refactoring for clarity. There's also a subtle bug in that if r_id_hash.any? is false, then @request_id remains undefined.

Off the dome I came up with:

def request_id
  if !defined? @request_id
    request_id_arg, other_args = arguments.partition { |arg| arg.is_a?(Hash) && arg.key?(:request_id) }
    @request_id = request_id_arg.first[:request_id] rescue nil
    self.arguments = other_args if other_args.any?
  end
  @request_id
end

This retains the usual if/end/return pattern and should fix the nil assignment bug.

@jason-raitz jason-raitz marked this pull request as ready for review February 17, 2026 21:53
Copy link
Member

@anarchivist anarchivist left a comment

Choose a reason for hiding this comment

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

👏 i like the direction this took! r+.

Copy link
Member

@danschmidt5189 danschmidt5189 left a comment

Choose a reason for hiding this comment

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

Looks good, I like how this turned out, very clean / Rails-y.

Copy link
Member

@awilfox awilfox 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 cleaning it up so well! r+

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants