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

Add global enable_listen_notify configuration to disable both notify and listen #810

Merged

Conversation

mitchellhenke
Copy link
Contributor

@mitchellhenke mitchellhenke commented Jan 24, 2023

Based on discussion in #731 (comment), this is a draft implementation of allowing the LISTEN/NOTIFY functionality to be configurable

I need to add some tests, but I wasn't sure on my initial approach.

Copy link
Owner

@bensheldon bensheldon left a comment

Choose a reason for hiding this comment

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

@mitchellhenke I think all the pieces are here, but I left some comments about the particulars.

Also, this led me to create #811, which is very out of scope for your change, but I wanted to document the other observations I had too, in case it provides some more context for your changes.

Comment on lines 337 to 342
ActiveModel::Type::Boolean.new.cast(
options[:enable_listen_notify] ||
rails_config[:enable_listen_notify] ||
env['GOOD_JOB_ENABLE_LISTEN_NOTIFY'] ||
DEFAULT_ENABLE_LISTEN_NOTIFY
)
Copy link
Owner

Choose a reason for hiding this comment

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

Because these are Booleans, I think this logic needs to do cast-to-boolean and then return the value if it isn't nil, for each and every value.

Right now I think it's possible for false values to not be set if passed in through rails_config.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ahhhhh, yep, thank you

@@ -165,6 +166,8 @@ def create_executor
end

def listen(delay: 0)
return unless @enable_listening
Copy link
Owner

@bensheldon bensheldon Jan 25, 2023

Choose a reason for hiding this comment

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

This can't be an early return. Creating the future is necessary because the Notifier is a bit more of a general purpose Reactor now with more responsibilities than just LISTENing e.g. this background thread creates/manages the Process record.

It will be messier but I think the unless @enable_listening needs to go within the Future/thread:

  1. Calling connection.execute("LISTEN #{CHANNEL}") and the ActiveSupport Notification wrapping it, though the callback trigger needs to remain
  2. Within #wait_for_notify having !@enable_listening that cause the logic to fall down to the sleep WAIT_INTERVAL path
  3. Calling connection.execute("UNLISTEN *")

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for explaining, I've added a couple commits to do the above and also tried avoiding checking out the connection. I'm not sure if it's right, and I couldn't figure out how to test it. notifier.connection was always nil whether or not enable_listening was enabled.

@bensheldon
Copy link
Owner

@mitchellhenke I just pushed up a few tweaks to this. I'm happy with where it ended up, but I'd love your eyes on it one more time before I merge it.

Also, I just wanted to document that this will mean that the Probe Server's status/connected will return a HTTP error status when listening is not used. Are you using that functionality?

@mitchellhenke
Copy link
Contributor Author

mitchellhenke commented Jan 27, 2023

@mitchellhenke I just pushed up a few tweaks to this. I'm happy with where it ended up, but I'd love your eyes on it one more time before I merge it.

Thanks! It makes sense to me.

Also, I just wanted to document that this will mean that the Probe Server's status/connected will return a HTTP error status when listening is not used. Are you using that functionality?

Ohhh, I wouldn't want to break that. I'm not using it currently, but might in the future. I think I understand this a bit better now. My primary goal at the outset was to limit the herd of queue selection queries that happens when enqueuing a lot of jobs (not necessarily in bulk).

It could be a lot simpler and still accomplish the goal by adding a notify argument to the enqueue (and enqueue_at?) methods to specify whether to skip or send the NOTIFY. Whether or not that should be globally configurable feels a bit debatable, but I'd be happy to open a PR that at least adds the argument.

@bensheldon
Copy link
Owner

It could be a lot simpler and still accomplish the goal by adding a notify argument to the enqueue (and enqueue_at?) methods to specify whether to skip or send the NOTIFY.

I agree on the simpler aspect of getting this closer to the individual job, but we aren't able to (or I'm very reluctant to) modify the Adapter interface.

I'm thinking instead that it could be done as a job extension so that you could do something like this:

MyJob.set(good_job_notify: false).perform_later

Does that more closely match your needs? I think I can whip that up pretty quick.

@bensheldon
Copy link
Owner

@mitchellhenke I whipped up that extension 😄 : #814

@mitchellhenke
Copy link
Contributor Author

@mitchellhenke I whipped up that extension 😄 : #814

Thank you! Is it possible to opt in to not notifying for all jobs? The limitation on retries has me worry about a cascade of failures becoming a cascade of notifications on retry.

@bensheldon
Copy link
Owner

@mitchellhenke I updated #814 to preserve the setting across retries.

@bensheldon
Copy link
Owner

@mitchellhenke I updated the PR to also be serialized/preserved into the job data so that it will persist across job retries.

@bensheldon bensheldon closed this Jan 29, 2023
@bensheldon bensheldon reopened this Jan 29, 2023
@bensheldon
Copy link
Owner

Whoops, didn't mean to close this.

@mitchellhenke
Copy link
Contributor Author

@bensheldon yeah, that looks good to me!

…configuration

# Conflicts:
#	lib/good_job/notifier.rb
…configuration

# Conflicts:
#	lib/good_job/adapter.rb
@bensheldon bensheldon added the enhancement New feature or request label Feb 6, 2023
@bensheldon bensheldon changed the title Add enable_listen_notify configuration Add global enable_listen_notify configuration to disable both notify and listen Feb 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants