parsl 2025.3.17__tar.gz → 2025.3.24__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-2025.3.17/parsl.egg-info → parsl-2025.3.24}/PKG-INFO +2 -2
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/dataflow/dflow.py +1 -3
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/base.py +13 -37
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/flux/executor.py +1 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/globus_compute.py +1 -1
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/high_throughput/executor.py +18 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/radical/executor.py +1 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/status_handling.py +8 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/taskvine/executor.py +1 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/workqueue/executor.py +1 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/errors.py +5 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/monitoring.py +55 -115
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/radios/zmq_router.py +80 -18
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/multiprocessing.py +42 -2
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_monitoring/test_exit_helper.py +6 -7
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_monitoring/test_fuzz_zmq.py +1 -1
- parsl-2025.3.24/parsl/tests/test_monitoring/test_radio_zmq.py +27 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_monitoring/test_stdouterr.py +3 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_shutdown/test_kill_monitoring.py +1 -1
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/usage_tracking/usage.py +2 -2
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/version.py +1 -1
- {parsl-2025.3.17 → parsl-2025.3.24/parsl.egg-info}/PKG-INFO +2 -2
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl.egg-info/SOURCES.txt +1 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/LICENSE +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/MANIFEST.in +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/README.rst +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/addresses.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/app/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/app/app.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/app/bash.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/app/errors.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/app/futures.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/app/python.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/benchmark/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/benchmark/perf.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/concurrent/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/config.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/configs/ASPIRE1.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/configs/Azure.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/configs/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/configs/bridges.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/configs/cc_in2p3.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/configs/ec2.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/configs/expanse.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/configs/frontera.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/configs/gc_multisite.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/configs/gc_tutorial.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/configs/htex_local.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/configs/illinoiscluster.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/configs/improv.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/configs/kubernetes.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/configs/local_threads.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/configs/midway.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/configs/osg.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/configs/polaris.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/configs/stampede2.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/configs/summit.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/configs/toss3_llnl.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/configs/vineex_local.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/configs/wqex_local.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/curvezmq.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/data_provider/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/data_provider/data_manager.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/data_provider/file_noop.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/data_provider/files.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/data_provider/ftp.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/data_provider/globus.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/data_provider/http.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/data_provider/rsync.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/data_provider/staging.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/data_provider/zip.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/dataflow/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/dataflow/dependency_resolvers.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/dataflow/errors.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/dataflow/futures.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/dataflow/memoization.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/dataflow/rundirs.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/dataflow/states.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/dataflow/taskrecord.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/errors.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/errors.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/execute_task.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/flux/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/flux/execute_parsl_task.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/flux/flux_instance_manager.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/high_throughput/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/high_throughput/errors.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/high_throughput/interchange.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/high_throughput/manager_record.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/high_throughput/manager_selector.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/high_throughput/monitoring_info.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/high_throughput/mpi_executor.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/high_throughput/mpi_prefix_composer.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/high_throughput/mpi_resource_management.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/high_throughput/probe.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/high_throughput/process_worker_pool.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/high_throughput/zmq_pipes.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/radical/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/radical/rpex_resources.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/radical/rpex_worker.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/taskvine/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/taskvine/errors.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/taskvine/exec_parsl_function.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/taskvine/factory.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/taskvine/factory_config.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/taskvine/manager.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/taskvine/manager_config.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/taskvine/utils.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/threads.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/workqueue/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/workqueue/errors.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/workqueue/exec_parsl_function.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/workqueue/parsl_coprocess.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/executors/workqueue/parsl_coprocess_stub.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/jobs/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/jobs/error_handlers.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/jobs/errors.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/jobs/job_status_poller.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/jobs/states.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/jobs/strategy.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/launchers/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/launchers/base.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/launchers/errors.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/launchers/launchers.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/log_utils.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/db_manager.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/message_type.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/queries/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/queries/pandas.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/radios/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/radios/base.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/radios/filesystem.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/radios/filesystem_router.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/radios/htex.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/radios/multiprocessing.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/radios/udp.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/radios/udp_router.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/radios/zmq.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/remote.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/types.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/visualization/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/visualization/app.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/visualization/models.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/visualization/plots/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/visualization/plots/default/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/visualization/plots/default/task_plots.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/visualization/plots/default/workflow_plots.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/visualization/plots/default/workflow_resource_plots.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/visualization/static/parsl-logo-white.png +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/visualization/static/parsl-monitor.css +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/visualization/templates/app.html +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/visualization/templates/dag.html +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/visualization/templates/error.html +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/visualization/templates/layout.html +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/visualization/templates/resource_usage.html +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/visualization/templates/task.html +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/visualization/templates/workflow.html +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/visualization/templates/workflows_summary.html +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/visualization/utils.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/visualization/version.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/monitoring/visualization/views.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/process_loggers.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/aws/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/aws/aws.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/aws/template.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/azure/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/azure/azure.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/azure/template.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/base.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/cluster_provider.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/condor/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/condor/condor.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/condor/template.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/errors.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/googlecloud/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/googlecloud/googlecloud.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/grid_engine/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/grid_engine/grid_engine.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/grid_engine/template.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/kubernetes/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/kubernetes/kube.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/kubernetes/template.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/local/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/local/local.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/lsf/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/lsf/lsf.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/lsf/template.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/pbspro/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/pbspro/pbspro.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/pbspro/template.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/slurm/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/slurm/slurm.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/slurm/template.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/torque/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/torque/template.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/providers/torque/torque.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/py.typed +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/serialize/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/serialize/base.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/serialize/concretes.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/serialize/errors.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/serialize/facade.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/serialize/proxystore.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/callables_helper.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/azure_single_node.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/bluewaters.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/bridges.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/cc_in2p3.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/comet.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/ec2_single_node.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/ec2_spot.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/flux_local.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/frontera.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/globus_compute.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/htex_local.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/htex_local_alternate.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/htex_local_intask_staging.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/htex_local_rsync_staging.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/local_radical.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/local_radical_mpi.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/local_threads.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/local_threads_checkpoint.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/local_threads_checkpoint_dfk_exit.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/local_threads_checkpoint_periodic.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/local_threads_checkpoint_task_exit.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/local_threads_ftp_in_task.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/local_threads_globus.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/local_threads_http_in_task.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/local_threads_monitoring.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/local_threads_no_cache.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/midway.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/nscc_singapore.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/osg_htex.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/petrelkube.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/slurm_local.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/summit.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/taskvine_ex.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/user_opts.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/configs/workqueue_ex.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/conftest.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/integration/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/integration/latency.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/integration/test_apps/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/integration/test_parsl_load_default_config.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/integration/test_stress/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/integration/test_stress/test_python_simple.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/integration/test_stress/test_python_threads.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/manual_tests/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/manual_tests/htex_local.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/manual_tests/test_basic.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/manual_tests/test_log_filter.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/manual_tests/test_memory_limits.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/manual_tests/test_regression_220.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/manual_tests/test_udp_simple.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/manual_tests/test_worker_count.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/scaling_tests/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/scaling_tests/htex_local.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/scaling_tests/local_threads.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/scaling_tests/test_scale.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/scaling_tests/vineex_condor.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/scaling_tests/vineex_local.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/scaling_tests/wqex_condor.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/scaling_tests/wqex_local.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/site_tests/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/site_tests/site_config_selector.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/site_tests/test_provider.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/site_tests/test_site.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/sites/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/sites/test_affinity.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/sites/test_concurrent.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/sites/test_dynamic_executor.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/sites/test_ec2.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/sites/test_launchers.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/sites/test_mpi/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/sites/test_worker_info.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_aalst_patterns.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_bash_apps/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_bash_apps/test_apptimeout.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_bash_apps/test_basic.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_bash_apps/test_error_codes.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_bash_apps/test_inputs_default.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_bash_apps/test_keyword_overlaps.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_bash_apps/test_kwarg_storage.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_bash_apps/test_memoize.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_bash_apps/test_memoize_ignore_args.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_bash_apps/test_memoize_ignore_args_regr.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_bash_apps/test_multiline.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_bash_apps/test_pipeline.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_bash_apps/test_std_uri.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_bash_apps/test_stdout.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_callables.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_checkpointing/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_checkpointing/test_periodic.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_checkpointing/test_python_checkpoint_1.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_checkpointing/test_python_checkpoint_2.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_checkpointing/test_regression_232.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_checkpointing/test_regression_233.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_checkpointing/test_regression_239.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_checkpointing/test_task_exit.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_curvezmq.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_docs/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_docs/test_from_slides.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_docs/test_kwargs.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_docs/test_tutorial_1.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_docs/test_workflow1.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_docs/test_workflow2.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_docs/test_workflow4.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_error_handling/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_error_handling/test_fail.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_error_handling/test_python_walltime.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_error_handling/test_rand_fail.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_error_handling/test_resource_spec.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_error_handling/test_retries.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_error_handling/test_retry_handler.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_error_handling/test_retry_handler_failure.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_error_handling/test_serialization_fail.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_error_handling/test_wrap_with_logs.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_execute_task.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_flowcontrol/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_flux.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_htex/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_htex/test_basic.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_htex/test_block_manager_selector_unit.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_htex/test_command_client_timeout.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_htex/test_connected_blocks.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_htex/test_cpu_affinity_explicit.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_htex/test_disconnected_blocks.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_htex/test_disconnected_blocks_failing_provider.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_htex/test_drain.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_htex/test_htex.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_htex/test_interchange_exit_bad_registration.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_htex/test_manager_failure.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_htex/test_manager_selector_by_block.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_htex/test_managers_command.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_htex/test_missing_worker.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_htex/test_multiple_disconnected_blocks.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_htex/test_resource_spec_validation.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_htex/test_worker_failure.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_htex/test_zmq_binding.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_monitoring/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_monitoring/test_app_names.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_monitoring/test_basic.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_monitoring/test_db_locks.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_monitoring/test_htex_init_blocks_vs_monitoring.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_monitoring/test_incomplete_futures.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_monitoring/test_memoization_representation.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_monitoring/test_viz_colouring.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_mpi_apps/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_mpi_apps/test_bad_mpi_config.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_mpi_apps/test_mpi_mode_enabled.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_mpi_apps/test_mpi_prefix.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_mpi_apps/test_mpi_scheduler.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_mpi_apps/test_mpiex.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_mpi_apps/test_resource_spec.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_providers/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_providers/test_kubernetes_provider.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_providers/test_local_provider.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_providers/test_pbspro_template.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_providers/test_slurm_instantiate.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_providers/test_slurm_template.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_providers/test_submiterror_deprecation.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_arg_input_types.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_basic.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_context_manager.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_dep_standard_futures.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_dependencies.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_dependencies_deep.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_depfail_propagation.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_fail.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_fibonacci_iterative.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_fibonacci_recursive.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_futures.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_garbage_collect.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_import_fail.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_inputs_default.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_join.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_lifted.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_mapred.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_memoize_1.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_memoize_2.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_memoize_4.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_memoize_bad_id_for_memo.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_memoize_ignore_args.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_memoize_joinapp.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_outputs.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_overview.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_pipeline.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_pluggable_future_resolution.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_simple.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_timeout.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_python_apps/test_type5.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_radical/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_radical/test_mpi_funcs.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_regression/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_regression/test_1480.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_regression/test_1606_wait_for_current_tasks.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_regression/test_1653.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_regression/test_221.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_regression/test_226.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_regression/test_2652.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_regression/test_69a.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_regression/test_854.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_regression/test_97_parallelism_0.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_regression/test_98.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_scaling/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_scaling/test_block_error_handler.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_scaling/test_regression_1621.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_scaling/test_regression_3568_scaledown_vs_MISSING.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_scaling/test_regression_3696_oscillation.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_scaling/test_scale_down.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_scaling/test_scale_down_htex_auto_scale.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_scaling/test_scale_down_htex_unregistered.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_scaling/test_shutdown_scalein.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_scaling/test_worker_interchange_bad_messages_3262.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_serialization/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_serialization/test_2555_caching_deserializer.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_serialization/test_3495_deserialize_managerlost.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_serialization/test_basic.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_serialization/test_htex_code_cache.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_serialization/test_pack_resource_spec.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_serialization/test_proxystore_configured.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_serialization/test_proxystore_impl.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_shutdown/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_staging/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_staging/staging_provider.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_staging/test_1316.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_staging/test_docs_1.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_staging/test_docs_2.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_staging/test_elaborate_noop_file.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_staging/test_file.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_staging/test_file_apps.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_staging/test_file_staging.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_staging/test_output_chain_filenames.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_staging/test_staging_ftp.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_staging/test_staging_ftp_in_task.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_staging/test_staging_globus.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_staging/test_staging_https.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_staging/test_staging_stdout.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_staging/test_zip_in.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_staging/test_zip_out.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_staging/test_zip_to_zip.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_summary.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_thread_parallelism.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_threads/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_threads/test_configs.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_threads/test_lazy_errors.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_utils/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_utils/test_execute_wait.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_utils/test_representation_mixin.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/test_utils/test_sanitize_dns.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/unit/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/unit/test_address.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/unit/test_file.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/unit/test_globus_compute_executor.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/unit/test_usage_tracking.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/tests/utils.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/usage_tracking/__init__.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/usage_tracking/api.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/usage_tracking/levels.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl/utils.py +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl.egg-info/dependency_links.txt +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl.egg-info/entry_points.txt +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl.egg-info/requires.txt +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/parsl.egg-info/top_level.txt +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/requirements.txt +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/setup.cfg +0 -0
- {parsl-2025.3.17 → parsl-2025.3.24}/setup.py +0 -0
@@ -1,9 +1,9 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: parsl
|
3
|
-
Version: 2025.3.
|
3
|
+
Version: 2025.3.24
|
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/2025.03.
|
6
|
+
Download-URL: https://github.com/Parsl/parsl/archive/2025.03.24.tar.gz
|
7
7
|
Author: The Parsl Team
|
8
8
|
Author-email: parsl@googlegroups.com
|
9
9
|
License: Apache 2.0
|
@@ -1128,9 +1128,7 @@ class DataFlowKernel:
|
|
1128
1128
|
executor.run_id = self.run_id
|
1129
1129
|
executor.run_dir = self.run_dir
|
1130
1130
|
if self.monitoring:
|
1131
|
-
executor.
|
1132
|
-
executor.hub_zmq_port = self.monitoring.hub_zmq_port
|
1133
|
-
executor.submit_monitoring_radio = self.monitoring.radio
|
1131
|
+
executor.monitoring_messages = self.monitoring.resource_msgs
|
1134
1132
|
if hasattr(executor, 'provider'):
|
1135
1133
|
if hasattr(executor.provider, 'script_dir'):
|
1136
1134
|
executor.provider.script_dir = os.path.join(self.run_dir, 'submit_scripts')
|
@@ -1,11 +1,14 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
import os
|
2
4
|
from abc import ABCMeta, abstractmethod
|
3
5
|
from concurrent.futures import Future
|
6
|
+
from multiprocessing.queues import Queue
|
4
7
|
from typing import Any, Callable, Dict, Optional
|
5
8
|
|
6
9
|
from typing_extensions import Literal, Self
|
7
10
|
|
8
|
-
from parsl.monitoring.
|
11
|
+
from parsl.monitoring.types import TaggedMonitoringMessage
|
9
12
|
|
10
13
|
|
11
14
|
class ParslExecutor(metaclass=ABCMeta):
|
@@ -42,6 +45,13 @@ class ParslExecutor(metaclass=ABCMeta):
|
|
42
45
|
invariant, not co-variant, and it looks like @typeguard cannot be
|
43
46
|
persuaded otherwise. So if you're implementing an executor and want to
|
44
47
|
@typeguard the constructor, you'll have to use List[Any] here.
|
48
|
+
|
49
|
+
The DataFlowKernel will set this attribute before calling .start(),
|
50
|
+
if monitoring is enabled:
|
51
|
+
|
52
|
+
monitoring_messages: Optional[Queue[TaggedMonitoringMessage]] - an executor
|
53
|
+
can send messages to the monitoring hub by putting them into
|
54
|
+
this queue.
|
45
55
|
"""
|
46
56
|
|
47
57
|
label: str = "undefined"
|
@@ -50,15 +60,11 @@ class ParslExecutor(metaclass=ABCMeta):
|
|
50
60
|
def __init__(
|
51
61
|
self,
|
52
62
|
*,
|
53
|
-
|
54
|
-
hub_zmq_port: Optional[int] = None,
|
55
|
-
submit_monitoring_radio: Optional[MonitoringRadioSender] = None,
|
63
|
+
monitoring_messages: Optional[Queue[TaggedMonitoringMessage]] = None,
|
56
64
|
run_dir: str = ".",
|
57
65
|
run_id: Optional[str] = None,
|
58
66
|
):
|
59
|
-
self.
|
60
|
-
self.hub_zmq_port = hub_zmq_port
|
61
|
-
self.submit_monitoring_radio = submit_monitoring_radio
|
67
|
+
self.monitoring_messages = monitoring_messages
|
62
68
|
self.run_dir = os.path.abspath(run_dir)
|
63
69
|
self.run_id = run_id
|
64
70
|
|
@@ -125,33 +131,3 @@ class ParslExecutor(metaclass=ABCMeta):
|
|
125
131
|
@run_id.setter
|
126
132
|
def run_id(self, value: Optional[str]) -> None:
|
127
133
|
self._run_id = value
|
128
|
-
|
129
|
-
@property
|
130
|
-
def hub_address(self) -> Optional[str]:
|
131
|
-
"""Address to the Hub for monitoring.
|
132
|
-
"""
|
133
|
-
return self._hub_address
|
134
|
-
|
135
|
-
@hub_address.setter
|
136
|
-
def hub_address(self, value: Optional[str]) -> None:
|
137
|
-
self._hub_address = value
|
138
|
-
|
139
|
-
@property
|
140
|
-
def hub_zmq_port(self) -> Optional[int]:
|
141
|
-
"""Port to the Hub for monitoring.
|
142
|
-
"""
|
143
|
-
return self._hub_zmq_port
|
144
|
-
|
145
|
-
@hub_zmq_port.setter
|
146
|
-
def hub_zmq_port(self, value: Optional[int]) -> None:
|
147
|
-
self._hub_zmq_port = value
|
148
|
-
|
149
|
-
@property
|
150
|
-
def submit_monitoring_radio(self) -> Optional[MonitoringRadioSender]:
|
151
|
-
"""Local radio for sending monitoring messages
|
152
|
-
"""
|
153
|
-
return self._submit_monitoring_radio
|
154
|
-
|
155
|
-
@submit_monitoring_radio.setter
|
156
|
-
def submit_monitoring_radio(self, value: Optional[MonitoringRadioSender]) -> None:
|
157
|
-
self._submit_monitoring_radio = value
|
@@ -231,6 +231,7 @@ class FluxExecutor(ParslExecutor, RepresentationMixin):
|
|
231
231
|
|
232
232
|
def start(self):
|
233
233
|
"""Called when DFK starts the executor when the config is loaded."""
|
234
|
+
super().start()
|
234
235
|
os.makedirs(self.working_dir, exist_ok=True)
|
235
236
|
self._submission_thread.start()
|
236
237
|
|
@@ -67,7 +67,7 @@ class GlobusComputeExecutor(ParslExecutor, RepresentationMixin):
|
|
67
67
|
|
68
68
|
def start(self) -> None:
|
69
69
|
""" Start the Globus Compute Executor """
|
70
|
-
|
70
|
+
super().start()
|
71
71
|
|
72
72
|
def submit(self, func: Callable, resource_specification: Dict[str, Any], *args: Any, **kwargs: Any) -> Future:
|
73
73
|
""" Submit func to globus-compute
|
@@ -29,6 +29,7 @@ from parsl.executors.high_throughput.manager_selector import (
|
|
29
29
|
)
|
30
30
|
from parsl.executors.status_handling import BlockProviderExecutor
|
31
31
|
from parsl.jobs.states import TERMINAL_STATES, JobState, JobStatus
|
32
|
+
from parsl.monitoring.radios.zmq_router import ZMQRadioReceiver, start_zmq_receiver
|
32
33
|
from parsl.process_loggers import wrap_with_logs
|
33
34
|
from parsl.providers import LocalProvider
|
34
35
|
from parsl.providers.base import ExecutionProvider
|
@@ -334,6 +335,10 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin, UsageIn
|
|
334
335
|
self._result_queue_thread_exit = threading.Event()
|
335
336
|
self._result_queue_thread: Optional[threading.Thread] = None
|
336
337
|
|
338
|
+
self.zmq_monitoring: Optional[ZMQRadioReceiver]
|
339
|
+
self.zmq_monitoring = None
|
340
|
+
self.hub_zmq_port = None
|
341
|
+
|
337
342
|
radio_mode = "htex"
|
338
343
|
enable_mpi_mode: bool = False
|
339
344
|
mpi_launcher: str = "mpiexec"
|
@@ -407,6 +412,7 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin, UsageIn
|
|
407
412
|
def start(self):
|
408
413
|
"""Create the Interchange process and connect to it.
|
409
414
|
"""
|
415
|
+
super().start()
|
410
416
|
if self.encrypted and self.cert_dir is None:
|
411
417
|
logger.debug("Creating CurveZMQ certificates")
|
412
418
|
self.cert_dir = curvezmq.create_certificates(self.logdir)
|
@@ -427,6 +433,15 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin, UsageIn
|
|
427
433
|
self.loopback_address, self.interchange_port_range, self.cert_dir
|
428
434
|
)
|
429
435
|
|
436
|
+
if self.monitoring_messages is not None:
|
437
|
+
self.zmq_monitoring = start_zmq_receiver(monitoring_messages=self.monitoring_messages,
|
438
|
+
loopback_address=self.loopback_address,
|
439
|
+
port_range=self.interchange_port_range,
|
440
|
+
logdir=self.logdir,
|
441
|
+
worker_debug=self.worker_debug,
|
442
|
+
)
|
443
|
+
self.hub_zmq_port = self.zmq_monitoring.port
|
444
|
+
|
430
445
|
self._result_queue_thread = None
|
431
446
|
self._start_result_queue_thread()
|
432
447
|
self._start_local_interchange_process()
|
@@ -861,6 +876,9 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin, UsageIn
|
|
861
876
|
if self._result_queue_thread:
|
862
877
|
self._result_queue_thread.join()
|
863
878
|
|
879
|
+
if self.zmq_monitoring:
|
880
|
+
self.zmq_monitoring.close()
|
881
|
+
|
864
882
|
logger.info("Finished HighThroughputExecutor shutdown attempt")
|
865
883
|
|
866
884
|
def get_usage_information(self):
|
@@ -215,6 +215,7 @@ class RadicalPilotExecutor(ParslExecutor, RepresentationMixin):
|
|
215
215
|
"""Create the Pilot component and pass it.
|
216
216
|
"""
|
217
217
|
logger.info("starting RadicalPilotExecutor")
|
218
|
+
super().start()
|
218
219
|
logger.info('Parsl: {0}'.format(parsl.__version__))
|
219
220
|
logger.info('RADICAL pilot: {0}'.format(rp.version))
|
220
221
|
self.session = rp.Session(cfg={'base': self.run_dir},
|
@@ -14,6 +14,7 @@ from parsl.executors.errors import BadStateException, ScalingFailed
|
|
14
14
|
from parsl.jobs.error_handlers import noop_error_handler, simple_error_handler
|
15
15
|
from parsl.jobs.states import TERMINAL_STATES, JobState, JobStatus
|
16
16
|
from parsl.monitoring.message_type import MessageType
|
17
|
+
from parsl.monitoring.radios.multiprocessing import MultiprocessingQueueRadioSender
|
17
18
|
from parsl.providers.base import ExecutionProvider
|
18
19
|
from parsl.utils import AtomicIDCounter
|
19
20
|
|
@@ -83,6 +84,13 @@ class BlockProviderExecutor(ParslExecutor):
|
|
83
84
|
# of pending, active and recently terminated blocks
|
84
85
|
self._status = {} # type: Dict[str, JobStatus]
|
85
86
|
|
87
|
+
self.submit_monitoring_radio: Optional[MultiprocessingQueueRadioSender] = None
|
88
|
+
|
89
|
+
def start(self):
|
90
|
+
super().start()
|
91
|
+
if self.monitoring_messages:
|
92
|
+
self.submit_monitoring_radio = MultiprocessingQueueRadioSender(self.monitoring_messages)
|
93
|
+
|
86
94
|
def _make_status_dict(self, block_ids: List[str], status_list: List[JobStatus]) -> Dict[str, JobStatus]:
|
87
95
|
"""Given a list of block ids and a list of corresponding status strings,
|
88
96
|
returns a dictionary mapping each block id to the corresponding status
|
@@ -239,6 +239,7 @@ class TaskVineExecutor(BlockProviderExecutor, putils.RepresentationMixin):
|
|
239
239
|
retrieve Parsl tasks within the TaskVine system.
|
240
240
|
"""
|
241
241
|
|
242
|
+
super().start()
|
242
243
|
# Synchronize connection and communication settings between the manager and factory
|
243
244
|
self.__synchronize_manager_factory_comm_settings()
|
244
245
|
|
@@ -314,6 +314,7 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
|
|
314
314
|
"""Create submit process and collector thread to create, send, and
|
315
315
|
retrieve Parsl tasks within the Work Queue system.
|
316
316
|
"""
|
317
|
+
super().start()
|
317
318
|
self.tasks_lock = threading.Lock()
|
318
319
|
|
319
320
|
# Create directories for data and results
|
@@ -4,10 +4,9 @@ import logging
|
|
4
4
|
import multiprocessing.synchronize as ms
|
5
5
|
import os
|
6
6
|
import queue
|
7
|
-
|
8
|
-
from multiprocessing.context import ForkProcess as ForkProcessType
|
7
|
+
import warnings
|
9
8
|
from multiprocessing.queues import Queue
|
10
|
-
from typing import TYPE_CHECKING,
|
9
|
+
from typing import TYPE_CHECKING, Any, Optional, Union
|
11
10
|
|
12
11
|
import typeguard
|
13
12
|
|
@@ -15,9 +14,13 @@ from parsl.monitoring.errors import MonitoringHubStartError
|
|
15
14
|
from parsl.monitoring.radios.filesystem_router import filesystem_router_starter
|
16
15
|
from parsl.monitoring.radios.multiprocessing import MultiprocessingQueueRadioSender
|
17
16
|
from parsl.monitoring.radios.udp_router import udp_router_starter
|
18
|
-
from parsl.monitoring.radios.zmq_router import zmq_router_starter
|
19
17
|
from parsl.monitoring.types import TaggedMonitoringMessage
|
20
|
-
from parsl.multiprocessing import
|
18
|
+
from parsl.multiprocessing import (
|
19
|
+
SizedQueue,
|
20
|
+
SpawnEvent,
|
21
|
+
SpawnProcess,
|
22
|
+
join_terminate_close_proc,
|
23
|
+
)
|
21
24
|
from parsl.utils import RepresentationMixin
|
22
25
|
|
23
26
|
_db_manager_excepts: Optional[Exception]
|
@@ -38,7 +41,7 @@ class MonitoringHub(RepresentationMixin):
|
|
38
41
|
def __init__(self,
|
39
42
|
hub_address: str,
|
40
43
|
hub_port: Optional[int] = None,
|
41
|
-
hub_port_range:
|
44
|
+
hub_port_range: Any = None,
|
42
45
|
|
43
46
|
workflow_name: Optional[str] = None,
|
44
47
|
workflow_version: Optional[str] = None,
|
@@ -57,12 +60,11 @@ class MonitoringHub(RepresentationMixin):
|
|
57
60
|
Note that despite the similar name, this is not related to
|
58
61
|
hub_port_range.
|
59
62
|
Default: None
|
60
|
-
hub_port_range :
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
Default: (55050, 56000)
|
63
|
+
hub_port_range : unused
|
64
|
+
Unused, but retained until 2025-09-14 to avoid configuration errors.
|
65
|
+
This value previously configured one ZMQ channel inside the
|
66
|
+
HighThroughputExecutor. That ZMQ channel is now configured by the
|
67
|
+
interchange_port_range parameter of HighThroughputExecutor.
|
66
68
|
workflow_name : str
|
67
69
|
The name for the workflow. Default to the name of the parsl script
|
68
70
|
workflow_version : str
|
@@ -89,6 +91,13 @@ class MonitoringHub(RepresentationMixin):
|
|
89
91
|
|
90
92
|
self.hub_address = hub_address
|
91
93
|
self.hub_port = hub_port
|
94
|
+
|
95
|
+
if hub_port_range is not None:
|
96
|
+
message = "Instead of MonitoringHub.hub_port_range, Use HighThroughputExecutor.interchange_port_range"
|
97
|
+
warnings.warn(message, DeprecationWarning)
|
98
|
+
logger.warning(message)
|
99
|
+
# This is used by RepresentationMixin so needs to exist as an attribute
|
100
|
+
# even though now it is otherwise unused.
|
92
101
|
self.hub_port_range = hub_port_range
|
93
102
|
|
94
103
|
self.logging_endpoint = logging_endpoint
|
@@ -120,90 +129,59 @@ class MonitoringHub(RepresentationMixin):
|
|
120
129
|
# in the future, Queue will allow runtime subscripts.
|
121
130
|
|
122
131
|
if TYPE_CHECKING:
|
123
|
-
zmq_comm_q: Queue[Union[int, str]]
|
124
132
|
udp_comm_q: Queue[Union[int, str]]
|
125
133
|
else:
|
126
|
-
zmq_comm_q: Queue
|
127
134
|
udp_comm_q: Queue
|
128
135
|
|
129
|
-
zmq_comm_q = SizedQueue(maxsize=10)
|
130
136
|
udp_comm_q = SizedQueue(maxsize=10)
|
131
137
|
|
132
138
|
self.resource_msgs: Queue[TaggedMonitoringMessage]
|
133
139
|
self.resource_msgs = SizedQueue()
|
134
140
|
|
135
141
|
self.router_exit_event: ms.Event
|
136
|
-
self.router_exit_event =
|
137
|
-
|
138
|
-
self.
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
self.zmq_router_proc.start()
|
151
|
-
|
152
|
-
self.udp_router_proc = ForkProcess(target=udp_router_starter,
|
153
|
-
kwargs={"comm_q": udp_comm_q,
|
154
|
-
"resource_msgs": self.resource_msgs,
|
155
|
-
"exit_event": self.router_exit_event,
|
156
|
-
"hub_address": self.hub_address,
|
157
|
-
"udp_port": self.hub_port,
|
158
|
-
"run_dir": dfk_run_dir,
|
159
|
-
"logging_level": logging.DEBUG if self.monitoring_debug else logging.INFO,
|
160
|
-
},
|
161
|
-
name="Monitoring-UDP-Router-Process",
|
162
|
-
daemon=True,
|
163
|
-
)
|
142
|
+
self.router_exit_event = SpawnEvent()
|
143
|
+
|
144
|
+
self.udp_router_proc = SpawnProcess(target=udp_router_starter,
|
145
|
+
kwargs={"comm_q": udp_comm_q,
|
146
|
+
"resource_msgs": self.resource_msgs,
|
147
|
+
"exit_event": self.router_exit_event,
|
148
|
+
"hub_address": self.hub_address,
|
149
|
+
"udp_port": self.hub_port,
|
150
|
+
"run_dir": dfk_run_dir,
|
151
|
+
"logging_level": logging.DEBUG if self.monitoring_debug else logging.INFO,
|
152
|
+
},
|
153
|
+
name="Monitoring-UDP-Router-Process",
|
154
|
+
daemon=True,
|
155
|
+
)
|
164
156
|
self.udp_router_proc.start()
|
165
157
|
|
166
158
|
self.dbm_exit_event: ms.Event
|
167
|
-
self.dbm_exit_event =
|
168
|
-
|
169
|
-
self.dbm_proc =
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
159
|
+
self.dbm_exit_event = SpawnEvent()
|
160
|
+
|
161
|
+
self.dbm_proc = SpawnProcess(target=dbm_starter,
|
162
|
+
args=(self.resource_msgs,),
|
163
|
+
kwargs={"run_dir": dfk_run_dir,
|
164
|
+
"logging_level": logging.DEBUG if self.monitoring_debug else logging.INFO,
|
165
|
+
"db_url": self.logging_endpoint,
|
166
|
+
"exit_event": self.dbm_exit_event,
|
167
|
+
},
|
168
|
+
name="Monitoring-DBM-Process",
|
169
|
+
daemon=True,
|
170
|
+
)
|
179
171
|
self.dbm_proc.start()
|
180
|
-
logger.info("Started
|
181
|
-
self.
|
182
|
-
|
183
|
-
self.filesystem_proc =
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
172
|
+
logger.info("Started UDP router process %s and DBM process %s",
|
173
|
+
self.udp_router_proc.pid, self.dbm_proc.pid)
|
174
|
+
|
175
|
+
self.filesystem_proc = SpawnProcess(target=filesystem_router_starter,
|
176
|
+
args=(self.resource_msgs, dfk_run_dir, self.router_exit_event),
|
177
|
+
name="Monitoring-Filesystem-Process",
|
178
|
+
daemon=True
|
179
|
+
)
|
188
180
|
self.filesystem_proc.start()
|
189
181
|
logger.info("Started filesystem radio receiver process %s", self.filesystem_proc.pid)
|
190
182
|
|
191
183
|
self.radio = MultiprocessingQueueRadioSender(self.resource_msgs)
|
192
184
|
|
193
|
-
try:
|
194
|
-
zmq_comm_q_result = zmq_comm_q.get(block=True, timeout=120)
|
195
|
-
zmq_comm_q.close()
|
196
|
-
zmq_comm_q.join_thread()
|
197
|
-
except queue.Empty:
|
198
|
-
logger.error("Monitoring ZMQ Router has not reported port in 120s. Aborting")
|
199
|
-
raise MonitoringHubStartError()
|
200
|
-
|
201
|
-
if isinstance(zmq_comm_q_result, str):
|
202
|
-
logger.error("MonitoringRouter sent an error message: %s", zmq_comm_q_result)
|
203
|
-
raise RuntimeError(f"MonitoringRouter failed to start: {zmq_comm_q_result}")
|
204
|
-
|
205
|
-
self.hub_zmq_port = zmq_comm_q_result
|
206
|
-
|
207
185
|
try:
|
208
186
|
udp_comm_q_result = udp_comm_q.get(block=True, timeout=120)
|
209
187
|
udp_comm_q.close()
|
@@ -232,9 +210,6 @@ class MonitoringHub(RepresentationMixin):
|
|
232
210
|
logger.info("Setting router termination event")
|
233
211
|
self.router_exit_event.set()
|
234
212
|
|
235
|
-
logger.info("Waiting for ZMQ router to terminate")
|
236
|
-
join_terminate_close_proc(self.zmq_router_proc)
|
237
|
-
|
238
213
|
logger.info("Waiting for UDP router to terminate")
|
239
214
|
join_terminate_close_proc(self.udp_router_proc)
|
240
215
|
|
@@ -251,38 +226,3 @@ class MonitoringHub(RepresentationMixin):
|
|
251
226
|
self.resource_msgs.close()
|
252
227
|
self.resource_msgs.join_thread()
|
253
228
|
logger.info("Closed monitoring multiprocessing queues")
|
254
|
-
|
255
|
-
|
256
|
-
def join_terminate_close_proc(process: ForkProcessType, *, timeout: int = 30) -> None:
|
257
|
-
"""Increasingly aggressively terminate a process.
|
258
|
-
|
259
|
-
This function assumes that the process is likely to exit before
|
260
|
-
the join timeout, driven by some other means, such as the
|
261
|
-
MonitoringHub router_exit_event. If the process does not exit, then
|
262
|
-
first terminate() and then kill() will be used to end the process.
|
263
|
-
|
264
|
-
In the case of a very mis-behaving process, this function might take
|
265
|
-
up to 3*timeout to exhaust all termination methods and return.
|
266
|
-
"""
|
267
|
-
logger.debug("Joining process")
|
268
|
-
process.join(timeout)
|
269
|
-
|
270
|
-
# run a sequence of increasingly aggressive steps to shut down the process.
|
271
|
-
if process.is_alive():
|
272
|
-
logger.error("Process did not join. Terminating.")
|
273
|
-
process.terminate()
|
274
|
-
process.join(timeout)
|
275
|
-
if process.is_alive():
|
276
|
-
logger.error("Process did not join after terminate. Killing.")
|
277
|
-
process.kill()
|
278
|
-
process.join(timeout)
|
279
|
-
# This kill should not be caught by any signal handlers so it is
|
280
|
-
# unlikely that this join will timeout. If it does, there isn't
|
281
|
-
# anything further to do except log an error in the next if-block.
|
282
|
-
|
283
|
-
if process.is_alive():
|
284
|
-
logger.error("Process failed to end")
|
285
|
-
# don't call close if the process hasn't ended:
|
286
|
-
# process.close() doesn't work on a running process.
|
287
|
-
else:
|
288
|
-
process.close()
|
@@ -3,16 +3,27 @@ from __future__ import annotations
|
|
3
3
|
import logging
|
4
4
|
import multiprocessing.queues as mpq
|
5
5
|
import os
|
6
|
+
import queue
|
6
7
|
import time
|
7
|
-
from multiprocessing.
|
8
|
+
from multiprocessing.context import SpawnProcess as SpawnProcessType
|
9
|
+
from multiprocessing.queues import Queue as QueueType
|
10
|
+
from multiprocessing.synchronize import Event as EventType
|
8
11
|
from typing import Tuple
|
9
12
|
|
10
13
|
import typeguard
|
11
14
|
import zmq
|
12
15
|
|
16
|
+
from parsl.addresses import tcp_url
|
13
17
|
from parsl.log_utils import set_file_logger
|
18
|
+
from parsl.monitoring.errors import MonitoringRouterStartError
|
14
19
|
from parsl.monitoring.radios.multiprocessing import MultiprocessingQueueRadioSender
|
15
20
|
from parsl.monitoring.types import TaggedMonitoringMessage
|
21
|
+
from parsl.multiprocessing import (
|
22
|
+
SizedQueue,
|
23
|
+
SpawnEvent,
|
24
|
+
SpawnProcess,
|
25
|
+
join_terminate_close_proc,
|
26
|
+
)
|
16
27
|
from parsl.process_loggers import wrap_with_logs
|
17
28
|
from parsl.utils import setproctitle
|
18
29
|
|
@@ -23,21 +34,21 @@ class MonitoringRouter:
|
|
23
34
|
|
24
35
|
def __init__(self,
|
25
36
|
*,
|
26
|
-
|
27
|
-
|
37
|
+
address: str,
|
38
|
+
port_range: Tuple[int, int] = (55050, 56000),
|
28
39
|
|
29
40
|
run_dir: str = ".",
|
30
41
|
logging_level: int = logging.INFO,
|
31
42
|
resource_msgs: mpq.Queue,
|
32
|
-
exit_event:
|
43
|
+
exit_event: EventType,
|
33
44
|
):
|
34
45
|
""" Initializes a monitoring configuration class.
|
35
46
|
|
36
47
|
Parameters
|
37
48
|
----------
|
38
|
-
|
49
|
+
address : str
|
39
50
|
The ip address at which the workers will be able to reach the Hub.
|
40
|
-
|
51
|
+
port_range : tuple(int, int)
|
41
52
|
The MonitoringHub picks ports at random from the range which will be used by Hub.
|
42
53
|
Default: (55050, 56000)
|
43
54
|
run_dir : str
|
@@ -51,11 +62,11 @@ class MonitoringRouter:
|
|
51
62
|
"""
|
52
63
|
os.makedirs(run_dir, exist_ok=True)
|
53
64
|
self.logger = set_file_logger(f"{run_dir}/monitoring_zmq_router.log",
|
54
|
-
name="
|
65
|
+
name="zmq_monitoring_router",
|
55
66
|
level=logging_level)
|
56
67
|
self.logger.debug("Monitoring router starting")
|
57
68
|
|
58
|
-
self.
|
69
|
+
self.address = address
|
59
70
|
|
60
71
|
self.loop_freq = 10.0 # milliseconds
|
61
72
|
|
@@ -64,15 +75,15 @@ class MonitoringRouter:
|
|
64
75
|
self.zmq_receiver_channel.setsockopt(zmq.LINGER, 0)
|
65
76
|
self.zmq_receiver_channel.set_hwm(0)
|
66
77
|
self.zmq_receiver_channel.RCVTIMEO = int(self.loop_freq) # in milliseconds
|
67
|
-
self.logger.debug("
|
68
|
-
self.zmq_receiver_port = self.zmq_receiver_channel.bind_to_random_port(
|
69
|
-
min_port=
|
70
|
-
max_port=
|
78
|
+
self.logger.debug("address: {}. port_range {}".format(address, port_range))
|
79
|
+
self.zmq_receiver_port = self.zmq_receiver_channel.bind_to_random_port(tcp_url(address),
|
80
|
+
min_port=port_range[0],
|
81
|
+
max_port=port_range[1])
|
71
82
|
|
72
83
|
self.target_radio = MultiprocessingQueueRadioSender(resource_msgs)
|
73
84
|
self.exit_event = exit_event
|
74
85
|
|
75
|
-
@wrap_with_logs(target="
|
86
|
+
@wrap_with_logs(target="zmq_monitoring_router")
|
76
87
|
def start(self) -> None:
|
77
88
|
self.logger.info("Starting ZMQ listener")
|
78
89
|
try:
|
@@ -108,17 +119,17 @@ class MonitoringRouter:
|
|
108
119
|
def zmq_router_starter(*,
|
109
120
|
comm_q: mpq.Queue,
|
110
121
|
resource_msgs: mpq.Queue,
|
111
|
-
exit_event:
|
122
|
+
exit_event: EventType,
|
112
123
|
|
113
|
-
|
114
|
-
|
124
|
+
address: str,
|
125
|
+
port_range: Tuple[int, int],
|
115
126
|
|
116
127
|
run_dir: str,
|
117
128
|
logging_level: int) -> None:
|
118
129
|
setproctitle("parsl: monitoring zmq router")
|
119
130
|
try:
|
120
|
-
router = MonitoringRouter(
|
121
|
-
|
131
|
+
router = MonitoringRouter(address=address,
|
132
|
+
port_range=port_range,
|
122
133
|
run_dir=run_dir,
|
123
134
|
logging_level=logging_level,
|
124
135
|
resource_msgs=resource_msgs,
|
@@ -129,3 +140,54 @@ def zmq_router_starter(*,
|
|
129
140
|
else:
|
130
141
|
comm_q.put(router.zmq_receiver_port)
|
131
142
|
router.start()
|
143
|
+
|
144
|
+
|
145
|
+
class ZMQRadioReceiver():
|
146
|
+
def __init__(self, *, process: SpawnProcessType, exit_event: EventType, port: int) -> None:
|
147
|
+
self.process = process
|
148
|
+
self.exit_event = exit_event
|
149
|
+
self.port = port
|
150
|
+
|
151
|
+
def close(self) -> None:
|
152
|
+
self.exit_event.set()
|
153
|
+
join_terminate_close_proc(self.process)
|
154
|
+
|
155
|
+
|
156
|
+
def start_zmq_receiver(*,
|
157
|
+
monitoring_messages: QueueType,
|
158
|
+
loopback_address: str,
|
159
|
+
port_range: Tuple[int, int],
|
160
|
+
logdir: str,
|
161
|
+
worker_debug: bool) -> ZMQRadioReceiver:
|
162
|
+
comm_q = SizedQueue(maxsize=10)
|
163
|
+
|
164
|
+
router_exit_event = SpawnEvent()
|
165
|
+
|
166
|
+
router_proc = SpawnProcess(target=zmq_router_starter,
|
167
|
+
kwargs={"comm_q": comm_q,
|
168
|
+
"resource_msgs": monitoring_messages,
|
169
|
+
"exit_event": router_exit_event,
|
170
|
+
"address": loopback_address,
|
171
|
+
"port_range": port_range,
|
172
|
+
"run_dir": logdir,
|
173
|
+
"logging_level": logging.DEBUG if worker_debug else logging.INFO,
|
174
|
+
},
|
175
|
+
name="Monitoring-ZMQ-Router-Process",
|
176
|
+
daemon=True,
|
177
|
+
)
|
178
|
+
router_proc.start()
|
179
|
+
|
180
|
+
try:
|
181
|
+
logger.debug("Waiting for router process to report port")
|
182
|
+
comm_q_result = comm_q.get(block=True, timeout=120)
|
183
|
+
comm_q.close()
|
184
|
+
comm_q.join_thread()
|
185
|
+
except queue.Empty:
|
186
|
+
logger.error("Monitoring ZMQ Router has not reported port in 120s")
|
187
|
+
raise MonitoringRouterStartError()
|
188
|
+
|
189
|
+
if isinstance(comm_q_result, str):
|
190
|
+
logger.error("MonitoringRouter sent an error message: %s", comm_q_result)
|
191
|
+
raise RuntimeError(f"MonitoringRouter failed to start: {comm_q_result}")
|
192
|
+
|
193
|
+
return ZMQRadioReceiver(process=router_proc, exit_event=router_exit_event, port=comm_q_result)
|