Skip to content

Commit

Permalink
Merge branch 'mainline' into justinsaws/add_latency_telemetry
Browse files Browse the repository at this point in the history
  • Loading branch information
justinsaws authored Jan 28, 2025
2 parents 4b24596 + e101473 commit 7c055d1
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 3 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ classifiers = [
# Applications that consume this library should be the ones that are more strictly
# limiting dependencies if they want/need to.
dependencies = [
"boto3 >= 1.34.75",
"boto3 >= 1.36.8",
"click >= 8.1.7",
"pyyaml >= 6.0",
# Job Attachments
Expand Down
4 changes: 4 additions & 0 deletions src/deadline/client/api/_submit_job_bundle.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def create_job_from_job_bundle(
priority: Optional[int] = None,
max_failed_tasks_count: Optional[int] = None,
max_retries_per_task: Optional[int] = None,
max_worker_count: Optional[int] = None,
print_function_callback: Callable[[str], None] = lambda msg: None,
decide_cancel_submission_callback: Callable[
[AssetUploadGroup], bool
Expand Down Expand Up @@ -122,6 +123,7 @@ def create_job_from_job_bundle(
config (ConfigParser, optional): The AWS Deadline Cloud configuration
object to use instead of the config file.
priority (int, optional): explicit value for the priority of the job.
max_worker_count (int, optional): explicit value for the max worker count of the job.
max_failed_tasks_count (int, optional): explicit value for the maximum allowed failed tasks.
max_retries_per_task (int, optional): explicit value for the maximum retries per task.
print_function_callback (Callable str -> None, optional): Callback to print messages produced in this function.
Expand Down Expand Up @@ -309,6 +311,8 @@ def create_job_from_job_bundle(

if priority is not None:
create_job_args["priority"] = priority
if max_worker_count is not None:
create_job_args["maxWorkerCount"] = max_worker_count
if max_failed_tasks_count is not None:
create_job_args["maxFailedTasksCount"] = max_failed_tasks_count
if max_retries_per_task is not None:
Expand Down
7 changes: 7 additions & 0 deletions src/deadline/client/cli/_groups/bundle_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ def validate_parameters(ctx, param, value):
type=int,
help="The maximum number of times to retry a task before it is marked as failed.",
)
@click.option(
"--max-worker-count",
type=int,
help="The max worker count of the job.",
)
@click.option(
"--job-attachments-file-system",
help="The method workers use to access job attachments. "
Expand Down Expand Up @@ -132,6 +137,7 @@ def bundle_submit(
priority,
max_failed_tasks_count,
max_retries_per_task,
max_worker_count,
require_paths_exist,
submitter_name,
**args,
Expand Down Expand Up @@ -208,6 +214,7 @@ def _decide_cancel_submission(upload_group: AssetUploadGroup) -> bool:
priority=priority,
max_failed_tasks_count=max_failed_tasks_count,
max_retries_per_task=max_retries_per_task,
max_worker_count=max_worker_count,
hashing_progress_callback=hash_callback_manager.callback,
upload_progress_callback=upload_callback_manager.callback,
create_job_result_callback=_check_create_job_wait_canceled,
Expand Down
1 change: 1 addition & 0 deletions src/deadline/client/job_bundle/submission.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"priority",
"maxFailedTasksCount",
"maxRetriesPerTask",
"maxWorkerCount",
]


Expand Down
46 changes: 45 additions & 1 deletion src/deadline/client/ui/widgets/shared_job_settings_tab.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
QHBoxLayout,
QLabel,
QLineEdit,
QRadioButton,
QSpinBox,
QVBoxLayout,
QWidget,
Expand Down Expand Up @@ -291,13 +292,37 @@ def _build_ui(self):
self.max_retries_per_task_box.setRange(0, 2147483647)
self.layout.addRow(self.max_retries_per_task_box_label, self.max_retries_per_task_box)

self.max_worker_count_box_label = QLabel("Maximum worker count")
self.max_worker_count_box_label.setToolTip("Maximum worker count of job.")
self.max_worker_count_box = QSpinBox()
self.max_worker_count_box.setRange(1, 2147483647)
self.unlimited_max_worker_count = QRadioButton("No max worker count")
self.limited_max_worker_count = QRadioButton("Set max worker count")
self.limited_max_worker_count.toggled.connect(
self.limited_max_worker_count_radio_button_toggled
)
self.max_worker_count_layout = QVBoxLayout(self)
self.max_worker_count_layout.addWidget(self.unlimited_max_worker_count)
self.max_worker_count_layout.addWidget(self.limited_max_worker_count)
self.max_worker_count_layout.addWidget(self.max_worker_count_box)
self.layout.addRow(self.max_worker_count_box_label, self.max_worker_count_layout)

def limited_max_worker_count_radio_button_toggled(self, state):
"""
Enable the max worker count text box when limited max worker count radio button is enabled.
"""
self.max_worker_count_box.setHidden(not state)

def refresh_ui(self, settings: Any):
self.sub_name_edit.setText(settings.name)
self.desc_edit.setText(settings.description)
self.initial_status_box.setCurrentText("READY")
self.max_failed_tasks_count_box.setValue(20)
self.max_retries_per_task_box.setValue(5)
self.priority_box.setValue(50)
self.unlimited_max_worker_count.setChecked(True)
self.limited_max_worker_count.setChecked(False)
self.max_worker_count_box.setHidden(True)

def set_parameter_value(self, parameter: dict[str, Any]):
"""
Expand All @@ -315,6 +340,16 @@ def set_parameter_value(self, parameter: dict[str, Any]):
self.max_retries_per_task_box.setValue(parameter["value"])
elif parameter_name == "deadline:priority":
self.priority_box.setValue(parameter["value"])
elif parameter_name == "deadline:maxWorkerCount":
if parameter["value"] == -1:
self.unlimited_max_worker_count.setChecked(True)
self.limited_max_worker_count.setChecked(False)
self.max_worker_count_box.setHidden(True)
else:
self.unlimited_max_worker_count.setChecked(False)
self.limited_max_worker_count.setChecked(True)
self.max_worker_count_box.setHidden(False)
self.max_worker_count_box.setValue(parameter["value"])
else:
raise KeyError(parameter_name)

Expand All @@ -323,7 +358,7 @@ def get_parameters(self):
Returns a list of OpenJD parameter definition dicts with
a "value" key filled from the widget.
"""
return [
job_parameters = [
{
"name": "deadline:targetTaskRunStatus",
"type": "STRING",
Expand Down Expand Up @@ -358,6 +393,15 @@ def get_parameters(self):
},
{"name": "deadline:priority", "type": "INT", "value": self.priority_box.value()},
]
if not self.unlimited_max_worker_count.isChecked():
job_parameters.append(
{
"name": "deadline:maxWorkerCount",
"type": "INT",
"value": self.max_worker_count_box.value(),
}
)
return job_parameters

def update_settings(self, settings):
"""
Expand Down
8 changes: 8 additions & 0 deletions test/unit/deadline_client/api/test_job_bundle_submission.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,10 @@ def get_minimal_json_job_template(job_name):
{
"name": "deadline:maxRetriesPerTask",
"value": 5
},
{
"name": "deadline:maxWorkerCount",
"value": 10
}
]
}
Expand All @@ -213,6 +217,7 @@ def get_minimal_json_job_template(job_name):
"targetTaskRunStatus": "SUSPENDED",
"maxFailedTasksCount": 20,
"maxRetriesPerTask": 5,
"maxWorkerCount": 10,
},
),
"DEADLINE_ONLY_YAML": (
Expand All @@ -227,12 +232,15 @@ def get_minimal_json_job_template(job_name):
value: 250
- name: "deadline:maxRetriesPerTask"
value: 15
- name: "deadline:maxWorkerCount"
value: 10
""",
{
"priority": 45,
"targetTaskRunStatus": "SUSPENDED",
"maxFailedTasksCount": 250,
"maxRetriesPerTask": 15,
"maxWorkerCount": 10,
},
),
# A parameter_values.json/yaml file with just job template values
Expand Down
5 changes: 4 additions & 1 deletion test/unit/deadline_client/cli/test_cli_bundle.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ def test_cli_bundle_explicit_parameters(fresh_deadline_config):

def test_cli_bundle_priority_retries(fresh_deadline_config):
"""
Confirm that --priority, --max-failed-tasks-count, and --max-retries-per-task get passed in from the CLI.
Confirm that --priority, --max-failed-tasks-count, --max_worker_count and --max-retries-per-task get passed in from the CLI.
"""
# Use a temporary directory for the job bundle
with tempfile.TemporaryDirectory() as tmpdir, patch.object(boto3, "Session") as session_mock:
Expand Down Expand Up @@ -230,6 +230,8 @@ def test_cli_bundle_priority_retries(fresh_deadline_config):
"12",
"--max-retries-per-task",
"4",
"--max-worker-count",
"123",
],
)

Expand All @@ -244,6 +246,7 @@ def test_cli_bundle_priority_retries(fresh_deadline_config):
priority=25,
maxFailedTasksCount=12,
maxRetriesPerTask=4,
maxWorkerCount=123,
)
assert result.exit_code == 0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,10 @@ def test_max_retries_per_task_should_be_integer_within_range(
):
shared_job_settings_tab.shared_job_properties_box.max_retries_per_task_box.setValue(-1)
assert shared_job_settings_tab.shared_job_properties_box.max_retries_per_task_box.value() == 0


def test_max_worker_count_should_be_integer_within_range(
shared_job_settings_tab: SharedJobSettingsWidget,
):
shared_job_settings_tab.shared_job_properties_box.max_worker_count_box.setValue(-1)
assert shared_job_settings_tab.shared_job_properties_box.max_worker_count_box.value() == 1

0 comments on commit 7c055d1

Please sign in to comment.