Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions src/toil/cwl/cwltoil.py
Original file line number Diff line number Diff line change
Expand Up @@ -2636,15 +2636,23 @@ def __init__(
# If not using the Toil file store, output files just go directly to
# their final homes their space doesn't need to be accounted per-job.

options_dict: dict = {} # type: ignore
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the # type: ignore here intentional? As far as I can tell dict = {} is valid Python and shouldn't produce a type error. Would dict[str, Any] be a more precise annotation, and would that remove the need for the ignore comment entirely?

run_local: bool = self.conditional.is_false(cwljob)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cwljob may still have unresolved Promise objects at init time if when references an output from an upstream step. Since Conditional.is_false resolves promises without a file store, could this either crash or return the wrong result in that case? The worst case I can think of is is_false incorrectly returning True here, setting local=True with no resources, but then the fully-resolved condition at run() time returning False, meaning real work runs on the leader with no reserved resources. Would wrapping this in a try/except that falls back to run_local = False be a safe way to handle that?

if not run_local:
options_dict["cores"] = req["cores"]
options_dict["memory"] = memory
options_dict["disk"] = int(total_disk)
options_dict["accelerators"] = accelerators
options_dict["preemptible"] = preemptible

super().__init__(
cores=req["cores"],
memory=memory,
disk=int(total_disk),
accelerators=accelerators,
preemptible=preemptible,
tool_id=self.cwltool.tool["id"],
parent_name=parent_name,
local=isinstance(tool, cwltool.command_line_tool.ExpressionTool),
local=(
isinstance(tool, cwltool.command_line_tool.ExpressionTool)
or run_local
),
**options_dict,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When run_local is True, options_dict is empty so cores, memory, disk, accelerators, and preemptible all fall back to Job defaults. CWLJobWrapper, which also runs locally, explicitly passes cores=1, memory="1GiB", disk="1MiB" for its local run. Would it be worth doing the same here for consistency, rather than relying on the defaults being equivalent?

)

self.cwljob = cwljob
Expand Down