feat: fix job rate limiting with --max-jobs-per-second and introduce the more flexible --max-jobs-per-timespan#3010
Conversation
…the more flexible --max-jobs-per-timespan
|
Please format your code with black: |
WalkthroughThe recent changes enhance Snakemake's command-line interface and job scheduling capabilities. Key updates include the consolidation of internal command-line arguments, the introduction of Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant CLI
participant Scheduler
participant JobRateLimiter
User->>CLI: Input command with job parameters
CLI->>Scheduler: Initialize with job parameters
Scheduler->>JobRateLimiter: Set max jobs per timespan
Scheduler->>User: Confirm job submission limits
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (invoked as PR comments)
Additionally, you can add CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 4
Outside diff range, codebase verification and nitpick comments (2)
tests/testapi.py (1)
124-139: Ensure comprehensive test coverage.The
test_job_rate_limiterfunction effectively tests the basic functionality of theJobRateLimiterclass. Consider adding edge cases and scenarios with varying time spans to ensure robustness.snakemake/scheduler.py (1)
475-488: Review job selection logic with rate limiting.The
job_selectormethod now incorporates rate limiting. Ensure that this logic correctly limits job submissions and handles edge cases where no jobs can be submitted.
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (6)
- snakemake/cli.py (7 hunks)
- snakemake/jobs.py (1 hunks)
- snakemake/scheduler.py (11 hunks)
- snakemake/settings/types.py (3 hunks)
- tests/testapi.py (2 hunks)
- tests/tests.py (1 hunks)
Additional context used
Ruff
tests/testapi.py
8-8:
sysimported but unusedRemove unused import:
sys(F401)
tests/tests.py
1677-1677:
runmay be undefined, or defined from star imports(F405)
1677-1677:
dpathmay be undefined, or defined from star imports(F405)
snakemake/cli.py
1694-1694: Do not assign a
lambdaexpression, use adefRewrite
help_internalas adef(E731)
Additional comments not posted (10)
snakemake/settings/types.py (2)
57-81: Verify regular expression pattern and error handling.The
MaxJobsPerTimespanclass uses a regular expression to parse input strings. Ensure that the pattern correctly matches all intended formats and that error messages are clear and informative.Verification successful
Regular expression and error handling are correctly implemented.
The regular expression pattern in the
MaxJobsPerTimespanclass correctly matches the intended formats, and the error handling provides clear messages for invalid inputs. No issues found.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify if the regular expression in `MaxJobsPerTimespan` correctly matches intended formats. # Test: Check if the regex matches valid formats and rejects invalid ones. rg --type python -A 5 $'MaxJobsPerTimespan.arg_re'Length of output: 80
Script:
#!/bin/bash # Description: Verify if the regular expression in `MaxJobsPerTimespan` correctly matches intended formats. # Test: Search for the `arg_re` pattern within the `MaxJobsPerTimespan` class definition. rg 'MaxJobsPerTimespan' -A 10Length of output: 4314
289-295: Ensure backward compatibility and consistency.The
max_jobs_per_secondattribute has been changed to optional, andmax_jobs_per_timespanhas been introduced. Verify that these changes maintain backward compatibility and that the logic in__post_init__is consistent with existing functionality.Verification successful
Backward Compatibility and Consistency Verified
The changes to make
max_jobs_per_secondoptional and introducemax_jobs_per_timespanmaintain backward compatibility and are consistent with existing functionality. The logic in__post_init__ensures proper initialization whenmax_jobs_per_secondis set.
- Usage in
snakemake/scheduler.pyandsnakemake/cli.pyshows that the code handles the optional nature ofmax_jobs_per_secondappropriately.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify backward compatibility and consistency of changes in `SchedulingSettings`. # Test: Check for usage of `max_jobs_per_second` and ensure it is handled correctly with the new optional type. rg --type python -A 5 $'max_jobs_per_second'Length of output: 74
Script:
#!/bin/bash # Description: Verify backward compatibility and consistency of changes in `SchedulingSettings`. # Test: Check for usage of `max_jobs_per_second` and ensure it is handled correctly with the new optional type. rg --type py -A 5 'max_jobs_per_second'Length of output: 1789
snakemake/scheduler.py (1)
72-77: Verify initialization logic for job rate limiter.Ensure that the
job_rate_limiteris correctly initialized based on the scheduling settings, and verify that this logic does not introduce any unintended side effects.Verification successful
Job Rate Limiter Initialization and Usage Verified
The
job_rate_limiteris correctly initialized and integrated within the scheduler logic. It checks the scheduling settings and is only instantiated if the conditions are met. The limiter is used to manage job execution, ensuring the number of jobs does not exceed the specified limits. This logic appears to be implemented correctly without introducing unintended side effects.
- Initialization: The
job_rate_limiteris initialized based onmax_jobs_per_timespananddryrunconditions.- Usage: It regulates job execution by checking available slots and logging when limits are reached.
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the initialization logic for `job_rate_limiter`. # Test: Check if `job_rate_limiter` is correctly initialized and used in the scheduler. rg --type python -A 5 $'job_rate_limiter'Length of output: 71
Script:
#!/bin/bash # Description: Verify the initialization logic for `job_rate_limiter`. # Test: Check if `job_rate_limiter` is correctly initialized and used in the scheduler. rg --type py -A 5 $'job_rate_limiter'Length of output: 1638
snakemake/jobs.py (1)
108-123: Refactor improves clarity and adds_job_count.The refactoring of
_get_scheduler_resourcesenhances readability by separating the creation ofres_dictfrom the assignment of_scheduler_resources. The addition of"_job_count": 1seems intended for tracking job counts, which could be useful for resource management. Ensure this addition aligns with the overall design and resource management strategy.snakemake/cli.py (6)
874-874: LGTM! Internal argument grouping is clear.The
--scheduler-solver-pathargument has been moved to the internal group with a clear help description indicating its internal use.
1460-1463: LGTM! Internal argument grouping is clear.The
--local-groupidargument has been moved to the internal group with a clear help description indicating its internal use.
1464-1469: LGTM! Internal argument grouping is clear.The
--attemptargument has been moved to the internal group with a clear help description indicating its internal use.
1696-1699: LGTM! Internal argument grouping is clear.The
--scheduler-solver-pathargument has been added to the internal group with a clear help description indicating its internal use.
1700-1708: LGTM! Internal argument grouping is clear.The
--deploy-sourcesargument has been added to the internal group with a clear help description indicating its internal use.
1339-1347: Verify the implementation of--max-jobs-per-timespan.The new argument
--max-jobs-per-timespanis introduced with a clear format specification. The--max-jobs-per-secondis marked as deprecated. Ensure that all references to--max-jobs-per-secondare updated in the codebase.Verification successful
Deprecation of
--max-jobs-per-secondis correctly implemented.The
--max-jobs-per-secondargument is correctly marked as deprecated insnakemake/cli.py, and its mention inCHANGELOG.mdis appropriate for documentation purposes. No further updates are needed.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that all references to `--max-jobs-per-second` are updated or removed. # Test: Search for `--max-jobs-per-second` usage. Expect: Only occurrences in deprecated context. rg --type python -- '--max-jobs-per-second'Length of output: 74
Script:
#!/bin/bash # Description: Verify that all references to `--max-jobs-per-second` are updated or removed. # Test: Search for `--max-jobs-per-second` usage. Expect: Only occurrences in deprecated context. rg '--max-jobs-per-second'Length of output: 487
Script:
#!/bin/bash # Description: Verify that all references to `--max-jobs-per-second` are updated or removed. # Test: Search for `--max-jobs-per-second` usage. Expect: Only occurrences in deprecated context. rg -e '--max-jobs-per-second'Length of output: 161
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
…e into fix/job-rate-limiting
…e into fix/job-rate-limiting
There was a problem hiding this comment.
Actionable comments posted: 3
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (6)
- snakemake/cli.py (8 hunks)
- snakemake/scheduler.py (11 hunks)
- tests/common.py (1 hunks)
- tests/conftest.py (1 hunks)
- tests/testapi.py (2 hunks)
- tests/tests.py (7 hunks)
Files skipped from review as they are similar to previous changes (1)
- tests/testapi.py
Additional context used
Ruff
tests/conftest.py
68-71: Use
contextlib.suppress(Exception)instead oftry-except-passReplace with
contextlib.suppress(Exception)(SIM105)
tests/tests.py
982-982: Ambiguous variable name:
l(E741)
1028-1028: Ambiguous variable name:
l(E741)
Additional comments not posted (9)
snakemake/scheduler.py (3)
809-821: Efficient use ofdequefor job tracking.The
JobRateLimiterclass efficiently usesdequefor managing job registration times. The methods are well-implemented and align with the class's purpose.
475-487: Effective integration of job rate limiting.The
job_selectormethod effectively integrates theJobRateLimiterto control job submissions. This enhances the scheduling logic without disrupting existing functionality.
72-77: LGTM! Verifyjob_rate_limiterinitialization.The integration of
JobRateLimiterinto theJobSchedulerclass is well-executed. Ensure that thejob_rate_limiteris correctly initialized and used throughout the codebase.Verification successful
job_rate_limiteris correctly initialized and used.The
job_rate_limiteris properly initialized and utilized within thesnakemake/scheduler.pyfile. Its integration into theJobSchedulerclass is effective, and relevant methods are being called. Additionally, there is a test functiontest_job_rate_limiterindicating that its functionality is being tested.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the initialization and usage of `job_rate_limiter`. # Test: Search for `job_rate_limiter` initialization and usage. rg --type py 'job_rate_limiter'Length of output: 368
tests/tests.py (1)
1683-1685: Ensurerunanddpathare defined.The test function
test_max_jobs_per_timespanusesrunanddpath, which may be undefined due to star imports. Ensure these are correctly imported or defined to avoid runtime errors.snakemake/cli.py (5)
58-58: VerifyMaxJobsPerTimespanusage.Ensure that the
MaxJobsPerTimespantype is correctly implemented and used in the argument parser.Verification successful
MaxJobsPerTimespanis correctly used in the codebase.The
MaxJobsPerTimespantype is properly imported and utilized in the argument parser insnakemake/cli.py, consistent with its definition and usage elsewhere in the codebase. No issues were found.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check where `MaxJobsPerTimespan` is used in the codebase. # Test: Search for the usage of `MaxJobsPerTimespan` in the codebase. ast-grep --lang python --pattern $'MaxJobsPerTimespan'Length of output: 939
1695-1727: Relocation of internal arguments togroup_internal.The relocation of internal arguments is consistent, and the help text clearly indicates they are for internal use only.
Ensure that the internal use notice is clear and consistent across all relocated arguments.
Verification successful
All internal arguments have a clear internal use notice.
The help text for each internal argument in
group_internalclearly indicates that they are for internal use only. This is consistent across all relocated arguments.
- The help text for
--scheduler-solver-path,--deploy-sources,--target-jobs, and--modeall include the phrase "Internal use only."Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that all internal arguments have a clear internal use notice. # Test: Search for the help text of internal arguments to ensure they mention internal use. rg --type python --context 5 'help=help_internal'Length of output: 80
Script:
#!/bin/bash # Description: Verify that all internal arguments have a clear internal use notice. # Test: Search for the help text of internal arguments to ensure they mention internal use. rg --type py --context 5 'help=help_internal'Length of output: 1920
1695-1696: Function definition forhelp_internal.The
help_internalfunction is correctly implemented to format help text for internal arguments.Verify that
help_internalis used consistently for all internal arguments.Verification successful
Usage of
help_internalis consistent for internal arguments.The
help_internalfunction is used consistently for internal arguments throughout thesnakemake/cli.pyfile. This confirms that the function is being utilized as intended for formatting help text for internal options.
- File:
snakemake/cli.py
- Lines: Multiple occurrences where
help_internalis used to provide help text for internal arguments.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check the usage of `help_internal` function for internal arguments. # Test: Search for the usage of `help_internal` in the argument definitions. rg --type python --fixed-strings 'help=help_internal'Length of output: 84
Script:
#!/bin/bash # Description: Check the usage of `help_internal` function for internal arguments. # Test: Search for the usage of `help_internal` in the argument definitions using the correct file type for Python. rg --type py --fixed-strings 'help=help_internal'Length of output: 322
1340-1342: Ensure correct implementation of--max-jobs-per-timespan.Verify that the
MaxJobsPerTimespan.parse_choicemethod correctly handles the expected input format and that the help text is clear and informative.
1346-1348: Deprecation notice for--max-jobs-per-second.The deprecation notice clearly informs users to use
--max-jobs-per-timespaninstead.Verify that all references to
--max-jobs-per-secondare updated or deprecated in the codebase.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
|
There was a problem hiding this comment.
Actionable comments posted: 0
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (4)
- snakemake/scheduler.py (11 hunks)
- snakemake/settings/types.py (3 hunks)
- tests/conftest.py (2 hunks)
- tests/tests.py (7 hunks)
Files skipped from review as they are similar to previous changes (3)
- snakemake/settings/types.py
- tests/conftest.py
- tests/tests.py
Additional comments not posted (7)
snakemake/scheduler.py (7)
72-77: Verifyjob_rate_limiterinitialization logic.Ensure that
max_jobs_per_timespanis correctly configured in the workflow settings to avoid potential issues with job rate limiting.Verification successful
max_jobs_per_timespanis properly configured and integrated.The
max_jobs_per_timespansetting is defined and utilized across the codebase, including the scheduler and CLI components. Additionally, its behavior is tested, indicating proper configuration and integration.
snakemake/scheduler.py: Utilizesmax_jobs_per_timespanfor job rate limiting.snakemake/cli.py: Configuresmax_jobs_per_timespanfrom command-line arguments.snakemake/settings/types.py: Defines and managesmax_jobs_per_timespan.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that `max_jobs_per_timespan` is configured in the workflow settings. # Test: Search for `max_jobs_per_timespan` usage in the codebase. Expect: Proper configuration and usage. rg --type python $'max_jobs_per_timespan'Length of output: 71
Script:
#!/bin/bash # Description: Verify that `max_jobs_per_timespan` is configured in the workflow settings. # Test: Search for `max_jobs_per_timespan` usage in the codebase. Expect: Proper configuration and usage. rg --type py $'max_jobs_per_timespan'Length of output: 707
475-487: Verify integration of job rate limiter injob_selector.Ensure that the job rate limiter correctly interacts with the job selection logic and that the number of free jobs is accurately calculated.
Verification successful
Integration of job rate limiter in
job_selectoris consistent.The
job_selectormethod correctly integrates with the job rate limiter, using it to control job submissions based on available slots. The method is part of a strategy pattern that allows different job selection algorithms to be used.
snakemake/scheduler.py: Thejob_selectormethod interacts with_job_selectorand the job rate limiter.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the interaction of job rate limiter with job selection logic. # Test: Search for `job_selector` usage in the codebase. Expect: Proper interaction with job rate limiter. rg --type python $'job_selector'Length of output: 62
Script:
#!/bin/bash # Description: Verify the interaction of job rate limiter with job selection logic. # Test: Search for `job_selector` usage in the codebase. Expect: Proper interaction with job rate limiter. rg --type py 'job_selector'Length of output: 874
814-817: Verify job registration logic inregister_jobs.Ensure that the current time is correctly recorded for the specified number of jobs to maintain accurate job tracking.
Verification successful
Job registration logic in
register_jobsis correctly implemented and tested.The
register_jobsmethod is used in the codebase and has corresponding tests intests/testapi.py, indicating proper functionality verification.
snakemake/scheduler.py: Method usage for job registration.tests/testapi.py: Multiple test cases forregister_jobs.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the job registration logic in `register_jobs`. # Test: Search for `register_jobs` usage in the codebase. Expect: Correct job tracking. rg --type python $'register_jobs'Length of output: 63
Script:
#!/bin/bash # Description: Verify the job registration logic in `register_jobs`. # Test: Search for `register_jobs` usage in the codebase with the correct file type. Expect: Correct job tracking. rg --type py 'register_jobs'Length of output: 332
810-813: Verify initialization logic and data structure choice inJobRateLimiter.Ensure that the
dequeis the appropriate data structure for tracking job registration times, considering potential performance implications with a large number of jobs.Verification successful
Initialization logic and data structure choice in
JobRateLimiterare appropriate.The
dequeis efficiently used for managing job registration times, supporting the intended rate-limiting functionality. The initialization logic aligns with the expected usage patterns in both the scheduler and tests.
- File:
snakemake/scheduler.py- Tests:
tests/testapi.pyScripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the initialization logic and data structure choice in `JobRateLimiter`. # Test: Search for `JobRateLimiter` usage in the codebase. Expect: Appropriate data structure choice. rg --type python $'JobRateLimiter'Length of output: 64
Script:
#!/bin/bash # Description: Correctly search for `JobRateLimiter` usage in Python files. # Test: Search for `JobRateLimiter` usage in the codebase without specifying an incorrect file type. rg 'JobRateLimiter' --glob '*.py' -A 3Length of output: 1547
742-748: Verify resource update logic inupdate_available_resources.Ensure that resources are correctly decremented for each selected job to maintain accurate resource tracking.
Verification successful
Resource update logic in
update_available_resourcesis consistent.The method correctly decrements resources for jobs that are fully scheduled or selected, ensuring accurate resource tracking.
selected_jobsandsolutionare both derived from conditions that ensure only fully scheduled jobs are considered.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the resource update logic in `update_available_resources`. # Test: Search for `update_available_resources` usage in the codebase. Expect: Correct resource tracking. rg --type python $'update_available_resources'Length of output: 76
Script:
#!/bin/bash # Description: Verify the resource update logic in `update_available_resources`. # Test: Search for `update_available_resources` usage in the codebase. Expect: Correct resource tracking. rg 'update_available_resources'Length of output: 266
Script:
#!/bin/bash # Description: Find definitions and modifications of `selected_jobs` and `solution` in `snakemake/scheduler.py`. # Search for `selected_jobs` in `snakemake/scheduler.py` rg 'selected_jobs' snakemake/scheduler.py -A 5 -B 5 # Search for `solution` in `snakemake/scheduler.py` rg 'solution' snakemake/scheduler.py -A 5 -B 5Length of output: 2685
641-641: Verify call toupdate_available_resourcesinjob_selector_ilp.Ensure that the resources are correctly updated after job selection to prevent resource contention issues.
Verification successful
Verified: Call to
update_available_resourcesinjob_selector_ilpfunctions correctly.The method
update_available_resourcescorrectly updates the available resources by deducting the resources used byselected_jobs, ensuring proper resource management. No issues found with the implementation.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the call to `update_available_resources` in `job_selector_ilp`. # Test: Search for `job_selector_ilp` usage in the codebase. Expect: Correct updating of resources. rg --type python $'job_selector_ilp'Length of output: 66
Script:
#!/bin/bash # Description: Verify the call to `update_available_resources` in `job_selector_ilp`. # Test: Search for `job_selector_ilp` usage in the codebase. Expect: Correct updating of resources. rg --type py $'job_selector_ilp'Length of output: 174
Script:
#!/bin/bash # Description: Verify the implementation of `update_available_resources`. # Test: Search for the definition and usage of `update_available_resources` in the codebase. rg --type py $'def update_available_resources'Length of output: 127
Script:
#!/bin/bash # Description: Retrieve the implementation of `update_available_resources`. # Extract the implementation of `update_available_resources` from `snakemake/scheduler.py`. ast-grep --lang python --pattern $'def update_available_resources(self, selected_jobs):\n $$$' snakemake/scheduler.pyLength of output: 666
818-824: Verify calculation logic inget_free_jobs.Ensure that the calculation of free job slots accurately reflects the current job rate limit to prevent over-submission.
Verification successful
Calculation logic in
get_free_jobsis verified through tests.The test cases in
tests/testapi.pyconfirm that theget_free_jobsmethod correctly calculates the number of free job slots, ensuring that the job rate limit is respected. The assertions cover various scenarios, including job registration and time-based slot availability.
tests/testapi.py: Assertions verify expected behavior ofget_free_jobs.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the calculation logic in `get_free_jobs`. # Test: Search for `get_free_jobs` usage in the codebase. Expect: Accurate calculation of free job slots. rg --type python $'get_free_jobs'Length of output: 63
Script:
#!/bin/bash # Corrected: Verify the calculation logic in `get_free_jobs`. # Test: Search for `get_free_jobs` usage in the codebase. Expect: Accurate calculation of free job slots. rg --type py get_free_jobsLength of output: 411
Script:
#!/bin/bash # Extract test cases related to `get_free_jobs` from `tests/testapi.py`. # Search for the context around `get_free_jobs` assertions in the test file. rg --type py -A 5 'get_free_jobs' tests/testapi.pyLength of output: 395
🤖 I have created a release *beep* *boop* --- ## [8.17.0](v8.16.0...v8.17.0) (2024-08-13) ### Features * fix job rate limiting with --max-jobs-per-second and introduce the more flexible --max-jobs-per-timespan ([#3010](#3010)) ([9c31257](9c31257)) ### Bug Fixes * Allow hyphens in config keys given on the command line. ([#2998](#2998)) ([b70c0db](b70c0db)) * allowing trailing '+' in name patterns ([#3002](#3002)) ([59150d3](59150d3)) * print message if not yet enough resources for executing further jobs ([b8df036](b8df036)) * unawaited coroutine sanitize_local_storage_copies ([#2972](#2972)) ([715c572](715c572)) ### Documentation * Change sha256 checksum in docs to more realistic example ([#2987](#2987)) ([16a5cf2](16a5cf2)) * Make it more clear that the cluster commands now require a plugin ([#2976](#2976)) ([74134cf](74134cf)) * Update installation.rst to recommend Miniforge instead of Mambaforge ([#2975](#2975)) ([0fc7619](0fc7619)) * use plain monospace font instead of theme default that changes >= into ≥ ([cc17fc1](cc17fc1)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>



QC
docs/) is updated to reflect the changes or this is not necessary (e.g. if the change does neither modify the language nor the behavior or functionalities of Snakemake).Summary by CodeRabbit
New Features
--max-jobs-per-timespan.JobRateLimiterto improve job submission control within defined limits.Bug Fixes
--max-jobs-per-secondargument and improved clarity in help descriptions.Tests
JobRateLimiterfunctionality.max_jobs_per_timespancommand behavior.