99"""REANA Workflow Controller workflows REST API."""
1010
1111import difflib
12- import fs
12+ import gc
1313import json
1414import logging
1515import mimetypes
6363 PROGRESS_STATUSES ,
6464 REANA_GITLAB_HOST ,
6565 PREVIEWABLE_MIME_TYPE_PREFIXES ,
66+ FORCE_GARBAGE_COLLECTION ,
67+ WORKSPACE_DISPLAY_FILE_LIMIT ,
6668)
6769from reana_workflow_controller .consumer import _update_workflow_status
6870from reana_workflow_controller .errors import (
7375)
7476from reana_workflow_controller .workflow_run_manager import KubernetesWorkflowRunManager
7577
78+ WORKSPACE_FILE_LISTING_FILTER_HINT = (
79+ "Please use more specific filters to narrow the results. "
80+ "Available filters: file name, size, or last-modified."
81+ )
82+ """Neutral filter hint shown when workspace listings exceed the display limit."""
83+
7684
7785def start_workflow (workflow , parameters ):
7886 """Start a workflow."""
@@ -222,6 +230,9 @@ def remove_workflow_jobs_from_cache(workflow):
222230
223231def delete_workflow (workflow , all_runs = False , workspace = False ):
224232 """Delete workflow."""
233+ if "delete" in FORCE_GARBAGE_COLLECTION :
234+ gc .collect ()
235+
225236 if workflow .status in [
226237 RunStatus .created ,
227238 RunStatus .finished ,
@@ -434,8 +445,16 @@ def list_directory_files(
434445 workspace_path : str , search : Dict [str , List [str ]] = None
435446) -> List [dict ]:
436447 """Return a list of files inside a given workspace."""
448+ if "ls" in FORCE_GARBAGE_COLLECTION :
449+ gc .collect ()
437450 file_list = []
438451 for file_name in workspace .walk (workspace_path , include_dirs = False ):
452+ if len (file_list ) >= WORKSPACE_DISPLAY_FILE_LIMIT :
453+ raise BadRequest (
454+ "Too many files to display "
455+ f"(limit={ WORKSPACE_DISPLAY_FILE_LIMIT } ). "
456+ f"{ WORKSPACE_FILE_LISTING_FILTER_HINT } "
457+ )
439458 st = workspace .lstat (workspace_path , file_name )
440459 file_info = {
441460 "name" : file_name ,
@@ -465,10 +484,12 @@ def remove_files_recursive_wildcard(workspace_path, path_or_pattern):
465484 :param workspace_path: Directory to delete files from.
466485 :param path_or_pattern: Wildcard pattern to use for the removal.
467486 :return: Dictionary with the results:
468- - dictionary with names of succesfully deleted files and their sizes
487+ - dictionary with names of successfully deleted files and their sizes
469488 - dictionary with names of failed deletions and corresponding
470489 error messages.
471490 """
491+ if "rm" in FORCE_GARBAGE_COLLECTION :
492+ gc .collect ()
472493 deleted = {"deleted" : {}, "failed" : {}}
473494 for file_name in workspace .glob_or_walk_directory (
474495 workspace_path , path_or_pattern , topdown = False
@@ -488,12 +509,20 @@ def list_files_recursive_wildcard(workspace_path, path_or_pattern, search=None):
488509 :param workspace_path: Directory to list files from.
489510 :param path_or_pattern: Wildcard pattern to use for the listing.
490511 :return: Dictionary with the results:
491- - dictionary with names of succesfully listed files and their sizes
512+ - dictionary with names of successfully listed files and their sizes
492513 - dictionary with names of failed listing and corresponding
493514 error messages.
494515 """
516+ if "ls" in FORCE_GARBAGE_COLLECTION :
517+ gc .collect ()
495518 list_files_recursive = []
496519 for path in workspace .glob_or_walk_directory (workspace_path , path_or_pattern ):
520+ if len (list_files_recursive ) >= WORKSPACE_DISPLAY_FILE_LIMIT :
521+ raise BadRequest (
522+ "Too many files to display "
523+ f"(limit={ WORKSPACE_DISPLAY_FILE_LIMIT } ). "
524+ f"{ WORKSPACE_FILE_LISTING_FILTER_HINT } "
525+ )
497526 st = workspace .lstat (workspace_path , path )
498527 raw_size = st .st_size
499528 mtime = st .st_mtime
0 commit comments