Optimizes niceness and cpulimit usage
This commit is contained in:
@@ -32,6 +32,24 @@ if TYPE_CHECKING:
|
||||
LIGHTWEIGHT_COMMANDS = {None, 'version', 'help', 'configure_workstation', 'upgrade'}
|
||||
|
||||
|
||||
def normalizeNicenessOption(ctx, param, value):
|
||||
from ffx.process import normalizeNiceness
|
||||
|
||||
try:
|
||||
return normalizeNiceness(value)
|
||||
except ValueError as ex:
|
||||
raise click.BadParameter(str(ex)) from ex
|
||||
|
||||
|
||||
def normalizeCpuOption(ctx, param, value):
|
||||
from ffx.process import normalizeCpuPercent
|
||||
|
||||
try:
|
||||
return normalizeCpuPercent(value)
|
||||
except ValueError as ex:
|
||||
raise click.BadParameter(str(ex)) from ex
|
||||
|
||||
|
||||
|
||||
@click.group()
|
||||
@click.pass_context
|
||||
@@ -194,6 +212,7 @@ def upgrade(ctx, branch):
|
||||
|
||||
commandSequences += [
|
||||
['git', 'pull'],
|
||||
[bundlePipPath, 'install', '--upgrade', 'pip', 'setuptools', 'wheel'],
|
||||
[bundlePipPath, 'install', '--editable', '.'],
|
||||
]
|
||||
|
||||
@@ -257,8 +276,22 @@ def getUnmuxSequence(trackDescriptor: TrackDescriptor, sourcePath, targetPrefix,
|
||||
@click.option('-l', '--label', type=str, default='', help='Label to be used as filename prefix')
|
||||
@click.option("-o", "--output-directory", type=str, default='')
|
||||
@click.option("-s", "--subtitles-only", is_flag=True, default=False)
|
||||
@click.option('--nice', type=int, default=99, help='Niceness of started processes')
|
||||
@click.option('--cpu', type=int, default=0, help='Limit CPU for started processes to percent')
|
||||
@click.option(
|
||||
'--nice',
|
||||
type=int,
|
||||
default=None,
|
||||
callback=normalizeNicenessOption,
|
||||
show_default='disabled',
|
||||
help='Adjust niceness of started processes (-20..19). Omit to disable; 99 also disables.',
|
||||
)
|
||||
@click.option(
|
||||
'--cpu',
|
||||
type=int,
|
||||
default=None,
|
||||
callback=normalizeCpuOption,
|
||||
show_default='disabled',
|
||||
help='Limit CPU percent of started processes (1..99). Omit to disable; 0 also disables.',
|
||||
)
|
||||
def unmux(ctx,
|
||||
paths,
|
||||
label,
|
||||
@@ -334,8 +367,22 @@ def unmux(ctx,
|
||||
@click.pass_context
|
||||
|
||||
@click.argument('paths', nargs=-1)
|
||||
@click.option('--nice', type=int, default=99, help='Niceness of started processes')
|
||||
@click.option('--cpu', type=int, default=0, help='Limit CPU for started processes to percent')
|
||||
@click.option(
|
||||
'--nice',
|
||||
type=int,
|
||||
default=None,
|
||||
callback=normalizeNicenessOption,
|
||||
show_default='disabled',
|
||||
help='Adjust niceness of started processes (-20..19). Omit to disable; 99 also disables.',
|
||||
)
|
||||
@click.option(
|
||||
'--cpu',
|
||||
type=int,
|
||||
default=None,
|
||||
callback=normalizeCpuOption,
|
||||
show_default='disabled',
|
||||
help='Limit CPU percent of started processes (1..99). Omit to disable; 0 also disables.',
|
||||
)
|
||||
def cropdetect(ctx,
|
||||
paths,
|
||||
nice,
|
||||
@@ -479,8 +526,22 @@ def checkUniqueDispositions(context, mediaDescriptor: MediaDescriptor):
|
||||
@click.option("--no-signature", is_flag=True, default=False)
|
||||
@click.option("--keep-mkvmerge-metadata", is_flag=True, default=False)
|
||||
|
||||
@click.option('--nice', type=int, default=99, help='Niceness of started processes')
|
||||
@click.option('--cpu', type=int, default=0, help='Limit CPU for started processes to percent')
|
||||
@click.option(
|
||||
'--nice',
|
||||
type=int,
|
||||
default=None,
|
||||
callback=normalizeNicenessOption,
|
||||
show_default='disabled',
|
||||
help='Adjust niceness of started processes (-20..19). Omit to disable; 99 also disables.',
|
||||
)
|
||||
@click.option(
|
||||
'--cpu',
|
||||
type=int,
|
||||
default=None,
|
||||
callback=normalizeCpuOption,
|
||||
show_default='disabled',
|
||||
help='Limit CPU percent of started processes (1..99). Omit to disable; 0 also disables.',
|
||||
)
|
||||
|
||||
@click.option('--rename-only', is_flag=True, default=False, help='Only renaming, no recoding')
|
||||
|
||||
|
||||
@@ -6,29 +6,72 @@ from .logging_utils import get_ffx_logger
|
||||
|
||||
COMMAND_TIMED_OUT_RETURN_CODE = 124
|
||||
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
|
||||
|
||||
|
||||
def formatCommandSequence(commandSequence: Iterable[str]) -> str:
|
||||
return shlex.join([str(token) for token in commandSequence])
|
||||
|
||||
|
||||
def normalizeNiceness(niceness) -> int | None:
|
||||
if niceness is None:
|
||||
return None
|
||||
|
||||
niceness = int(niceness)
|
||||
if niceness == DISABLED_NICENESS_SENTINEL:
|
||||
return None
|
||||
|
||||
if niceness < MIN_NICENESS or niceness > MAX_NICENESS:
|
||||
raise ValueError(
|
||||
f"Niceness must be between {MIN_NICENESS} and {MAX_NICENESS}, "
|
||||
+ f"or {DISABLED_NICENESS_SENTINEL} to disable."
|
||||
)
|
||||
|
||||
return niceness
|
||||
|
||||
|
||||
def normalizeCpuPercent(cpuPercent) -> int | None:
|
||||
if cpuPercent is None:
|
||||
return None
|
||||
|
||||
cpuPercent = int(cpuPercent)
|
||||
if cpuPercent == DISABLED_CPU_PERCENT_SENTINEL:
|
||||
return None
|
||||
|
||||
if cpuPercent < MIN_CPU_PERCENT or cpuPercent > MAX_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."
|
||||
)
|
||||
|
||||
return cpuPercent
|
||||
|
||||
|
||||
def getWrappedCommandSequence(commandSequence: List[str], context: dict = None) -> List[str]:
|
||||
"""
|
||||
niceness -20 bis +19
|
||||
cpu_percent: 1 bis 99
|
||||
niceness: -20 to 19, disabled when unset
|
||||
cpu_percent: 1 to 99, disabled when unset
|
||||
|
||||
When both limits are configured, cpulimit wraps a nice-adjusted command:
|
||||
cpulimit -l <cpu> -- nice -n <niceness> <command>
|
||||
"""
|
||||
|
||||
niceSequence = []
|
||||
resourceLimits = (context or {}).get('resource_limits', {})
|
||||
niceness = normalizeNiceness(resourceLimits.get('niceness'))
|
||||
cpu_percent = normalizeCpuPercent(resourceLimits.get('cpu_percent'))
|
||||
wrappedCommandSequence = [str(token) for token in commandSequence]
|
||||
|
||||
niceness = int((context or {}).get('resource_limits', {}).get('niceness', 99))
|
||||
cpu_percent = int((context or {}).get('resource_limits', {}).get('cpu_percent', 0))
|
||||
if niceness is not None:
|
||||
wrappedCommandSequence = ['nice', '-n', str(niceness)] + wrappedCommandSequence
|
||||
if cpu_percent is not None:
|
||||
wrappedCommandSequence = ['cpulimit', '-l', str(cpu_percent), '--'] + wrappedCommandSequence
|
||||
|
||||
if niceness >= -20 and niceness <= 19:
|
||||
niceSequence += ['nice', '-n', str(niceness)]
|
||||
if cpu_percent >= 1:
|
||||
niceSequence += ['cpulimit', '-l', str(cpu_percent), '--']
|
||||
|
||||
return niceSequence + [str(token) for token in commandSequence]
|
||||
return wrappedCommandSequence
|
||||
|
||||
|
||||
def getProcessTimeoutSeconds(context: dict = None, timeoutSeconds: float = None):
|
||||
|
||||
Reference in New Issue
Block a user