Skip to content

[WIP] Put katello event queue handler back into Dynflow #11363

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

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

jturel
Copy link
Member

@jturel jturel commented Apr 8, 2025

What are the changes introduced in this pull request?

I decided to leverage AI to answer an age-old question: how can the katello event queue without dynflow? After an intrepid vibe coding session an answer emerged: run the katello event queue with dynflow. The code you are about to read is 100% AI generated.

Jokes aside, using this approach or one like it will stop running the queue in background threads in the web process which is an improvement. Not yet sure if there are any practical downsides to the changes here, but it is functional!

Considerations taken when implementing this change?

Trust AI completely

What are the testing steps for this pull request?

TBD

suspend do
katello_event = ::Katello::EventQueue.next_event(event.event_type, event.object_id)
if katello_event
handler = ::Katello::EventMonitor::PollerThread.new
Copy link
Member Author

Choose a reason for hiding this comment

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

PollerThread is the original name of the class. It does not spawn any threads

@jturel jturel marked this pull request as draft April 8, 2025 01:48
Comment on lines 22 to 18
def plan
plan_self
end

Copy link
Member

Choose a reason for hiding this comment

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

You can drop this, there's a general blanket implementation in dynflow itself that covers this.

end

def run(event = nil)
match(event,
Copy link
Member

Choose a reason for hiding this comment

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

A good old case should work here as well and make it look more ruby-like.

Comment on lines 46 to 49
katello_event = ::Katello::EventQueue.oldest_runnable_event
if katello_event
# Passing this data to run avoids extra db querying
plan_event(Handle[katello_event.event_type, katello_event.object_id])
Copy link
Member

Choose a reason for hiding this comment

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

Why not process the event straight away? I mean this works, but it adds an unnecessary round trip

@@ -77,6 +77,14 @@ class Engine < ::Rails::Engine
ForemanTasks.dynflow.eager_load_actions!
end

initializer "katello.start_katello_events", before: :finisher_hook do
unless Rails.env.test?
ForemanTasks.dynflow.config.post_executor_init do |world|
Copy link
Member

Choose a reason for hiding this comment

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

if the action stops/pauses/whatever, the event queue won't be processed until the dynflow-sidekiq@orchestrator service is restarted. We should pay extra care to make the action essential immortal

module Actions
module Katello
module EventQueue
class Monitor < Actions::EntryAction
Copy link
Member

Choose a reason for hiding this comment

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

The default rescue_strategy is to pause the action. Iirc paused actions still hold the singleton lock. Using any of the other two strategies which would cause the lock to be unlocked on failure would probably be better idea for more hands-off operation.

end

Poll = Algebrick.atom

Copy link
Member

Choose a reason for hiding this comment

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

Unless stated otherwise, actions use the default queue. The default sidekiq queue is already used for almost everything, is it ok that event processing might be delayed?

Copy link
Member Author

Choose a reason for hiding this comment

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

It should be OK in combination with your prior point: instead of using a Poll -> Handle ping-pong the Poll will fully drain the queue in a loop which can be broken early with if world.terminating? to make sure shutdown isn't blocked.

module Actions
module Katello
module EventQueue
class Monitor < Actions::EntryAction
Copy link
Member

Choose a reason for hiding this comment

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

Iirc foreman-maintain performs checks for long running tasks before upgrade, we'll probably need to whitelist this new action in there.

@jturel jturel force-pushed the katello_event_queue_dynflow branch from 20e9a1c to efdf968 Compare April 14, 2025 22:37
@qcjames53
Copy link
Contributor

Hey @jturel, thanks for the PR. We're conducting a review of the open PRs this afternoon and were just passing through. Please ping us when you'd like a review!

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

Successfully merging this pull request may close these issues.

3 participants