Skip to content

Commit 8f85dcd

Browse files
committed
refactor: changed to only signalling, no distinction between scopes
1 parent de4611a commit 8f85dcd

File tree

1 file changed

+19
-19
lines changed

1 file changed

+19
-19
lines changed

snakemake_executor_plugin_slurm/utils.py

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -336,23 +336,23 @@ def delete_empty_dirs(path: Path) -> None:
336336
# Provide more context in the error message
337337
raise OSError(f"Failed to remove empty directory {path}: {e}") from e
338338

339-
339+
# only run this parser once per unique input string
340+
# chache the results for efficiency.
340341
@lru_cache(maxsize=None)
341342
def parse_slurm_signal_settings(signal_settings: Optional[str]) -> dict[str, str]:
342343
"""
343-
Parse rule-specific SLURM signal settings (format: rule[:SCOPE]:SIGNAL@TIME).
344+
Parse rule-specific SLURM signal settings (format: rule:SIGNAL@TIME).
344345
345346
- rule: rule name or 'all' for all rules
346-
- SCOPE: B (batch script, default) or R (reservation)
347347
- SIGNAL: signal name (SIGTERM, SIGUSR1) or number (15, 10)
348348
- TIME: seconds before wall time (must be >= 1)
349349
350350
Examples:
351-
- rule1:SIGTERM@30 → batch script, SIGTERM at 30 secs
352-
- rule2:R:SIGUSR1@60 → reservation, SIGUSR1 at 60 secs
351+
- rule1:SIGTERM@30 → SIGTERM at 30 secs
352+
- rule2:SIGUSR1@60 → SIGUSR1 at 60 secs
353353
- all:15@45 → all rules, signal 15 at 45 secs
354354
355-
Returns dict mapping rule names to SLURM signal specs: [B:|R:]<sig_num>@<time>
355+
Returns dict mapping rule names to SLURM signal specs: <signal>@<time>
356356
"""
357357
if not signal_settings:
358358
return {}
@@ -392,25 +392,25 @@ def parse_slurm_signal_settings(signal_settings: Optional[str]) -> dict[str, str
392392
"SIGSYS": 31,
393393
}
394394

395-
# Pattern: rule[:SCOPE]:SIGNAL@TIME where SCOPE is optional (B|R)
395+
# Pattern: rule:SIGNAL@TIME
396396
pattern = re.compile(
397-
r"^(?P<rule>\w+)(?::(?P<scope>[BR]))?:(?P<signal>\w+)@(?P<seconds>\d+)$"
397+
r"^(?P<rule>\w+):(?P<signal>\w+)@(?P<seconds>\d+)$"
398398
)
399399

400400
for raw_entry in signal_settings.split(","):
401401
entry = raw_entry.strip()
402402
if not entry:
403403
raise WorkflowError(
404404
"Invalid signal specification: empty entry found. "
405-
"Expected 'rule[:SCOPE]:SIGNAL@TIME' (e.g., 'rule1:SIGTERM@30')."
405+
"Expected 'rule:SIGNAL@TIME' (e.g., 'rule1:SIGTERM@30')."
406406
)
407407

408408
match = pattern.fullmatch(entry)
409409
if match is None:
410410
raise WorkflowError(
411411
f"Invalid signal specification '{entry}'. "
412-
"Expected 'rule[:SCOPE]:SIGNAL@TIME' (e.g., 'rule1:SIGTERM@30', "
413-
"'rule2:R:15@60', 'all:SIGUSR1@45')."
412+
"Expected 'rule:SIGNAL@TIME' (e.g., 'rule1:SIGTERM@30', "
413+
"'rule2:15@60', 'all:SIGUSR1@45')."
414414
)
415415

416416
rule_name = match.group("rule")
@@ -420,7 +420,7 @@ def parse_slurm_signal_settings(signal_settings: Optional[str]) -> dict[str, str
420420
)
421421

422422
signal_str = match.group("signal")
423-
# Convert signal name to number if needed
423+
# Validate signal name or number.
424424
if signal_str.isdigit():
425425
signal_num = int(signal_str)
426426
if signal_num < 1 or signal_num > 31:
@@ -439,8 +439,7 @@ def parse_slurm_signal_settings(signal_settings: Optional[str]) -> dict[str, str
439439
if seconds < 1:
440440
raise WorkflowError("Signal lead time must be at least 1 second.")
441441

442-
scope = match.group("scope") or "B" # Default to batch script
443-
parsed_settings[rule_name] = f"{scope}:{signal_num}@{seconds}"
442+
parsed_settings[rule_name] = f"{signal_str}@{seconds}"
444443

445444
return parsed_settings
446445

@@ -451,14 +450,15 @@ def get_slurm_signal_arg(signal_settings: Optional[str], rule_name: str) -> str:
451450
Checks for rule-specific signal first, then falls back to 'all' if set.
452451
"""
453452
# we need to check the signal settings, first.
454-
signal_settings_pattern = (
455-
r"^\s*(\w+)(?::[BR])?:\w+@\d+\s*" r"(,\s*\w+(?::[BR])?:\w+@\d+\s*)*$"
456-
)
453+
if not signal_settings:
454+
return ""
455+
456+
signal_settings_pattern = r"^\s*\w+:\w+@\d+\s*(,\s*\w+:\w+@\d+\s*)*$"
457457
if not re.match(signal_settings_pattern, signal_settings):
458458
raise WorkflowError(
459459
f"Invalid signal specification: '{signal_settings}'. "
460-
"Expected format: 'rule[:SCOPE]:SIGNAL@TIME' "
461-
"(e.g., 'rule1:SIGTERM@30', 'rule2:R:15@60', "
460+
"Expected format: 'rule:SIGNAL@TIME' "
461+
"(e.g., 'rule1:SIGTERM@30', 'rule2:15@60', "
462462
"'all:SIGUSR1@45')."
463463
)
464464

0 commit comments

Comments
 (0)