#401 nice cpu limit

main
Maveno 11 months ago
parent 8c7eee580d
commit 1d4507782b

@ -153,11 +153,15 @@ def getUnmuxSequence(trackDescriptor: TrackDescriptor, sourcePath, targetPrefix,
@click.option('-l', '--label', type=str, default='', help='Label to be used as filename prefix') @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("-o", "--output-directory", type=str, default='')
@click.option("-s", "--subtitles-only", is_flag=True, default=False) @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')
def unmux(ctx, def unmux(ctx,
paths, paths,
label, label,
output_directory, output_directory,
subtitles_only): subtitles_only,
nice,
cpu):
existingSourcePaths = [p for p in paths if os.path.isfile(p)] existingSourcePaths = [p for p in paths if os.path.isfile(p)]
ctx.obj['logger'].debug(f"\nUnmuxing {len(existingSourcePaths)} files") ctx.obj['logger'].debug(f"\nUnmuxing {len(existingSourcePaths)} files")
@ -195,7 +199,7 @@ def unmux(ctx,
if unmuxSequence: if unmuxSequence:
if not ctx.obj['dry_run']: if not ctx.obj['dry_run']:
ctx.obj['logger'].debug(f"Executing unmuxing sequence: {' '.join(unmuxSequence)}") ctx.obj['logger'].debug(f"Executing unmuxing sequence: {' '.join(unmuxSequence)}")
out, err, rc = executeProcess(unmuxSequence) out, err, rc = executeProcess(unmuxSequence, niceness=nice, cpu_percent=cpu)
if rc: if rc:
ctx.obj['logger'].error(f"Unmuxing of stream {trackDescriptor.getIndex()} failed with error ({rc}) {err}") ctx.obj['logger'].error(f"Unmuxing of stream {trackDescriptor.getIndex()} failed with error ({rc}) {err}")
else: else:
@ -314,6 +318,9 @@ def checkUniqueDispositions(context, mediaDescriptor: MediaDescriptor):
@click.option("--no-signature", is_flag=True, default=False) @click.option("--no-signature", is_flag=True, default=False)
@click.option("--keep-mkvmerge-metadata", 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')
def convert(ctx, def convert(ctx,
paths, paths,
label, label,
@ -360,7 +367,10 @@ def convert(ctx,
dont_pass_dispositions, dont_pass_dispositions,
no_prompt, no_prompt,
no_signature, no_signature,
keep_mkvmerge_metadata): keep_mkvmerge_metadata,
nice,
cpu):
"""Batch conversion of audiovideo files in format suitable for web playback, e.g. jellyfin """Batch conversion of audiovideo files in format suitable for web playback, e.g. jellyfin
Files found under PATHS will be converted according to parameters. Files found under PATHS will be converted according to parameters.
@ -387,6 +397,12 @@ def convert(ctx,
context['no_signature'] = no_signature context['no_signature'] = no_signature
context['keep_mkvmerge_metadata'] = keep_mkvmerge_metadata context['keep_mkvmerge_metadata'] = keep_mkvmerge_metadata
context['resource_limits'] = {}
context['resource_limits']['niceness'] = nice
context['resource_limits']['cpu_percent'] = cpu
context['denoiser'] = NlmeansController(parameters = denoise, context['denoiser'] = NlmeansController(parameters = denoise,
strength = denoise_strength, strength = denoise_strength,
patchSize = denoise_patch_size, patchSize = denoise_patch_size,

@ -43,6 +43,10 @@ class FfxController():
self.__configurationData = self.__context['config'].getData() self.__configurationData = self.__context['config'].getData()
# Convenience
self.__niceness = self.__context['resource_limits']['niceness'] if 'resource_limits' in self.__context.keys() and 'niceness' in self.__context['resource_limits'].keys() else 99
self.__cpuPercent = self.__context['resource_limits']['cpu_percent'] if 'resource_limits' in self.__context.keys() and 'cpu_percent' in self.__context['resource_limits'].keys() else 0
self.__logger = context['logger'] self.__logger = context['logger']
@ -268,7 +272,7 @@ class FfxController():
self.__logger.debug(f"FfxController.runJob() commandSequence:{' '.join(commandSequence)}") self.__logger.debug(f"FfxController.runJob() commandSequence:{' '.join(commandSequence)}")
if not self.__context['dry_run']: if not self.__context['dry_run']:
executeProcess(commandSequence) executeProcess(commandSequence, niceness=self.__niceness, cpu_percent=self.__cpuPercent)
if videoEncoder == VideoEncoder.VP9: if videoEncoder == VideoEncoder.VP9:
@ -296,7 +300,7 @@ class FfxController():
os.remove(FfxController.TEMP_FILE_NAME) os.remove(FfxController.TEMP_FILE_NAME)
if not self.__context['dry_run']: if not self.__context['dry_run']:
executeProcess(commandSequence1) executeProcess(commandSequence1, niceness=self.__niceness, cpu_percent=self.__cpuPercent)
commandSequence2 = (commandTokens commandSequence2 = (commandTokens
+ self.__targetMediaDescriptor.getImportFileTokens() + self.__targetMediaDescriptor.getImportFileTokens()
@ -318,7 +322,7 @@ class FfxController():
self.__logger.debug(f"FfxController.runJob() commandSequence2:{' '.join(commandSequence2)}") self.__logger.debug(f"FfxController.runJob() commandSequence2:{' '.join(commandSequence2)}")
if not self.__context['dry_run']: if not self.__context['dry_run']:
out, err, rc = executeProcess(commandSequence2) out, err, rc = executeProcess(commandSequence2, niceness=self.__niceness, cpu_percent=self.__cpuPercent)
if rc: if rc:
raise click.ClickException(f"Command resulted in error: rc={rc} error={err}") raise click.ClickException(f"Command resulted in error: rc={rc} error={err}")
@ -345,4 +349,4 @@ class FfxController():
str(length), str(length),
path] path]
out, err, rc = executeProcess(commandTokens) out, err, rc = executeProcess(commandTokens, niceness=self.__niceness, cpu_percent=self.__cpuPercent)

@ -1,9 +1,29 @@
import subprocess import subprocess, click
from typing import List from typing import List
def executeProcess(commandSequence: List[str], directory: str = None): def executeProcess(commandSequence: List[str], directory: str = None, niceness: int = 99, cpu_percent: int = 0):
# process = subprocess.Popen([t.encode('utf-8') for t in commandSequence], stdout=subprocess.PIPE, stderr=subprocess.PIPE) """
process = subprocess.Popen(commandSequence, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8', cwd = directory) niceness -20 bis +19
cpu_percent: 1 bis 99
"""
nice = int(niceness)
cpu = int(cpu_percent)
click.echo(f"nice {nice} cpu {cpu}")
niceSequence = []
if nice >= -20 and nice <= 19:
niceSequence += ['nice', '-n', str(nice)]
if cpu >= 1 and cpu <= 99:
niceSequence += ['cpulimit', '-l', str(cpu), '--']
niceCommand = niceSequence + commandSequence
click.echo(f"executeProcess(): {' '.join(niceCommand)}")
process = subprocess.Popen(niceCommand, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8', cwd = directory)
output, error = process.communicate() output, error = process.communicate()
# return output.decode('utf-8'), error.decode('utf-8'), process.returncode
return output, error, process.returncode return output, error, process.returncode

@ -103,6 +103,10 @@ class Scenario():
self._testDbFilePath = os.path.join(self._testDirectory, 'test.db') self._testDbFilePath = os.path.join(self._testDirectory, 'test.db')
self.createEmptyTestDatabase() self.createEmptyTestDatabase()
# Convenience
self._niceness = self._context['resource_limits']['niceness'] if 'resource_limits' in self._context.keys() and 'niceness' in self._context['resource_limits'].keys() else 99
self._cpuPercent = self._context['resource_limits']['cpu_percent'] if 'resource_limits' in self._context.keys() and 'cpu_percent' in self._context['resource_limits'].keys() else 99
def createEmptyTestDatabase(self): def createEmptyTestDatabase(self):

@ -118,7 +118,7 @@ class Scenario1(Scenario):
self._logger.debug(f"{variantLabel}: Test sequence: {commandSequence}") self._logger.debug(f"{variantLabel}: Test sequence: {commandSequence}")
out, err, rc = executeProcess(commandSequence, directory = self._testDirectory) out, err, rc = executeProcess(commandSequence, directory = self._testDirectory, niceness=self._niceness, cpu_percent=self._cpuPercent)
if out and self._context['verbosity'] >= 9: if out and self._context['verbosity'] >= 9:
self._logger.debug(f"{variantLabel}: Process output: {out}") self._logger.debug(f"{variantLabel}: Process output: {out}")

@ -103,7 +103,7 @@ class Scenario2(Scenario):
self._logger.debug(f"{variantLabel}: Test sequence: {commandSequence}") self._logger.debug(f"{variantLabel}: Test sequence: {commandSequence}")
out, err, rc = executeProcess(commandSequence, directory = self._testDirectory) out, err, rc = executeProcess(commandSequence, directory = self._testDirectory, niceness=self._niceness, cpu_percent=self._cpuPercent)
if out and self._context['verbosity'] >= 9: if out and self._context['verbosity'] >= 9:
self._logger.debug(f"{variantLabel}: Process output: {out}") self._logger.debug(f"{variantLabel}: Process output: {out}")

@ -187,7 +187,7 @@ class Scenario4(Scenario):
self._logger.debug(f"{variantLabel}: Test sequence: {commandSequence}") self._logger.debug(f"{variantLabel}: Test sequence: {commandSequence}")
out, err, rc = executeProcess(commandSequence, directory = self._testDirectory) out, err, rc = executeProcess(commandSequence, directory = self._testDirectory, niceness=self._niceness, cpu_percent=self._cpuPercent)
if out and self._context['verbosity'] >= 9: if out and self._context['verbosity'] >= 9:
self._logger.debug(f"{variantLabel}: Process output: {out}") self._logger.debug(f"{variantLabel}: Process output: {out}")

Loading…
Cancel
Save