-
Notifications
You must be signed in to change notification settings - Fork 897
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
[V2V] Add CPU and network throttling in model #18576
[V2V] Add CPU and network throttling in model #18576
Conversation
app/models/conversion_host.rb
Outdated
value == 'unlimited' ? value : "#{value.to_i / active_tasks.size}" | ||
end | ||
|
||
def apply_virtv2v_limits(path, limits) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are there any reasonable defaults we can set for path
and/or limits
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope. Path is stored in the task and specific to a single migration, so no default. And limits is built by the task object from different sources, so the default can be {}
.
app/models/conversion_host.rb
Outdated
@@ -56,6 +56,22 @@ def ipaddress(family = 'ipv4') | |||
resource.ipaddresses.detect { |ip| IPAddr.new(ip).send("#{family}?") } | |||
end | |||
|
|||
def get_cpu_limit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need get_
, or can we just redefine the existing method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm neither a big fan of get_
. It's an attribute of ConversionHost, but should default to Settings.transformation.limits.cpu_limit_per_host
which we implemented in a previous PR. Can we override an attribute with a method ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I think this is the way: http://joshfrankel.me/blog/overriding-activerecord-getters-with-the-same-attribute-name/
app/models/infra_conversion_job.rb
Outdated
@@ -104,6 +104,11 @@ def poll_conversion | |||
|
|||
case v2v_status | |||
when 'active' | |||
begin | |||
migration_task.apply_virtv2v_limits if migration_task.options.fetch_path(:virtv2v_wrapper, 'throttling_file') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is throttling_file
coming from? Is that a configurable thing? Or is hard coding it ok?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It comes from the output of virt-v2v-wrapper, like state_file
. So, pretty much hard coded.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fdupont-redhat, 2 question
- are we doing this
apply_virtv2v_limits
in every polling, like every 15s, regardless limits changed or not? - so this control flow is
infra_conversion_job -> miq_request_task.apply_virtv2v_limits -> conversion_host.apply_virtv2v_limits
? seems convoluted. This is the reason I asked to re-consider where we want to keep the throttling logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree with @jameswn. Seems like too many hoops.
app/models/conversion_host.rb
Outdated
end | ||
|
||
def get_network_limit | ||
value = network_limit || Setting.transformation.limits.network_limit_per_host |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Settings
@@ -233,6 +233,16 @@ def get_conversion_state | |||
update_options(updates) | |||
end | |||
|
|||
# Applies the limits for the task. | |||
# CPU and network limits are set at the host level but other limits may not. | |||
def apply_virtv2v_limits |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am thinking where this and forthcoming throttling code should reside.
May be a mixin
or a sub-module of infra_conversion_job
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For me, the logic should reside in the task as it has all the knowledge of the execution context. The infra_conversion_job is mainly a state machine, and should remain pretty stupid and delegate any intelligence to the task. As whether it should be in a mixin, I'm wondering how much code can be reused by other classes.
app/models/infra_conversion_job.rb
Outdated
@@ -104,6 +104,11 @@ def poll_conversion | |||
|
|||
case v2v_status | |||
when 'active' | |||
begin | |||
migration_task.apply_virtv2v_limits if migration_task.options.fetch_path(:virtv2v_wrapper, 'throttling_file') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fdupont-redhat, 2 question
- are we doing this
apply_virtv2v_limits
in every polling, like every 15s, regardless limits changed or not? - so this control flow is
infra_conversion_job -> miq_request_task.apply_virtv2v_limits -> conversion_host.apply_virtv2v_limits
? seems convoluted. This is the reason I asked to re-consider where we want to keep the throttling logic.
:cpu => conversion_host.get_cpu_limit, | ||
:network => conversion_host.get_network_limit | ||
} | ||
conversion_host.apply_virtv2v_limits(options[:virtv2v_wrapper]['throttling_file'], limits) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This construction of limits
seems redundant. If this self
object has no opinion on how the limits are constructed, why not let conversion_host
do it internally?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I kind of agree with @jameswnl. Seems like this could be refactored away or delegated.
hey guys what is the status of this? I don't see any updates for a couple of weeks and it is still WIP |
@fdupont-redhat @djberg96 @jameswnl any updates on this one? We're holding off on merging ManageIQ/manageiq-v2v#915 until it's ready |
3323486
to
a770fe2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
Some comments would be good if you have some time to add them.
lib/infra_conversion_throttler.rb
Outdated
# Applying the limits is done via the conversion_host which handles the writing. | ||
def self.apply_limits | ||
running_conversion_jobs.each do |ch, jobs| | ||
number_of_jobs = ch.active_tasks.size |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm if ConversionHost#active_tasks got out of sync with the running jobs somehow and was 0 then this division will blow up...maybe set this to 1 if it is 0?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. jobs.size
is safer because jobs
can't be empty inside the loop.
lib/infra_conversion_throttler.rb
Outdated
throttling_file_path = migration_task.options.fetch_path(:virtv2v_wrapper, 'throttling_file') | ||
next unless throttling_file_path | ||
limits = { | ||
:cpu => cpu_limit == 'unlimited' ? cpu_limit : (cpu_limit.to_i / number_of_jobs).to_s, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is minor but this calculation doesn't depend on anything in this loop so you could calculate it up here
Something like
cpu_limit = ch.cpu_limit || Settings.transformation.limits.cpu_limit_per_host
cpu_limit = (cpu_limit.to_i / number_of_jobs).to_s unless cpu_limit == "unlimited"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved.
@@ -40,16 +40,21 @@ def self.running_conversion_jobs | |||
# Applying the limits is done via the conversion_host which handles the writing. | |||
def self.apply_limits | |||
running_conversion_jobs.each do |ch, jobs| | |||
number_of_jobs = ch.active_tasks.size | |||
number_of_jobs = jobs.size |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 even better
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Checked commits fabiendupont/manageiq@5531207~...bb72895 with ruby 2.3.3, rubocop 0.52.1, haml-lint 0.20.0, and yamllint 1.10.0 |
…ts_to_virtv2v [V2V] Add CPU and network throttling in model (cherry picked from commit ce7c67c) https://bugzilla.redhat.com/show_bug.cgi?id=1702085
Hammer backport details:
|
…rce_limits_to_virtv2v" This reverts commit b34ee8b.
Reverted Hammer backport
|
Now that we introduced default values for CPU and network limits in the settings and that the throttling mechanism is backported into the model, it is time to add the model code to leverage the CPU and network limits at the conversion host level.
This pull request adds:
Currently all limits are at the conversion host level, so it looks like the apply_virtv2v_limits method should belong to the ConversionHost class, but later we may have limits on different scopes. This allows better flexibility to concentrate the hash build in the task.
Associated RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1690851
Depends On: ManageIQ/manageiq-gems-pending#426