Fix cpu percentage interpretations
This commit is contained in:
@@ -30,6 +30,11 @@ if TYPE_CHECKING:
|
||||
from ffx.track_descriptor import TrackDescriptor
|
||||
|
||||
LIGHTWEIGHT_COMMANDS = {None, 'version', 'help', 'configure_workstation', 'upgrade'}
|
||||
CPU_OPTION_HELP = (
|
||||
"Limit CPU for started processes. Use an absolute cpulimit value such as 200 "
|
||||
+ "(about 2 cores), or use a percentage such as 25% for a share of present cores. "
|
||||
+ "Omit to disable; 0 also disables."
|
||||
)
|
||||
|
||||
|
||||
def normalizeNicenessOption(ctx, param, value):
|
||||
@@ -286,11 +291,11 @@ def getUnmuxSequence(trackDescriptor: TrackDescriptor, sourcePath, targetPrefix,
|
||||
)
|
||||
@click.option(
|
||||
'--cpu',
|
||||
type=int,
|
||||
type=str,
|
||||
default=None,
|
||||
callback=normalizeCpuOption,
|
||||
show_default='disabled',
|
||||
help='Limit CPU percent of started processes (1..99). Omit to disable; 0 also disables.',
|
||||
help=CPU_OPTION_HELP,
|
||||
)
|
||||
def unmux(ctx,
|
||||
paths,
|
||||
@@ -309,6 +314,7 @@ def unmux(ctx,
|
||||
|
||||
ctx.obj['resource_limits'] = {}
|
||||
ctx.obj['resource_limits']['niceness'] = nice
|
||||
ctx.obj['resource_limits']['cpu_limit'] = cpu
|
||||
ctx.obj['resource_limits']['cpu_percent'] = cpu
|
||||
|
||||
for sourcePath in existingSourcePaths:
|
||||
@@ -377,11 +383,11 @@ def unmux(ctx,
|
||||
)
|
||||
@click.option(
|
||||
'--cpu',
|
||||
type=int,
|
||||
type=str,
|
||||
default=None,
|
||||
callback=normalizeCpuOption,
|
||||
show_default='disabled',
|
||||
help='Limit CPU percent of started processes (1..99). Omit to disable; 0 also disables.',
|
||||
help=CPU_OPTION_HELP,
|
||||
)
|
||||
def cropdetect(ctx,
|
||||
paths,
|
||||
@@ -394,6 +400,7 @@ def cropdetect(ctx,
|
||||
|
||||
ctx.obj['resource_limits'] = {}
|
||||
ctx.obj['resource_limits']['niceness'] = nice
|
||||
ctx.obj['resource_limits']['cpu_limit'] = cpu
|
||||
ctx.obj['resource_limits']['cpu_percent'] = cpu
|
||||
|
||||
for sourcePath in existingSourcePaths:
|
||||
@@ -536,11 +543,11 @@ def checkUniqueDispositions(context, mediaDescriptor: MediaDescriptor):
|
||||
)
|
||||
@click.option(
|
||||
'--cpu',
|
||||
type=int,
|
||||
type=str,
|
||||
default=None,
|
||||
callback=normalizeCpuOption,
|
||||
show_default='disabled',
|
||||
help='Limit CPU percent of started processes (1..99). Omit to disable; 0 also disables.',
|
||||
help=CPU_OPTION_HELP,
|
||||
)
|
||||
|
||||
@click.option('--rename-only', is_flag=True, default=False, help='Only renaming, no recoding')
|
||||
@@ -643,6 +650,7 @@ def convert(ctx,
|
||||
|
||||
context['resource_limits'] = {}
|
||||
context['resource_limits']['niceness'] = nice
|
||||
context['resource_limits']['cpu_limit'] = cpu
|
||||
context['resource_limits']['cpu_percent'] = cpu
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import os
|
||||
import shlex
|
||||
import subprocess
|
||||
from typing import Iterable, List
|
||||
@@ -9,9 +10,9 @@ COMMAND_NOT_FOUND_RETURN_CODE = 127
|
||||
MIN_NICENESS = -20
|
||||
MAX_NICENESS = 19
|
||||
DISABLED_NICENESS_SENTINEL = 99
|
||||
MIN_CPU_PERCENT = 1
|
||||
MAX_CPU_PERCENT = 99
|
||||
DISABLED_CPU_PERCENT_SENTINEL = 0
|
||||
MIN_CPU_PERCENT = 1
|
||||
MAX_CPU_PERCENT = 100
|
||||
|
||||
|
||||
def formatCommandSequence(commandSequence: Iterable[str]) -> str:
|
||||
@@ -35,18 +36,42 @@ def normalizeNiceness(niceness) -> int | None:
|
||||
return niceness
|
||||
|
||||
|
||||
def getPresentCpuCount() -> int:
|
||||
if hasattr(os, 'sched_getaffinity'):
|
||||
affinity = os.sched_getaffinity(0)
|
||||
if affinity:
|
||||
return len(affinity)
|
||||
|
||||
cpuCount = os.cpu_count()
|
||||
return cpuCount if cpuCount and cpuCount > 0 else 1
|
||||
|
||||
|
||||
def normalizeCpuPercent(cpuPercent) -> int | None:
|
||||
if cpuPercent is None:
|
||||
return None
|
||||
|
||||
cpuPercent = str(cpuPercent).strip()
|
||||
if cpuPercent.endswith('%'):
|
||||
percentValue = int(cpuPercent[:-1].strip())
|
||||
if percentValue == DISABLED_CPU_PERCENT_SENTINEL:
|
||||
return None
|
||||
|
||||
if percentValue < MIN_CPU_PERCENT or percentValue > MAX_CPU_PERCENT:
|
||||
raise ValueError(
|
||||
f"CPU percentage must be between {MIN_CPU_PERCENT}% and {MAX_CPU_PERCENT}%, "
|
||||
+ f"or {DISABLED_CPU_PERCENT_SENTINEL} to disable."
|
||||
)
|
||||
|
||||
return percentValue * getPresentCpuCount()
|
||||
|
||||
cpuPercent = int(cpuPercent)
|
||||
if cpuPercent == DISABLED_CPU_PERCENT_SENTINEL:
|
||||
return None
|
||||
|
||||
if cpuPercent < MIN_CPU_PERCENT or cpuPercent > MAX_CPU_PERCENT:
|
||||
if cpuPercent < MIN_CPU_PERCENT:
|
||||
raise ValueError(
|
||||
f"CPU limit must be between {MIN_CPU_PERCENT} and {MAX_CPU_PERCENT}, "
|
||||
+ f"or {DISABLED_CPU_PERCENT_SENTINEL} to disable."
|
||||
"CPU limit must be a positive absolute value such as 200, "
|
||||
+ f"a percentage such as 25%, or {DISABLED_CPU_PERCENT_SENTINEL} to disable."
|
||||
)
|
||||
|
||||
return cpuPercent
|
||||
@@ -55,7 +80,7 @@ def normalizeCpuPercent(cpuPercent) -> int | None:
|
||||
def getWrappedCommandSequence(commandSequence: List[str], context: dict = None) -> List[str]:
|
||||
"""
|
||||
niceness: -20 to 19, disabled when unset
|
||||
cpu_percent: 1 to 99, disabled when unset
|
||||
cpu limit: positive absolute cpulimit value, or a machine-wide percentage
|
||||
|
||||
When both limits are configured, cpulimit wraps a nice-adjusted command:
|
||||
cpulimit -l <cpu> -- nice -n <niceness> <command>
|
||||
@@ -63,7 +88,9 @@ def getWrappedCommandSequence(commandSequence: List[str], context: dict = None)
|
||||
|
||||
resourceLimits = (context or {}).get('resource_limits', {})
|
||||
niceness = normalizeNiceness(resourceLimits.get('niceness'))
|
||||
cpu_percent = normalizeCpuPercent(resourceLimits.get('cpu_percent'))
|
||||
cpu_percent = normalizeCpuPercent(
|
||||
resourceLimits.get('cpu_limit', resourceLimits.get('cpu_percent'))
|
||||
)
|
||||
wrappedCommandSequence = [str(token) for token in commandSequence]
|
||||
|
||||
if niceness is not None:
|
||||
|
||||
Reference in New Issue
Block a user