parsl 2024.3.25__tar.gz → 2024.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {parsl-2024.3.25/parsl.egg-info → parsl-2024.4.1}/PKG-INFO +2 -2
- {parsl-2024.3.25 → parsl-2024.4.1}/README.rst +1 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/dataflow/dflow.py +25 -33
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/base.py +1 -1
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/high_throughput/executor.py +8 -20
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/high_throughput/process_worker_pool.py +5 -2
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/status_handling.py +6 -6
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/taskvine/executor.py +17 -13
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/workqueue/executor.py +17 -14
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/jobs/job_status_poller.py +8 -7
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/jobs/strategy.py +31 -18
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/monitoring.py +1 -20
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/site_tests/test_provider.py +1 -1
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_htex/test_disconnected_blocks.py +0 -1
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_htex/test_drain.py +1 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_monitoring/test_htex_init_blocks_vs_monitoring.py +9 -6
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_context_manager.py +3 -3
- parsl-2024.4.1/parsl/tests/test_scaling/test_shutdown_scalein.py +78 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/version.py +1 -1
- {parsl-2024.3.25 → parsl-2024.4.1/parsl.egg-info}/PKG-INFO +2 -2
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl.egg-info/SOURCES.txt +5 -5
- parsl-2024.3.25/parsl/usage_tracking/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/LICENSE +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/MANIFEST.in +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/addresses.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/app/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/app/app.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/app/bash.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/app/errors.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/app/futures.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/app/python.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/benchmark/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/benchmark/perf.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/channels/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/channels/base.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/channels/errors.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/channels/local/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/channels/local/local.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/channels/oauth_ssh/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/channels/oauth_ssh/oauth_ssh.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/channels/ssh/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/channels/ssh/ssh.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/channels/ssh_il/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/channels/ssh_il/ssh_il.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/concurrent/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/config.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/configs/ASPIRE1.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/configs/Azure.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/configs/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/configs/ad_hoc.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/configs/bridges.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/configs/cc_in2p3.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/configs/ec2.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/configs/expanse.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/configs/frontera.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/configs/htex_local.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/configs/illinoiscluster.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/configs/kubernetes.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/configs/local_threads.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/configs/midway.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/configs/osg.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/configs/polaris.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/configs/stampede2.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/configs/summit.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/configs/toss3_llnl.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/configs/vineex_local.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/configs/wqex_local.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/curvezmq.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/data_provider/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/data_provider/data_manager.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/data_provider/file_noop.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/data_provider/files.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/data_provider/ftp.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/data_provider/globus.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/data_provider/http.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/data_provider/rsync.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/data_provider/staging.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/dataflow/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/dataflow/errors.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/dataflow/futures.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/dataflow/memoization.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/dataflow/rundirs.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/dataflow/states.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/dataflow/taskrecord.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/errors.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/errors.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/flux/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/flux/execute_parsl_task.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/flux/executor.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/flux/flux_instance_manager.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/high_throughput/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/high_throughput/errors.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/high_throughput/interchange.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/high_throughput/manager_record.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/high_throughput/monitoring_info.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/high_throughput/mpi_prefix_composer.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/high_throughput/mpi_resource_management.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/high_throughput/probe.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/high_throughput/zmq_pipes.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/radical/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/radical/executor.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/radical/rpex_master.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/radical/rpex_resources.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/radical/rpex_worker.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/taskvine/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/taskvine/errors.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/taskvine/exec_parsl_function.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/taskvine/factory.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/taskvine/factory_config.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/taskvine/manager.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/taskvine/manager_config.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/taskvine/utils.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/threads.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/workqueue/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/workqueue/errors.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/workqueue/exec_parsl_function.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/workqueue/parsl_coprocess.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/executors/workqueue/parsl_coprocess_stub.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/jobs/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/jobs/error_handlers.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/jobs/errors.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/jobs/states.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/launchers/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/launchers/base.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/launchers/errors.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/launchers/launchers.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/log_utils.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/db_manager.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/message_type.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/queries/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/queries/pandas.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/radios.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/remote.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/router.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/types.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/visualization/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/visualization/app.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/visualization/models.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/visualization/plots/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/visualization/plots/default/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/visualization/plots/default/task_plots.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/visualization/plots/default/workflow_plots.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/visualization/plots/default/workflow_resource_plots.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/visualization/static/parsl-logo-white.png +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/visualization/static/parsl-monitor.css +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/visualization/templates/app.html +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/visualization/templates/dag.html +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/visualization/templates/error.html +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/visualization/templates/layout.html +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/visualization/templates/resource_usage.html +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/visualization/templates/task.html +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/visualization/templates/workflow.html +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/visualization/templates/workflows_summary.html +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/visualization/utils.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/visualization/version.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/monitoring/visualization/views.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/multiprocessing.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/process_loggers.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/ad_hoc/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/ad_hoc/ad_hoc.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/aws/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/aws/aws.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/aws/template.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/azure/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/azure/azure.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/azure/template.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/base.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/cluster_provider.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/cobalt/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/cobalt/cobalt.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/cobalt/template.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/condor/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/condor/condor.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/condor/template.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/errors.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/googlecloud/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/googlecloud/googlecloud.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/grid_engine/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/grid_engine/grid_engine.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/grid_engine/template.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/kubernetes/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/kubernetes/kube.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/kubernetes/template.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/local/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/local/local.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/lsf/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/lsf/lsf.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/lsf/template.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/pbspro/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/pbspro/pbspro.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/pbspro/template.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/slurm/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/slurm/slurm.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/slurm/template.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/torque/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/torque/template.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/providers/torque/torque.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/py.typed +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/serialize/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/serialize/base.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/serialize/concretes.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/serialize/errors.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/serialize/facade.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/serialize/proxystore.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/callables_helper.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/ad_hoc_cluster_htex.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/azure_single_node.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/bluewaters.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/bridges.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/cc_in2p3.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/comet.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/cooley_htex.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/ec2_single_node.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/ec2_spot.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/frontera.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/htex_ad_hoc_cluster.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/htex_local.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/htex_local_alternate.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/htex_local_intask_staging.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/htex_local_rsync_staging.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/local_adhoc.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/local_radical.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/local_radical_mpi.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/local_threads.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/local_threads_checkpoint.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/local_threads_checkpoint_dfk_exit.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/local_threads_checkpoint_periodic.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/local_threads_checkpoint_task_exit.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/local_threads_ftp_in_task.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/local_threads_globus.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/local_threads_http_in_task.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/local_threads_monitoring.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/local_threads_no_cache.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/midway.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/nscc_singapore.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/osg_htex.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/petrelkube.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/summit.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/swan_htex.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/taskvine_ex.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/theta.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/user_opts.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/configs/workqueue_ex.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/conftest.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/integration/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/integration/latency.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/integration/test_apps/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/integration/test_channels/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/integration/test_channels/test_channels.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/integration/test_channels/test_local_channel.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/integration/test_channels/test_scp_1.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/integration/test_channels/test_ssh_1.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/integration/test_channels/test_ssh_errors.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/integration/test_channels/test_ssh_file_transport.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/integration/test_channels/test_ssh_interactive.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/integration/test_parsl_load_default_config.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/integration/test_stress/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/integration/test_stress/test_python_simple.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/integration/test_stress/test_python_threads.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/manual_tests/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/manual_tests/htex_local.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/manual_tests/test_ad_hoc_htex.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/manual_tests/test_basic.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/manual_tests/test_fan_in_out_htex_remote.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/manual_tests/test_log_filter.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/manual_tests/test_memory_limits.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/manual_tests/test_oauth_ssh.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/manual_tests/test_regression_220.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/manual_tests/test_udp_simple.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/manual_tests/test_worker_count.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/scaling_tests/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/scaling_tests/htex_local.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/scaling_tests/local_threads.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/scaling_tests/test_scale.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/scaling_tests/vineex_condor.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/scaling_tests/vineex_local.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/scaling_tests/wqex_condor.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/scaling_tests/wqex_local.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/site_tests/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/site_tests/site_config_selector.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/site_tests/test_site.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/sites/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/sites/test_affinity.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/sites/test_concurrent.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/sites/test_dynamic_executor.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/sites/test_ec2.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/sites/test_launchers.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/sites/test_local_adhoc.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/sites/test_mpi/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/sites/test_worker_info.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_aalst_patterns.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_bash_apps/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_bash_apps/test_apptimeout.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_bash_apps/test_basic.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_bash_apps/test_error_codes.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_bash_apps/test_keyword_overlaps.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_bash_apps/test_kwarg_storage.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_bash_apps/test_memoize.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_bash_apps/test_memoize_ignore_args.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_bash_apps/test_memoize_ignore_args_regr.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_bash_apps/test_multiline.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_bash_apps/test_pipeline.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_bash_apps/test_stdout.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_callables.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_channels/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_channels/test_large_output.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_checkpointing/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_checkpointing/test_periodic.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_checkpointing/test_python_checkpoint_1.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_checkpointing/test_python_checkpoint_2.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_checkpointing/test_python_checkpoint_3.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_checkpointing/test_regression_232.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_checkpointing/test_regression_233.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_checkpointing/test_regression_239.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_checkpointing/test_task_exit.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_curvezmq.py +0 -0
- {parsl-2024.3.25/parsl/tests/test_data → parsl-2024.4.1/parsl/tests/test_docs}/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_docs/test_from_slides.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_docs/test_kwargs.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_docs/test_tutorial_1.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_docs/test_workflow1.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_docs/test_workflow2.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_docs/test_workflow4.py +0 -0
- {parsl-2024.3.25/parsl/tests/test_docs → parsl-2024.4.1/parsl/tests/test_error_handling}/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_error_handling/test_fail.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_error_handling/test_python_walltime.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_error_handling/test_rand_fail.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_error_handling/test_resource_spec.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_error_handling/test_retries.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_error_handling/test_retry_handler.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_error_handling/test_retry_handler_failure.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_error_handling/test_serialization_fail.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_error_handling/test_wrap_with_logs.py +0 -0
- {parsl-2024.3.25/parsl/tests/test_error_handling → parsl-2024.4.1/parsl/tests/test_flowcontrol}/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_flux.py +0 -0
- {parsl-2024.3.25/parsl/tests/test_flowcontrol → parsl-2024.4.1/parsl/tests/test_htex}/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_htex/test_basic.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_htex/test_connected_blocks.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_htex/test_cpu_affinity_explicit.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_htex/test_htex.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_htex/test_manager_failure.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_htex/test_missing_worker.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_htex/test_multiple_disconnected_blocks.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_htex/test_worker_failure.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_htex/test_zmq_binding.py +0 -0
- {parsl-2024.3.25/parsl/tests/test_htex → parsl-2024.4.1/parsl/tests/test_monitoring}/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_monitoring/test_app_names.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_monitoring/test_basic.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_monitoring/test_db_locks.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_monitoring/test_fuzz_zmq.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_monitoring/test_incomplete_futures.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_monitoring/test_memoization_representation.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_monitoring/test_viz_colouring.py +0 -0
- {parsl-2024.3.25/parsl/tests/test_monitoring → parsl-2024.4.1/parsl/tests/test_mpi_apps}/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_mpi_apps/test_bad_mpi_config.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_mpi_apps/test_mpi_mode_disabled.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_mpi_apps/test_mpi_mode_enabled.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_mpi_apps/test_mpi_prefix.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_mpi_apps/test_mpi_scheduler.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_mpi_apps/test_resource_spec.py +0 -0
- {parsl-2024.3.25/parsl/tests/test_mpi_apps → parsl-2024.4.1/parsl/tests/test_providers}/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_providers/test_cobalt_deprecation_warning.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_providers/test_local_provider.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_providers/test_pbspro_template.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_providers/test_slurm_instantiate.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_providers/test_slurm_template.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_providers/test_submiterror_deprecation.py +0 -0
- {parsl-2024.3.25/parsl/tests/test_providers → parsl-2024.4.1/parsl/tests/test_python_apps}/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_arg_input_types.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_basic.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_dep_standard_futures.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_dependencies.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_depfail_propagation.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_fail.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_fibonacci_iterative.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_fibonacci_recursive.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_futures.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_garbage_collect.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_import_fail.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_join.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_lifted.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_mapred.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_memoize_1.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_memoize_2.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_memoize_4.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_memoize_bad_id_for_memo.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_memoize_ignore_args.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_memoize_joinapp.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_outputs.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_overview.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_pipeline.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_simple.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_timeout.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_type5.py +0 -0
- {parsl-2024.3.25/parsl/tests/test_python_apps → parsl-2024.4.1/parsl/tests/test_radical}/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_radical/test_mpi_funcs.py +0 -0
- {parsl-2024.3.25/parsl/tests/test_radical → parsl-2024.4.1/parsl/tests/test_regression}/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_regression/test_1480.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_regression/test_1606_wait_for_current_tasks.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_regression/test_1653.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_regression/test_221.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_regression/test_226.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_regression/test_2652.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_regression/test_69a.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_regression/test_854.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_regression/test_97_parallelism_0.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_regression/test_98.py +0 -0
- {parsl-2024.3.25/parsl/tests/test_regression → parsl-2024.4.1/parsl/tests/test_scaling}/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_scaling/test_block_error_handler.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_scaling/test_regression_1621.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_scaling/test_scale_down.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_scaling/test_scale_down_htex_auto_scale.py +0 -0
- {parsl-2024.3.25/parsl/tests/test_scaling → parsl-2024.4.1/parsl/tests/test_serialization}/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_serialization/test_2555_caching_deserializer.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_serialization/test_basic.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_serialization/test_htex_code_cache.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_serialization/test_pack_resource_spec.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_serialization/test_proxystore_configured.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_serialization/test_proxystore_impl.py +0 -0
- {parsl-2024.3.25/parsl/tests/test_serialization → parsl-2024.4.1/parsl/tests/test_shutdown}/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_shutdown/test_kill_monitoring.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_staging/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_staging/staging_provider.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_staging/test_1316.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_staging/test_docs_1.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_staging/test_docs_2.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_staging/test_elaborate_noop_file.py +0 -0
- {parsl-2024.3.25/parsl/tests/test_data → parsl-2024.4.1/parsl/tests/test_staging}/test_file.py +0 -0
- {parsl-2024.3.25/parsl/tests/test_data → parsl-2024.4.1/parsl/tests/test_staging}/test_file_apps.py +0 -0
- {parsl-2024.3.25/parsl/tests/test_data → parsl-2024.4.1/parsl/tests/test_staging}/test_file_staging.py +0 -0
- {parsl-2024.3.25/parsl/tests/test_data → parsl-2024.4.1/parsl/tests/test_staging}/test_output_chain_filenames.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_staging/test_staging_ftp.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_staging/test_staging_ftp_in_task.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_staging/test_staging_globus.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_staging/test_staging_https.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_summary.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_thread_parallelism.py +0 -0
- {parsl-2024.3.25/parsl/tests/test_shutdown → parsl-2024.4.1/parsl/tests/test_threads}/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_threads/test_configs.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_threads/test_lazy_errors.py +0 -0
- {parsl-2024.3.25/parsl/tests/test_threads → parsl-2024.4.1/parsl/tests/test_utils}/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/test_utils/test_representation_mixin.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/tests/utils.py +0 -0
- {parsl-2024.3.25/parsl/tests/test_utils → parsl-2024.4.1/parsl/usage_tracking}/__init__.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/usage_tracking/usage.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl/utils.py +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl.egg-info/dependency_links.txt +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl.egg-info/entry_points.txt +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl.egg-info/requires.txt +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/parsl.egg-info/top_level.txt +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/requirements.txt +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/setup.cfg +0 -0
- {parsl-2024.3.25 → parsl-2024.4.1}/setup.py +0 -0
@@ -1,9 +1,9 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: parsl
|
3
|
-
Version: 2024.
|
3
|
+
Version: 2024.4.1
|
4
4
|
Summary: Simple data dependent workflows in Python
|
5
5
|
Home-page: https://github.com/Parsl/parsl
|
6
|
-
Download-URL: https://github.com/Parsl/parsl/archive/2024.
|
6
|
+
Download-URL: https://github.com/Parsl/parsl/archive/2024.04.01.tar.gz
|
7
7
|
Author: The Parsl Team
|
8
8
|
Author-email: parsl@googlegroups.com
|
9
9
|
License: Apache 2.0
|
@@ -97,6 +97,7 @@ For Developers
|
|
97
97
|
|
98
98
|
2. Build and Test::
|
99
99
|
|
100
|
+
$ cd parsl # navigate to the root directory of the project
|
100
101
|
$ make # show all available makefile targets
|
101
102
|
$ make virtualenv # create a virtual environment
|
102
103
|
$ source .venv/bin/activate # activate the virtual environment
|
@@ -34,12 +34,12 @@ from parsl.dataflow.states import States, FINAL_STATES, FINAL_FAILURE_STATES
|
|
34
34
|
from parsl.dataflow.taskrecord import TaskRecord
|
35
35
|
from parsl.errors import ConfigurationError, InternalConsistencyError, NoDataFlowKernelError
|
36
36
|
from parsl.jobs.job_status_poller import JobStatusPoller
|
37
|
-
from parsl.jobs.states import JobStatus, JobState
|
38
37
|
from parsl.usage_tracking.usage import UsageTracker
|
39
38
|
from parsl.executors.base import ParslExecutor
|
40
39
|
from parsl.executors.status_handling import BlockProviderExecutor
|
41
40
|
from parsl.executors.threads import ThreadPoolExecutor
|
42
41
|
from parsl.monitoring import MonitoringHub
|
42
|
+
from parsl.monitoring.remote import monitor_wrapper
|
43
43
|
from parsl.process_loggers import wrap_with_logs
|
44
44
|
from parsl.providers.base import ExecutionProvider
|
45
45
|
from parsl.utils import get_version, get_std_fname_mode, get_all_checkpoints, Timer
|
@@ -207,7 +207,7 @@ class DataFlowKernel:
|
|
207
207
|
atexit.register(self.atexit_cleanup)
|
208
208
|
|
209
209
|
def __enter__(self):
|
210
|
-
|
210
|
+
return self
|
211
211
|
|
212
212
|
def __exit__(self, exc_type, exc_value, traceback):
|
213
213
|
logger.debug("Exiting the context manager, calling cleanup for DFK")
|
@@ -714,14 +714,14 @@ class DataFlowKernel:
|
|
714
714
|
|
715
715
|
if self.monitoring is not None and self.monitoring.resource_monitoring_enabled:
|
716
716
|
wrapper_logging_level = logging.DEBUG if self.monitoring.monitoring_debug else logging.INFO
|
717
|
-
(function, args, kwargs) =
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
717
|
+
(function, args, kwargs) = monitor_wrapper(function, args, kwargs, try_id, task_id,
|
718
|
+
self.monitoring.monitoring_hub_url,
|
719
|
+
self.run_id,
|
720
|
+
wrapper_logging_level,
|
721
|
+
self.monitoring.resource_monitoring_interval,
|
722
|
+
executor.radio_mode,
|
723
|
+
executor.monitor_resources(),
|
724
|
+
self.run_dir)
|
725
725
|
|
726
726
|
with self.submitter_lock:
|
727
727
|
exec_fu = executor.submit(function, task_record['resource_specification'], *args, **kwargs)
|
@@ -1141,14 +1141,7 @@ class DataFlowKernel:
|
|
1141
1141
|
self._create_remote_dirs_over_channel(executor.provider, executor.provider.channel)
|
1142
1142
|
|
1143
1143
|
self.executors[executor.label] = executor
|
1144
|
-
|
1145
|
-
if self.monitoring and block_ids:
|
1146
|
-
new_status = {}
|
1147
|
-
for bid in block_ids:
|
1148
|
-
new_status[bid] = JobStatus(JobState.PENDING)
|
1149
|
-
msg = executor.create_monitoring_info(new_status)
|
1150
|
-
logger.debug("Sending monitoring message {} to hub from DFK".format(msg))
|
1151
|
-
self.monitoring.send(MessageType.BLOCK_INFO, msg)
|
1144
|
+
executor.start()
|
1152
1145
|
block_executors = [e for e in executors if isinstance(e, BlockProviderExecutor)]
|
1153
1146
|
self.job_status_poller.add_executors(block_executors)
|
1154
1147
|
|
@@ -1223,22 +1216,21 @@ class DataFlowKernel:
|
|
1223
1216
|
|
1224
1217
|
logger.info("Scaling in and shutting down executors")
|
1225
1218
|
|
1219
|
+
for ef in self.job_status_poller._executor_facades:
|
1220
|
+
if not ef.executor.bad_state_is_set:
|
1221
|
+
logger.info(f"Scaling in executor {ef.executor.label}")
|
1222
|
+
|
1223
|
+
# this code needs to be at least as many blocks as need
|
1224
|
+
# cancelling, but it is safe to be more, as the scaling
|
1225
|
+
# code will cope with being asked to cancel more blocks
|
1226
|
+
# than exist.
|
1227
|
+
block_count = len(ef.status)
|
1228
|
+
ef.scale_in(block_count)
|
1229
|
+
|
1230
|
+
else: # and bad_state_is_set
|
1231
|
+
logger.warning(f"Not scaling in executor {ef.executor.label} because it is in bad state")
|
1232
|
+
|
1226
1233
|
for executor in self.executors.values():
|
1227
|
-
if isinstance(executor, BlockProviderExecutor):
|
1228
|
-
if not executor.bad_state_is_set:
|
1229
|
-
logger.info(f"Scaling in executor {executor.label}")
|
1230
|
-
if executor.provider:
|
1231
|
-
job_ids = executor.provider.resources.keys()
|
1232
|
-
block_ids = executor.scale_in(len(job_ids))
|
1233
|
-
if self.monitoring and block_ids:
|
1234
|
-
new_status = {}
|
1235
|
-
for bid in block_ids:
|
1236
|
-
new_status[bid] = JobStatus(JobState.CANCELLED)
|
1237
|
-
msg = executor.create_monitoring_info(new_status)
|
1238
|
-
logger.debug("Sending message {} to hub from DFK".format(msg))
|
1239
|
-
self.monitoring.send(MessageType.BLOCK_INFO, msg)
|
1240
|
-
else: # and bad_state_is_set
|
1241
|
-
logger.warning(f"Not shutting down executor {executor.label} because it is in bad state")
|
1242
1234
|
logger.info(f"Shutting down executor {executor.label}")
|
1243
1235
|
executor.shutdown()
|
1244
1236
|
logger.info(f"Shut down executor {executor.label}")
|
@@ -53,7 +53,7 @@ class ParslExecutor(metaclass=ABCMeta):
|
|
53
53
|
return False
|
54
54
|
|
55
55
|
@abstractmethod
|
56
|
-
def start(self) ->
|
56
|
+
def start(self) -> None:
|
57
57
|
"""Start the executor.
|
58
58
|
|
59
59
|
Any spin-up operations (for example: starting thread pools) should be performed here.
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import typing
|
2
|
+
from collections import defaultdict
|
2
3
|
from concurrent.futures import Future
|
3
4
|
import typeguard
|
4
5
|
import logging
|
@@ -400,16 +401,6 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin):
|
|
400
401
|
|
401
402
|
logger.debug("Starting HighThroughputExecutor with provider:\n%s", self.provider)
|
402
403
|
|
403
|
-
# TODO: why is this a provider property?
|
404
|
-
block_ids = []
|
405
|
-
if hasattr(self.provider, 'init_blocks'):
|
406
|
-
try:
|
407
|
-
block_ids = self.scale_out(blocks=self.provider.init_blocks)
|
408
|
-
except Exception as e:
|
409
|
-
logger.error("Scaling out failed: {}".format(e))
|
410
|
-
raise e
|
411
|
-
return block_ids
|
412
|
-
|
413
404
|
def start(self):
|
414
405
|
"""Create the Interchange process and connect to it.
|
415
406
|
"""
|
@@ -439,8 +430,7 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin):
|
|
439
430
|
|
440
431
|
logger.debug("Created management thread: {}".format(self._queue_management_thread))
|
441
432
|
|
442
|
-
|
443
|
-
return block_ids
|
433
|
+
self.initialize_scaling()
|
444
434
|
|
445
435
|
@wrap_with_logs
|
446
436
|
def _queue_management_worker(self):
|
@@ -698,7 +688,7 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin):
|
|
698
688
|
d['status'] = s.status_name
|
699
689
|
d['timestamp'] = datetime.datetime.now()
|
700
690
|
d['executor_label'] = self.label
|
701
|
-
d['job_id'] = self.
|
691
|
+
d['job_id'] = self.blocks_to_job_id.get(bid, None)
|
702
692
|
d['block_id'] = bid
|
703
693
|
msg.append(d)
|
704
694
|
return msg
|
@@ -741,13 +731,11 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin):
|
|
741
731
|
idle: float # shortest idle time of any manager in this block
|
742
732
|
|
743
733
|
managers = self.connected_managers()
|
744
|
-
block_info: Dict[str, BlockInfo] =
|
734
|
+
block_info: Dict[str, BlockInfo] = defaultdict(lambda: BlockInfo(tasks=0, idle=float('inf')))
|
745
735
|
for manager in managers:
|
746
736
|
if not manager['active']:
|
747
737
|
continue
|
748
738
|
b_id = manager['block_id']
|
749
|
-
if b_id not in block_info:
|
750
|
-
block_info[b_id] = BlockInfo(tasks=0, idle=float('inf'))
|
751
739
|
block_info[b_id].tasks += manager['tasks']
|
752
740
|
block_info[b_id].idle = min(block_info[b_id].idle, manager['idle_duration'])
|
753
741
|
|
@@ -779,14 +767,14 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin):
|
|
779
767
|
|
780
768
|
# Now kill via provider
|
781
769
|
# Potential issue with multiple threads trying to remove the same blocks
|
782
|
-
to_kill = [self.
|
770
|
+
to_kill = [self.blocks_to_job_id[bid] for bid in block_ids_to_kill if bid in self.blocks_to_job_id]
|
783
771
|
|
784
772
|
r = self.provider.cancel(to_kill)
|
785
773
|
job_ids = self._filter_scale_in_ids(to_kill, r)
|
786
774
|
|
787
|
-
# to_kill block_ids are fetched from self.
|
788
|
-
# If a block_id is in self.
|
789
|
-
block_ids_killed = [self.
|
775
|
+
# to_kill block_ids are fetched from self.blocks_to_job_id
|
776
|
+
# If a block_id is in self.blocks_to_job_id, it must exist in self.job_ids_to_block
|
777
|
+
block_ids_killed = [self.job_ids_to_block[jid] for jid in job_ids]
|
790
778
|
|
791
779
|
return block_ids_killed
|
792
780
|
|
@@ -335,14 +335,17 @@ class Manager:
|
|
335
335
|
self.heartbeat_to_incoming()
|
336
336
|
last_beat = time.time()
|
337
337
|
|
338
|
-
if
|
338
|
+
if time.time() > self.drain_time:
|
339
339
|
logger.info("Requesting drain")
|
340
340
|
self.drain_to_incoming()
|
341
|
-
self.drain_time = None
|
342
341
|
# This will start the pool draining...
|
343
342
|
# Drained exit behaviour does not happen here. It will be
|
344
343
|
# driven by the interchange sending a DRAINED_CODE message.
|
345
344
|
|
345
|
+
# now set drain time to the far future so we don't send a drain
|
346
|
+
# message every iteration.
|
347
|
+
self.drain_time = float('inf')
|
348
|
+
|
346
349
|
poll_duration_s = max(0, next_interesting_event_time - time.time())
|
347
350
|
socks = dict(poller.poll(timeout=poll_duration_s * 1000))
|
348
351
|
|
@@ -68,8 +68,8 @@ class BlockProviderExecutor(ParslExecutor):
|
|
68
68
|
self._block_id_counter = AtomicIDCounter()
|
69
69
|
|
70
70
|
self._tasks = {} # type: Dict[object, Future]
|
71
|
-
self.
|
72
|
-
self.
|
71
|
+
self.blocks_to_job_id = {} # type: Dict[str, str]
|
72
|
+
self.job_ids_to_block = {} # type: Dict[str, str]
|
73
73
|
|
74
74
|
def _make_status_dict(self, block_ids: List[str], status_list: List[JobStatus]) -> Dict[str, JobStatus]:
|
75
75
|
"""Given a list of block ids and a list of corresponding status strings,
|
@@ -194,8 +194,8 @@ class BlockProviderExecutor(ParslExecutor):
|
|
194
194
|
logger.info(f"Allocated block ID {block_id}")
|
195
195
|
try:
|
196
196
|
job_id = self._launch_block(block_id)
|
197
|
-
self.
|
198
|
-
self.
|
197
|
+
self.blocks_to_job_id[block_id] = job_id
|
198
|
+
self.job_ids_to_block[job_id] = block_id
|
199
199
|
block_ids.append(block_id)
|
200
200
|
except Exception as ex:
|
201
201
|
self._fail_job_async(block_id,
|
@@ -232,10 +232,10 @@ class BlockProviderExecutor(ParslExecutor):
|
|
232
232
|
# Not using self.blocks.keys() and self.blocks.values() simultaneously
|
233
233
|
# The dictionary may be changed during invoking this function
|
234
234
|
# As scale_in and scale_out are invoked in multiple threads
|
235
|
-
block_ids = list(self.
|
235
|
+
block_ids = list(self.blocks_to_job_id.keys())
|
236
236
|
job_ids = [] # types: List[Any]
|
237
237
|
for bid in block_ids:
|
238
|
-
job_ids.append(self.
|
238
|
+
job_ids.append(self.blocks_to_job_id[bid])
|
239
239
|
return block_ids, job_ids
|
240
240
|
|
241
241
|
@abstractproperty
|
@@ -186,7 +186,13 @@ class TaskVineExecutor(BlockProviderExecutor, putils.RepresentationMixin):
|
|
186
186
|
# Attribute indicating whether this executor was started to shut it down properly.
|
187
187
|
# This safeguards cases where an object of this executor is created but
|
188
188
|
# the executor never starts, so it shouldn't be shutdowned.
|
189
|
-
self.
|
189
|
+
self._is_started = False
|
190
|
+
|
191
|
+
# Attribute indicating whether this executor was shutdown before.
|
192
|
+
# This safeguards cases where this object is automatically shut down (e.g.,
|
193
|
+
# via atexit) and the user also explicitly calls shut down. While this is
|
194
|
+
# permitted, the effect of an executor shutdown should happen only once.
|
195
|
+
self._is_shutdown = False
|
190
196
|
|
191
197
|
def atexit_cleanup(self):
|
192
198
|
# Calls this executor's shutdown method upon Python exiting the process.
|
@@ -252,7 +258,7 @@ class TaskVineExecutor(BlockProviderExecutor, putils.RepresentationMixin):
|
|
252
258
|
"""
|
253
259
|
|
254
260
|
# Mark this executor object as started
|
255
|
-
self.
|
261
|
+
self._is_started = True
|
256
262
|
|
257
263
|
# Synchronize connection and communication settings between the manager and factory
|
258
264
|
self.__synchronize_manager_factory_comm_settings()
|
@@ -580,13 +586,6 @@ class TaskVineExecutor(BlockProviderExecutor, putils.RepresentationMixin):
|
|
580
586
|
self._worker_command = self._construct_worker_command()
|
581
587
|
self._patch_providers()
|
582
588
|
|
583
|
-
if hasattr(self.provider, 'init_blocks'):
|
584
|
-
try:
|
585
|
-
self.scale_out(blocks=self.provider.init_blocks)
|
586
|
-
except Exception as e:
|
587
|
-
logger.error("Initial block scaling out failed: {}".format(e))
|
588
|
-
raise e
|
589
|
-
|
590
589
|
@property
|
591
590
|
def outstanding(self) -> int:
|
592
591
|
"""Count the number of outstanding tasks."""
|
@@ -601,8 +600,8 @@ class TaskVineExecutor(BlockProviderExecutor, putils.RepresentationMixin):
|
|
601
600
|
"""Scale in method. Cancel a given number of blocks
|
602
601
|
"""
|
603
602
|
# Obtain list of blocks to kill
|
604
|
-
to_kill = list(self.
|
605
|
-
kill_ids = [self.
|
603
|
+
to_kill = list(self.blocks_to_job_id.keys())[:count]
|
604
|
+
kill_ids = [self.blocks_to_job_id[block] for block in to_kill]
|
606
605
|
|
607
606
|
# Cancel the blocks provisioned
|
608
607
|
if self.provider:
|
@@ -614,15 +613,19 @@ class TaskVineExecutor(BlockProviderExecutor, putils.RepresentationMixin):
|
|
614
613
|
"""Shutdown the executor. Sets flag to cancel the submit process and
|
615
614
|
collector thread, which shuts down the TaskVine system submission.
|
616
615
|
"""
|
617
|
-
if not self.
|
616
|
+
if not self._is_started:
|
618
617
|
# Don't shutdown if the executor never starts.
|
619
618
|
return
|
620
619
|
|
620
|
+
if self._is_shutdown:
|
621
|
+
# Don't shutdown this executor again.
|
622
|
+
return
|
623
|
+
|
621
624
|
logger.debug("TaskVine shutdown started")
|
622
625
|
self._should_stop.set()
|
623
626
|
|
624
627
|
# Remove the workers that are still going
|
625
|
-
kill_ids = [self.
|
628
|
+
kill_ids = [self.blocks_to_job_id[block] for block in self.blocks_to_job_id.keys()]
|
626
629
|
if self.provider:
|
627
630
|
logger.debug("Cancelling blocks")
|
628
631
|
self.provider.cancel(kill_ids)
|
@@ -636,6 +639,7 @@ class TaskVineExecutor(BlockProviderExecutor, putils.RepresentationMixin):
|
|
636
639
|
logger.debug("Joining on factory process")
|
637
640
|
self._factory_process.join()
|
638
641
|
|
642
|
+
self._is_shutdown = True
|
639
643
|
logger.debug("TaskVine shutdown completed")
|
640
644
|
|
641
645
|
@wrap_with_logs
|
@@ -255,7 +255,6 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
|
|
255
255
|
self.label = label
|
256
256
|
self.task_queue = multiprocessing.Queue() # type: multiprocessing.Queue
|
257
257
|
self.collector_queue = multiprocessing.Queue() # type: multiprocessing.Queue
|
258
|
-
self.blocks = {} # type: Dict[str, str]
|
259
258
|
self.address = address
|
260
259
|
self.port = port
|
261
260
|
self.executor_task_counter = -1
|
@@ -305,7 +304,13 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
|
|
305
304
|
# Attribute indicating whether this executor was started to shut it down properly.
|
306
305
|
# This safeguards cases where an object of this executor is created but
|
307
306
|
# the executor never starts, so it shouldn't be shutdowned.
|
308
|
-
self.
|
307
|
+
self.is_started = False
|
308
|
+
|
309
|
+
# Attribute indicating whether this executor was shutdown before.
|
310
|
+
# This safeguards cases where this object is automatically shut down (e.g.,
|
311
|
+
# via atexit) and the user also explicitly calls shut down. While this is
|
312
|
+
# permitted, the effect of an executor shutdown should happen only once.
|
313
|
+
self.is_shutdown = False
|
309
314
|
|
310
315
|
def atexit_cleanup(self):
|
311
316
|
# Calls this executor's shutdown method upon Python exiting the process.
|
@@ -321,7 +326,7 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
|
|
321
326
|
retrieve Parsl tasks within the Work Queue system.
|
322
327
|
"""
|
323
328
|
# Mark this executor object as started
|
324
|
-
self.
|
329
|
+
self.is_started = True
|
325
330
|
self.tasks_lock = threading.Lock()
|
326
331
|
|
327
332
|
# Create directories for data and results
|
@@ -669,13 +674,6 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
|
|
669
674
|
self.worker_command = self._construct_worker_command()
|
670
675
|
self._patch_providers()
|
671
676
|
|
672
|
-
if hasattr(self.provider, 'init_blocks'):
|
673
|
-
try:
|
674
|
-
self.scale_out(blocks=self.provider.init_blocks)
|
675
|
-
except Exception as e:
|
676
|
-
logger.error("Initial block scaling out failed: {}".format(e))
|
677
|
-
raise e
|
678
|
-
|
679
677
|
@property
|
680
678
|
def outstanding(self) -> int:
|
681
679
|
"""Count the number of outstanding tasks. This is inefficiently
|
@@ -697,8 +695,8 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
|
|
697
695
|
"""Scale in method.
|
698
696
|
"""
|
699
697
|
# Obtain list of blocks to kill
|
700
|
-
to_kill = list(self.
|
701
|
-
kill_ids = [self.
|
698
|
+
to_kill = list(self.blocks_to_job_id.keys())[:count]
|
699
|
+
kill_ids = [self.blocks_to_job_id[block] for block in to_kill]
|
702
700
|
|
703
701
|
# Cancel the blocks provisioned
|
704
702
|
if self.provider:
|
@@ -710,15 +708,19 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
|
|
710
708
|
"""Shutdown the executor. Sets flag to cancel the submit process and
|
711
709
|
collector thread, which shuts down the Work Queue system submission.
|
712
710
|
"""
|
713
|
-
if not self.
|
711
|
+
if not self.is_started:
|
714
712
|
# Don't shutdown if the executor never starts.
|
715
713
|
return
|
716
714
|
|
715
|
+
if self.is_shutdown:
|
716
|
+
# Don't shutdown this executor again.
|
717
|
+
return
|
718
|
+
|
717
719
|
logger.debug("Work Queue shutdown started")
|
718
720
|
self.should_stop.value = True
|
719
721
|
|
720
722
|
# Remove the workers that are still going
|
721
|
-
kill_ids = [self.
|
723
|
+
kill_ids = [self.blocks_to_job_id[block] for block in self.blocks_to_job_id.keys()]
|
722
724
|
if self.provider:
|
723
725
|
logger.debug("Cancelling blocks")
|
724
726
|
self.provider.cancel(kill_ids)
|
@@ -728,6 +730,7 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
|
|
728
730
|
logger.debug("Joining on collector thread")
|
729
731
|
self.collector_thread.join()
|
730
732
|
|
733
|
+
self.is_shutdown = True
|
731
734
|
logger.debug("Work Queue shutdown completed")
|
732
735
|
|
733
736
|
@wrap_with_logs
|
@@ -16,13 +16,14 @@ from parsl.utils import Timer
|
|
16
16
|
logger = logging.getLogger(__name__)
|
17
17
|
|
18
18
|
|
19
|
-
class
|
19
|
+
class PolledExecutorFacade:
|
20
20
|
def __init__(self, executor: BlockProviderExecutor, dfk: Optional["parsl.dataflow.dflow.DataFlowKernel"] = None):
|
21
21
|
self._executor = executor
|
22
22
|
self._dfk = dfk
|
23
23
|
self._interval = executor.status_polling_interval
|
24
24
|
self._last_poll_time = 0.0
|
25
25
|
self._status = {} # type: Dict[str, JobStatus]
|
26
|
+
self.first = True
|
26
27
|
|
27
28
|
# Create a ZMQ channel to send poll status to monitoring
|
28
29
|
self.monitoring_enabled = False
|
@@ -109,7 +110,7 @@ class JobStatusPoller(Timer):
|
|
109
110
|
def __init__(self, *, strategy: Optional[str], max_idletime: float,
|
110
111
|
strategy_period: Union[float, int],
|
111
112
|
dfk: Optional["parsl.dataflow.dflow.DataFlowKernel"] = None) -> None:
|
112
|
-
self.
|
113
|
+
self._executor_facades = [] # type: List[PolledExecutorFacade]
|
113
114
|
self.dfk = dfk
|
114
115
|
self._strategy = Strategy(strategy=strategy,
|
115
116
|
max_idletime=max_idletime)
|
@@ -117,21 +118,21 @@ class JobStatusPoller(Timer):
|
|
117
118
|
|
118
119
|
def poll(self) -> None:
|
119
120
|
self._update_state()
|
120
|
-
self._run_error_handlers(self.
|
121
|
-
self._strategy.strategize(self.
|
121
|
+
self._run_error_handlers(self._executor_facades)
|
122
|
+
self._strategy.strategize(self._executor_facades)
|
122
123
|
|
123
|
-
def _run_error_handlers(self, status: List[
|
124
|
+
def _run_error_handlers(self, status: List[PolledExecutorFacade]) -> None:
|
124
125
|
for es in status:
|
125
126
|
es.executor.handle_errors(es.status)
|
126
127
|
|
127
128
|
def _update_state(self) -> None:
|
128
129
|
now = time.time()
|
129
|
-
for item in self.
|
130
|
+
for item in self._executor_facades:
|
130
131
|
item.poll(now)
|
131
132
|
|
132
133
|
def add_executors(self, executors: Sequence[BlockProviderExecutor]) -> None:
|
133
134
|
for executor in executors:
|
134
135
|
if executor.status_polling_interval > 0:
|
135
136
|
logger.debug("Adding executor {}".format(executor.label))
|
136
|
-
self.
|
137
|
+
self._executor_facades.append(PolledExecutorFacade(executor, self.dfk))
|
137
138
|
self._strategy.add_executors(executors)
|
@@ -129,8 +129,8 @@ class Strategy:
|
|
129
129
|
self.executors = {}
|
130
130
|
self.max_idletime = max_idletime
|
131
131
|
|
132
|
-
self.strategies = {None: self.
|
133
|
-
'none': self.
|
132
|
+
self.strategies = {None: self._strategy_init_only,
|
133
|
+
'none': self._strategy_init_only,
|
134
134
|
'simple': self._strategy_simple,
|
135
135
|
'htex_auto_scale': self._strategy_htex_auto_scale}
|
136
136
|
|
@@ -146,15 +146,22 @@ class Strategy:
|
|
146
146
|
for executor in executors:
|
147
147
|
self.executors[executor.label] = {'idle_since': None}
|
148
148
|
|
149
|
-
def
|
150
|
-
"""
|
149
|
+
def _strategy_init_only(self, executor_facades: List[jsp.PolledExecutorFacade]) -> None:
|
150
|
+
"""Scale up to init_blocks at the start, then nothing more.
|
151
151
|
"""
|
152
|
-
|
152
|
+
for ef in executor_facades:
|
153
|
+
if ef.first:
|
154
|
+
executor = ef.executor
|
155
|
+
logger.debug(f"strategy_init_only: scaling out {executor.provider.init_blocks} initial blocks for {executor.label}")
|
156
|
+
ef.scale_out(executor.provider.init_blocks)
|
157
|
+
ef.first = False
|
158
|
+
else:
|
159
|
+
logger.debug("strategy_init_only: doing nothing")
|
153
160
|
|
154
|
-
def _strategy_simple(self,
|
155
|
-
self._general_strategy(
|
161
|
+
def _strategy_simple(self, executor_facades: List[jsp.PolledExecutorFacade]) -> None:
|
162
|
+
self._general_strategy(executor_facades, strategy_type='simple')
|
156
163
|
|
157
|
-
def _strategy_htex_auto_scale(self,
|
164
|
+
def _strategy_htex_auto_scale(self, executor_facades: List[jsp.PolledExecutorFacade]) -> None:
|
158
165
|
"""HTEX specific auto scaling strategy
|
159
166
|
|
160
167
|
This strategy works only for HTEX. This strategy will scale out by
|
@@ -169,24 +176,30 @@ class Strategy:
|
|
169
176
|
expected to scale in effectively only when # of workers, or tasks executing
|
170
177
|
per block is close to 1.
|
171
178
|
"""
|
172
|
-
self._general_strategy(
|
179
|
+
self._general_strategy(executor_facades, strategy_type='htex')
|
173
180
|
|
174
181
|
@wrap_with_logs
|
175
|
-
def _general_strategy(self,
|
176
|
-
logger.debug(f"general strategy starting with strategy_type {strategy_type} for {len(
|
182
|
+
def _general_strategy(self, executor_facades, *, strategy_type):
|
183
|
+
logger.debug(f"general strategy starting with strategy_type {strategy_type} for {len(executor_facades)} executors")
|
177
184
|
|
178
|
-
for
|
179
|
-
executor =
|
185
|
+
for ef in executor_facades:
|
186
|
+
executor = ef.executor
|
180
187
|
label = executor.label
|
181
188
|
if not isinstance(executor, BlockProviderExecutor):
|
182
189
|
logger.debug(f"Not strategizing for executor {label} because scaling not enabled")
|
183
190
|
continue
|
184
191
|
logger.debug(f"Strategizing for executor {label}")
|
185
192
|
|
193
|
+
if ef.first:
|
194
|
+
executor = ef.executor
|
195
|
+
logger.debug(f"Scaling out {executor.provider.init_blocks} initial blocks for {label}")
|
196
|
+
ef.scale_out(executor.provider.init_blocks)
|
197
|
+
ef.first = False
|
198
|
+
|
186
199
|
# Tasks that are either pending completion
|
187
200
|
active_tasks = executor.outstanding
|
188
201
|
|
189
|
-
status =
|
202
|
+
status = ef.status
|
190
203
|
|
191
204
|
# FIXME we need to handle case where provider does not define these
|
192
205
|
# FIXME probably more of this logic should be moved to the provider
|
@@ -242,7 +255,7 @@ class Strategy:
|
|
242
255
|
# We have resources idle for the max duration,
|
243
256
|
# we have to scale_in now.
|
244
257
|
logger.debug(f"Idle time has reached {self.max_idletime}s for executor {label}; scaling in")
|
245
|
-
|
258
|
+
ef.scale_in(active_blocks - min_blocks)
|
246
259
|
|
247
260
|
else:
|
248
261
|
logger.debug(
|
@@ -265,7 +278,7 @@ class Strategy:
|
|
265
278
|
excess_blocks = math.ceil(float(excess_slots) / (tasks_per_node * nodes_per_block))
|
266
279
|
excess_blocks = min(excess_blocks, max_blocks - active_blocks)
|
267
280
|
logger.debug(f"Requesting {excess_blocks} more blocks")
|
268
|
-
|
281
|
+
ef.scale_out(excess_blocks)
|
269
282
|
|
270
283
|
elif active_slots == 0 and active_tasks > 0:
|
271
284
|
logger.debug("Strategy case 4a: No active slots but some active tasks - could scale out by a single block")
|
@@ -274,7 +287,7 @@ class Strategy:
|
|
274
287
|
if active_blocks < max_blocks:
|
275
288
|
logger.debug("Requesting single block")
|
276
289
|
|
277
|
-
|
290
|
+
ef.scale_out(1)
|
278
291
|
else:
|
279
292
|
logger.debug("Not requesting single block, because at maxblocks already")
|
280
293
|
|
@@ -290,7 +303,7 @@ class Strategy:
|
|
290
303
|
excess_blocks = math.ceil(float(excess_slots) / (tasks_per_node * nodes_per_block))
|
291
304
|
excess_blocks = min(excess_blocks, active_blocks - min_blocks)
|
292
305
|
logger.debug(f"Requesting scaling in by {excess_blocks} blocks with idle time {self.max_idletime}s")
|
293
|
-
|
306
|
+
ef.scale_in(excess_blocks, max_idletime=self.max_idletime)
|
294
307
|
else:
|
295
308
|
logger.error("This strategy does not support scaling in except for HighThroughputExecutor - taking no action")
|
296
309
|
else:
|
@@ -8,8 +8,6 @@ import zmq
|
|
8
8
|
|
9
9
|
import queue
|
10
10
|
|
11
|
-
import parsl.monitoring.remote
|
12
|
-
|
13
11
|
from parsl.multiprocessing import ForkProcess, SizedQueue
|
14
12
|
from multiprocessing import Process
|
15
13
|
from multiprocessing.queues import Queue
|
@@ -23,7 +21,7 @@ from parsl.serialize import deserialize
|
|
23
21
|
from parsl.monitoring.router import router_starter
|
24
22
|
from parsl.monitoring.message_type import MessageType
|
25
23
|
from parsl.monitoring.types import AddressedMonitoringMessage
|
26
|
-
from typing import cast, Any,
|
24
|
+
from typing import cast, Any, Optional, Tuple, Union, TYPE_CHECKING
|
27
25
|
|
28
26
|
_db_manager_excepts: Optional[Exception]
|
29
27
|
|
@@ -269,23 +267,6 @@ class MonitoringHub(RepresentationMixin):
|
|
269
267
|
self.filesystem_proc.terminate()
|
270
268
|
self.filesystem_proc.join()
|
271
269
|
|
272
|
-
@staticmethod
|
273
|
-
def monitor_wrapper(f: Any,
|
274
|
-
args: Sequence,
|
275
|
-
kwargs: Dict,
|
276
|
-
try_id: int,
|
277
|
-
task_id: int,
|
278
|
-
monitoring_hub_url: str,
|
279
|
-
run_id: str,
|
280
|
-
logging_level: int,
|
281
|
-
sleep_dur: float,
|
282
|
-
radio_mode: str,
|
283
|
-
monitor_resources: bool,
|
284
|
-
run_dir: str) -> Tuple[Callable, Sequence, Dict]:
|
285
|
-
return parsl.monitoring.remote.monitor_wrapper(f, args, kwargs, try_id, task_id, monitoring_hub_url,
|
286
|
-
run_id, logging_level, sleep_dur, radio_mode,
|
287
|
-
monitor_resources, run_dir)
|
288
|
-
|
289
270
|
|
290
271
|
@wrap_with_logs
|
291
272
|
def filesystem_receiver(logdir: str, q: "queue.Queue[AddressedMonitoringMessage]", run_dir: str) -> None:
|
@@ -58,7 +58,7 @@ def test_provider():
|
|
58
58
|
logger.info("Job in terminal state")
|
59
59
|
|
60
60
|
_, current_jobs = executor._get_block_and_job_ids()
|
61
|
-
# PR 1952 stoped removing scale_in blocks from self.
|
61
|
+
# PR 1952 stoped removing scale_in blocks from self.blocks_to_job_id
|
62
62
|
# A new PR will handle removing blocks from self.block
|
63
63
|
# this includes failed/completed/canceled blocks
|
64
64
|
assert len(current_jobs) == 1, "Expected current_jobs == 1"
|