parsl 2024.7.29__tar.gz → 2024.8.12__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.7.29/parsl.egg-info → parsl-2024.8.12}/PKG-INFO +2 -2
- parsl-2024.8.12/parsl/channels/__init__.py +4 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/channels/oauth_ssh/oauth_ssh.py +2 -2
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/channels/ssh/ssh.py +1 -1
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/channels/ssh_il/ssh_il.py +2 -2
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/dataflow/dflow.py +2 -2
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/base.py +7 -7
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/high_throughput/executor.py +15 -7
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/high_throughput/interchange.py +40 -37
- parsl-2024.8.12/parsl/executors/high_throughput/manager_selector.py +25 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/status_handling.py +38 -24
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/taskvine/executor.py +2 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/workqueue/executor.py +2 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/db_manager.py +10 -10
- parsl-2024.8.12/parsl/monitoring/errors.py +6 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/monitoring.py +3 -3
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/radios.py +16 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/remote.py +4 -4
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/router.py +71 -35
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/__init__.py +0 -4
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/ad_hoc/ad_hoc.py +6 -2
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/local_adhoc.py +2 -2
- parsl-2024.8.12/parsl/tests/test_htex/test_disconnected_blocks_failing_provider.py +71 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_htex/test_htex.py +28 -19
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_htex/test_zmq_binding.py +4 -1
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_monitoring/test_basic.py +14 -1
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_mpi_apps/test_mpiex.py +1 -1
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_providers/test_local_provider.py +6 -5
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/version.py +1 -1
- {parsl-2024.7.29 → parsl-2024.8.12/parsl.egg-info}/PKG-INFO +2 -2
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl.egg-info/SOURCES.txt +3 -11
- parsl-2024.7.29/parsl/channels/__init__.py +0 -7
- parsl-2024.7.29/parsl/configs/ad_hoc.py +0 -38
- parsl-2024.7.29/parsl/tests/configs/ad_hoc_cluster_htex.py +0 -35
- parsl-2024.7.29/parsl/tests/configs/htex_ad_hoc_cluster.py +0 -26
- parsl-2024.7.29/parsl/tests/configs/swan_htex.py +0 -43
- parsl-2024.7.29/parsl/tests/integration/test_channels/test_scp_1.py +0 -45
- parsl-2024.7.29/parsl/tests/integration/test_channels/test_ssh_1.py +0 -40
- parsl-2024.7.29/parsl/tests/integration/test_channels/test_ssh_errors.py +0 -46
- parsl-2024.7.29/parsl/tests/integration/test_channels/test_ssh_file_transport.py +0 -41
- parsl-2024.7.29/parsl/tests/integration/test_channels/test_ssh_interactive.py +0 -24
- parsl-2024.7.29/parsl/tests/manual_tests/test_ad_hoc_htex.py +0 -49
- parsl-2024.7.29/parsl/tests/manual_tests/test_oauth_ssh.py +0 -13
- {parsl-2024.7.29 → parsl-2024.8.12}/LICENSE +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/MANIFEST.in +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/README.rst +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/addresses.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/app/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/app/app.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/app/bash.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/app/errors.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/app/futures.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/app/python.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/benchmark/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/benchmark/perf.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/channels/base.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/channels/errors.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/channels/local/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/channels/local/local.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/channels/oauth_ssh/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/channels/ssh/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/channels/ssh_il/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/concurrent/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/config.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/configs/ASPIRE1.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/configs/Azure.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/configs/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/configs/bridges.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/configs/cc_in2p3.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/configs/ec2.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/configs/expanse.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/configs/frontera.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/configs/htex_local.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/configs/illinoiscluster.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/configs/kubernetes.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/configs/local_threads.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/configs/midway.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/configs/osg.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/configs/polaris.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/configs/stampede2.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/configs/summit.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/configs/toss3_llnl.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/configs/vineex_local.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/configs/wqex_local.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/curvezmq.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/data_provider/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/data_provider/data_manager.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/data_provider/file_noop.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/data_provider/files.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/data_provider/ftp.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/data_provider/globus.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/data_provider/http.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/data_provider/rsync.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/data_provider/staging.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/data_provider/zip.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/dataflow/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/dataflow/dependency_resolvers.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/dataflow/errors.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/dataflow/futures.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/dataflow/memoization.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/dataflow/rundirs.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/dataflow/states.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/dataflow/taskrecord.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/errors.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/errors.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/flux/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/flux/execute_parsl_task.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/flux/executor.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/flux/flux_instance_manager.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/high_throughput/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/high_throughput/errors.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/high_throughput/manager_record.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/high_throughput/monitoring_info.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/high_throughput/mpi_executor.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/high_throughput/mpi_prefix_composer.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/high_throughput/mpi_resource_management.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/high_throughput/probe.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/high_throughput/process_worker_pool.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/high_throughput/zmq_pipes.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/radical/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/radical/executor.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/radical/rpex_resources.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/radical/rpex_worker.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/taskvine/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/taskvine/errors.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/taskvine/exec_parsl_function.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/taskvine/factory.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/taskvine/factory_config.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/taskvine/manager.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/taskvine/manager_config.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/taskvine/utils.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/threads.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/workqueue/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/workqueue/errors.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/workqueue/exec_parsl_function.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/workqueue/parsl_coprocess.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/executors/workqueue/parsl_coprocess_stub.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/jobs/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/jobs/error_handlers.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/jobs/errors.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/jobs/job_status_poller.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/jobs/states.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/jobs/strategy.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/launchers/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/launchers/base.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/launchers/errors.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/launchers/launchers.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/log_utils.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/message_type.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/queries/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/queries/pandas.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/types.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/visualization/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/visualization/app.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/visualization/models.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/visualization/plots/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/visualization/plots/default/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/visualization/plots/default/task_plots.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/visualization/plots/default/workflow_plots.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/visualization/plots/default/workflow_resource_plots.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/visualization/static/parsl-logo-white.png +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/visualization/static/parsl-monitor.css +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/visualization/templates/app.html +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/visualization/templates/dag.html +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/visualization/templates/error.html +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/visualization/templates/layout.html +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/visualization/templates/resource_usage.html +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/visualization/templates/task.html +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/visualization/templates/workflow.html +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/visualization/templates/workflows_summary.html +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/visualization/utils.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/visualization/version.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/monitoring/visualization/views.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/multiprocessing.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/process_loggers.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/ad_hoc/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/aws/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/aws/aws.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/aws/template.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/azure/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/azure/azure.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/azure/template.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/base.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/cluster_provider.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/cobalt/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/cobalt/cobalt.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/cobalt/template.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/condor/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/condor/condor.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/condor/template.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/errors.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/googlecloud/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/googlecloud/googlecloud.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/grid_engine/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/grid_engine/grid_engine.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/grid_engine/template.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/kubernetes/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/kubernetes/kube.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/kubernetes/template.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/local/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/local/local.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/lsf/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/lsf/lsf.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/lsf/template.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/pbspro/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/pbspro/pbspro.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/pbspro/template.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/slurm/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/slurm/slurm.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/slurm/template.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/torque/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/torque/template.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/providers/torque/torque.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/py.typed +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/serialize/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/serialize/base.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/serialize/concretes.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/serialize/errors.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/serialize/facade.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/serialize/proxystore.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/callables_helper.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/azure_single_node.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/bluewaters.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/bridges.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/cc_in2p3.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/comet.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/cooley_htex.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/ec2_single_node.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/ec2_spot.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/flux_local.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/frontera.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/htex_local.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/htex_local_alternate.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/htex_local_intask_staging.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/htex_local_rsync_staging.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/local_radical.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/local_radical_mpi.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/local_threads.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/local_threads_checkpoint.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/local_threads_checkpoint_dfk_exit.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/local_threads_checkpoint_periodic.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/local_threads_checkpoint_task_exit.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/local_threads_ftp_in_task.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/local_threads_globus.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/local_threads_http_in_task.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/local_threads_monitoring.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/local_threads_no_cache.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/midway.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/nscc_singapore.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/osg_htex.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/petrelkube.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/summit.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/taskvine_ex.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/theta.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/user_opts.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/configs/workqueue_ex.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/conftest.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/integration/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/integration/latency.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/integration/test_apps/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/integration/test_channels/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/integration/test_channels/test_channels.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/integration/test_channels/test_local_channel.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/integration/test_parsl_load_default_config.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/integration/test_stress/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/integration/test_stress/test_python_simple.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/integration/test_stress/test_python_threads.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/manual_tests/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/manual_tests/htex_local.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/manual_tests/test_basic.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/manual_tests/test_fan_in_out_htex_remote.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/manual_tests/test_log_filter.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/manual_tests/test_memory_limits.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/manual_tests/test_regression_220.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/manual_tests/test_udp_simple.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/manual_tests/test_worker_count.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/scaling_tests/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/scaling_tests/htex_local.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/scaling_tests/local_threads.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/scaling_tests/test_scale.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/scaling_tests/vineex_condor.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/scaling_tests/vineex_local.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/scaling_tests/wqex_condor.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/scaling_tests/wqex_local.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/site_tests/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/site_tests/site_config_selector.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/site_tests/test_provider.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/site_tests/test_site.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/sites/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/sites/test_affinity.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/sites/test_concurrent.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/sites/test_dynamic_executor.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/sites/test_ec2.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/sites/test_launchers.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/sites/test_local_adhoc.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/sites/test_mpi/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/sites/test_worker_info.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_aalst_patterns.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_bash_apps/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_bash_apps/test_apptimeout.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_bash_apps/test_basic.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_bash_apps/test_error_codes.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_bash_apps/test_inputs_default.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_bash_apps/test_keyword_overlaps.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_bash_apps/test_kwarg_storage.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_bash_apps/test_memoize.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_bash_apps/test_memoize_ignore_args.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_bash_apps/test_memoize_ignore_args_regr.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_bash_apps/test_multiline.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_bash_apps/test_pipeline.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_bash_apps/test_std_uri.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_bash_apps/test_stdout.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_callables.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_channels/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_channels/test_dfk_close.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_channels/test_large_output.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_checkpointing/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_checkpointing/test_periodic.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_checkpointing/test_python_checkpoint_1.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_checkpointing/test_python_checkpoint_2.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_checkpointing/test_python_checkpoint_3.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_checkpointing/test_regression_232.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_checkpointing/test_regression_233.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_checkpointing/test_regression_239.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_checkpointing/test_task_exit.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_curvezmq.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_docs/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_docs/test_from_slides.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_docs/test_kwargs.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_docs/test_tutorial_1.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_docs/test_workflow1.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_docs/test_workflow2.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_docs/test_workflow4.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_error_handling/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_error_handling/test_fail.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_error_handling/test_python_walltime.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_error_handling/test_rand_fail.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_error_handling/test_resource_spec.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_error_handling/test_retries.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_error_handling/test_retry_handler.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_error_handling/test_retry_handler_failure.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_error_handling/test_serialization_fail.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_error_handling/test_wrap_with_logs.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_flowcontrol/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_flux.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_htex/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_htex/test_basic.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_htex/test_command_client_timeout.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_htex/test_connected_blocks.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_htex/test_cpu_affinity_explicit.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_htex/test_disconnected_blocks.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_htex/test_drain.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_htex/test_manager_failure.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_htex/test_managers_command.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_htex/test_missing_worker.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_htex/test_multiple_disconnected_blocks.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_htex/test_worker_failure.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_monitoring/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_monitoring/test_app_names.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_monitoring/test_db_locks.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_monitoring/test_fuzz_zmq.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_monitoring/test_htex_init_blocks_vs_monitoring.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_monitoring/test_incomplete_futures.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_monitoring/test_memoization_representation.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_monitoring/test_stdouterr.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_monitoring/test_viz_colouring.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_mpi_apps/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_mpi_apps/test_bad_mpi_config.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_mpi_apps/test_mpi_mode_disabled.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_mpi_apps/test_mpi_mode_enabled.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_mpi_apps/test_mpi_prefix.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_mpi_apps/test_mpi_scheduler.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_mpi_apps/test_resource_spec.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_providers/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_providers/test_cobalt_deprecation_warning.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_providers/test_pbspro_template.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_providers/test_slurm_instantiate.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_providers/test_slurm_template.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_providers/test_submiterror_deprecation.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_arg_input_types.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_basic.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_context_manager.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_dep_standard_futures.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_dependencies.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_dependencies_deep.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_depfail_propagation.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_fail.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_fibonacci_iterative.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_fibonacci_recursive.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_futures.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_garbage_collect.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_import_fail.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_inputs_default.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_join.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_lifted.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_mapred.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_memoize_1.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_memoize_2.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_memoize_4.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_memoize_bad_id_for_memo.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_memoize_ignore_args.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_memoize_joinapp.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_outputs.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_overview.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_pipeline.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_pluggable_future_resolution.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_simple.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_timeout.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_python_apps/test_type5.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_radical/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_radical/test_mpi_funcs.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_regression/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_regression/test_1480.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_regression/test_1606_wait_for_current_tasks.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_regression/test_1653.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_regression/test_221.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_regression/test_226.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_regression/test_2652.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_regression/test_69a.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_regression/test_854.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_regression/test_97_parallelism_0.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_regression/test_98.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_scaling/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_scaling/test_block_error_handler.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_scaling/test_regression_1621.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_scaling/test_scale_down.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_scaling/test_scale_down_htex_auto_scale.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_scaling/test_scale_down_htex_unregistered.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_scaling/test_shutdown_scalein.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_serialization/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_serialization/test_2555_caching_deserializer.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_serialization/test_3495_deserialize_managerlost.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_serialization/test_basic.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_serialization/test_htex_code_cache.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_serialization/test_pack_resource_spec.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_serialization/test_proxystore_configured.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_serialization/test_proxystore_impl.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_shutdown/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_shutdown/test_kill_monitoring.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_staging/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_staging/staging_provider.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_staging/test_1316.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_staging/test_docs_1.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_staging/test_docs_2.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_staging/test_elaborate_noop_file.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_staging/test_file.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_staging/test_file_apps.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_staging/test_file_staging.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_staging/test_output_chain_filenames.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_staging/test_staging_ftp.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_staging/test_staging_ftp_in_task.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_staging/test_staging_globus.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_staging/test_staging_https.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_staging/test_staging_stdout.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_staging/test_zip_in.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_staging/test_zip_out.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_staging/test_zip_to_zip.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_summary.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_thread_parallelism.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_threads/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_threads/test_configs.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_threads/test_lazy_errors.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_utils/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/test_utils/test_representation_mixin.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/unit/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/unit/test_file.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/unit/test_usage_tracking.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/tests/utils.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/usage_tracking/__init__.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/usage_tracking/api.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/usage_tracking/levels.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/usage_tracking/usage.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl/utils.py +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl.egg-info/dependency_links.txt +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl.egg-info/entry_points.txt +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl.egg-info/requires.txt +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/parsl.egg-info/top_level.txt +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/requirements.txt +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/setup.cfg +0 -0
- {parsl-2024.7.29 → parsl-2024.8.12}/setup.py +0 -0
@@ -1,9 +1,9 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: parsl
|
3
|
-
Version: 2024.
|
3
|
+
Version: 2024.8.12
|
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.08.12.tar.gz
|
7
7
|
Author: The Parsl Team
|
8
8
|
Author-email: parsl@googlegroups.com
|
9
9
|
License: Apache 2.0
|
@@ -3,7 +3,7 @@ import socket
|
|
3
3
|
|
4
4
|
import paramiko
|
5
5
|
|
6
|
-
from parsl.channels.ssh.ssh import
|
6
|
+
from parsl.channels.ssh.ssh import DeprecatedSSHChannel
|
7
7
|
from parsl.errors import OptionalModuleMissing
|
8
8
|
|
9
9
|
try:
|
@@ -17,7 +17,7 @@ except (ImportError, NameError):
|
|
17
17
|
logger = logging.getLogger(__name__)
|
18
18
|
|
19
19
|
|
20
|
-
class
|
20
|
+
class DeprecatedOAuthSSHChannel(DeprecatedSSHChannel):
|
21
21
|
"""SSH persistent channel. This enables remote execution on sites
|
22
22
|
accessible via ssh. This channel uses Globus based OAuth tokens for authentication.
|
23
23
|
"""
|
@@ -24,7 +24,7 @@ class NoAuthSSHClient(paramiko.SSHClient):
|
|
24
24
|
return
|
25
25
|
|
26
26
|
|
27
|
-
class
|
27
|
+
class DeprecatedSSHChannel(Channel, RepresentationMixin):
|
28
28
|
''' SSH persistent channel. This enables remote execution on sites
|
29
29
|
accessible via ssh. It is assumed that the user has setup host keys
|
30
30
|
so as to ssh to the remote host. Which goes to say that the following
|
@@ -3,12 +3,12 @@ import logging
|
|
3
3
|
|
4
4
|
import paramiko
|
5
5
|
|
6
|
-
from parsl.channels.ssh.ssh import
|
6
|
+
from parsl.channels.ssh.ssh import DeprecatedSSHChannel
|
7
7
|
|
8
8
|
logger = logging.getLogger(__name__)
|
9
9
|
|
10
10
|
|
11
|
-
class
|
11
|
+
class DeprecatedSSHInteractiveLoginChannel(DeprecatedSSHChannel):
|
12
12
|
"""SSH persistent channel. This enables remote execution on sites
|
13
13
|
accessible via ssh. This channel supports interactive login and is appropriate when
|
14
14
|
keys are not set up.
|
@@ -116,7 +116,7 @@ class DataFlowKernel:
|
|
116
116
|
if self.monitoring:
|
117
117
|
if self.monitoring.logdir is None:
|
118
118
|
self.monitoring.logdir = self.run_dir
|
119
|
-
self.monitoring.start(self.
|
119
|
+
self.monitoring.start(self.run_dir, self.config.run_dir)
|
120
120
|
|
121
121
|
self.time_began = datetime.datetime.now()
|
122
122
|
self.time_completed: Optional[datetime.datetime] = None
|
@@ -1180,7 +1180,7 @@ class DataFlowKernel:
|
|
1180
1180
|
if self.monitoring:
|
1181
1181
|
executor.hub_address = self.monitoring.hub_address
|
1182
1182
|
executor.hub_zmq_port = self.monitoring.hub_zmq_port
|
1183
|
-
executor.
|
1183
|
+
executor.submit_monitoring_radio = self.monitoring.radio
|
1184
1184
|
if hasattr(executor, 'provider'):
|
1185
1185
|
if hasattr(executor.provider, 'script_dir'):
|
1186
1186
|
executor.provider.script_dir = os.path.join(self.run_dir, 'submit_scripts')
|
@@ -52,13 +52,13 @@ class ParslExecutor(metaclass=ABCMeta):
|
|
52
52
|
*,
|
53
53
|
hub_address: Optional[str] = None,
|
54
54
|
hub_zmq_port: Optional[int] = None,
|
55
|
-
|
55
|
+
submit_monitoring_radio: Optional[MonitoringRadioSender] = None,
|
56
56
|
run_dir: str = ".",
|
57
57
|
run_id: Optional[str] = None,
|
58
58
|
):
|
59
59
|
self.hub_address = hub_address
|
60
60
|
self.hub_zmq_port = hub_zmq_port
|
61
|
-
self.
|
61
|
+
self.submit_monitoring_radio = submit_monitoring_radio
|
62
62
|
self.run_dir = os.path.abspath(run_dir)
|
63
63
|
self.run_id = run_id
|
64
64
|
|
@@ -147,11 +147,11 @@ class ParslExecutor(metaclass=ABCMeta):
|
|
147
147
|
self._hub_zmq_port = value
|
148
148
|
|
149
149
|
@property
|
150
|
-
def
|
150
|
+
def submit_monitoring_radio(self) -> Optional[MonitoringRadioSender]:
|
151
151
|
"""Local radio for sending monitoring messages
|
152
152
|
"""
|
153
|
-
return self.
|
153
|
+
return self._submit_monitoring_radio
|
154
154
|
|
155
|
-
@
|
156
|
-
def
|
157
|
-
self.
|
155
|
+
@submit_monitoring_radio.setter
|
156
|
+
def submit_monitoring_radio(self, value: Optional[MonitoringRadioSender]) -> None:
|
157
|
+
self._submit_monitoring_radio = value
|
@@ -20,6 +20,10 @@ from parsl.data_provider.staging import Staging
|
|
20
20
|
from parsl.executors.errors import BadMessage, ScalingFailed
|
21
21
|
from parsl.executors.high_throughput import zmq_pipes
|
22
22
|
from parsl.executors.high_throughput.errors import CommandClientTimeoutError
|
23
|
+
from parsl.executors.high_throughput.manager_selector import (
|
24
|
+
ManagerSelector,
|
25
|
+
RandomManagerSelector,
|
26
|
+
)
|
23
27
|
from parsl.executors.high_throughput.mpi_prefix_composer import (
|
24
28
|
VALID_LAUNCHERS,
|
25
29
|
validate_resource_spec,
|
@@ -56,7 +60,7 @@ DEFAULT_LAUNCH_CMD = ("process_worker_pool.py {debug} {max_workers_per_node} "
|
|
56
60
|
"--mpi-launcher={mpi_launcher} "
|
57
61
|
"--available-accelerators {accelerators}")
|
58
62
|
|
59
|
-
DEFAULT_INTERCHANGE_LAUNCH_CMD = "interchange.py"
|
63
|
+
DEFAULT_INTERCHANGE_LAUNCH_CMD = ["interchange.py"]
|
60
64
|
|
61
65
|
GENERAL_HTEX_PARAM_DOCS = """provider : :class:`~parsl.providers.base.ExecutionProvider`
|
62
66
|
Provider to access computation resources. Can be one of :class:`~parsl.providers.aws.aws.EC2Provider`,
|
@@ -78,9 +82,9 @@ GENERAL_HTEX_PARAM_DOCS = """provider : :class:`~parsl.providers.base.ExecutionP
|
|
78
82
|
cores_per_worker, nodes_per_block, heartbeat_period ,heartbeat_threshold, logdir). For example:
|
79
83
|
launch_cmd="process_worker_pool.py {debug} -c {cores_per_worker} --task_url={task_url} --result_url={result_url}"
|
80
84
|
|
81
|
-
interchange_launch_cmd : str
|
82
|
-
Custom command line
|
83
|
-
the executor will use the default "interchange.py" command.
|
85
|
+
interchange_launch_cmd : Sequence[str]
|
86
|
+
Custom sequence of command line tokens to launch the interchange process from the executor. If
|
87
|
+
undefined, the executor will use the default "interchange.py" command.
|
84
88
|
|
85
89
|
address : string
|
86
90
|
An address to connect to the main Parsl process which is reachable from the network in which
|
@@ -238,7 +242,7 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin, UsageIn
|
|
238
242
|
label: str = 'HighThroughputExecutor',
|
239
243
|
provider: ExecutionProvider = LocalProvider(),
|
240
244
|
launch_cmd: Optional[str] = None,
|
241
|
-
interchange_launch_cmd: Optional[str] = None,
|
245
|
+
interchange_launch_cmd: Optional[Sequence[str]] = None,
|
242
246
|
address: Optional[str] = None,
|
243
247
|
worker_ports: Optional[Tuple[int, int]] = None,
|
244
248
|
worker_port_range: Optional[Tuple[int, int]] = (54000, 55000),
|
@@ -261,6 +265,7 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin, UsageIn
|
|
261
265
|
worker_logdir_root: Optional[str] = None,
|
262
266
|
enable_mpi_mode: bool = False,
|
263
267
|
mpi_launcher: str = "mpiexec",
|
268
|
+
manager_selector: ManagerSelector = RandomManagerSelector(),
|
264
269
|
block_error_handler: Union[bool, Callable[[BlockProviderExecutor, Dict[str, JobStatus]], None]] = True,
|
265
270
|
encrypted: bool = False):
|
266
271
|
|
@@ -276,6 +281,7 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin, UsageIn
|
|
276
281
|
self.prefetch_capacity = prefetch_capacity
|
277
282
|
self.address = address
|
278
283
|
self.address_probe_timeout = address_probe_timeout
|
284
|
+
self.manager_selector = manager_selector
|
279
285
|
if self.address:
|
280
286
|
self.all_addresses = address
|
281
287
|
else:
|
@@ -544,11 +550,13 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin, UsageIn
|
|
544
550
|
"poll_period": self.poll_period,
|
545
551
|
"logging_level": logging.DEBUG if self.worker_debug else logging.INFO,
|
546
552
|
"cert_dir": self.cert_dir,
|
553
|
+
"manager_selector": self.manager_selector,
|
554
|
+
"run_id": self.run_id,
|
547
555
|
}
|
548
556
|
|
549
557
|
config_pickle = pickle.dumps(interchange_config)
|
550
558
|
|
551
|
-
self.interchange_proc = subprocess.Popen(self.interchange_launch_cmd
|
559
|
+
self.interchange_proc = subprocess.Popen(self.interchange_launch_cmd, stdin=subprocess.PIPE)
|
552
560
|
stdin = self.interchange_proc.stdin
|
553
561
|
assert stdin is not None, "Popen should have created an IO object (vs default None) because of PIPE mode"
|
554
562
|
|
@@ -824,7 +832,7 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin, UsageIn
|
|
824
832
|
try:
|
825
833
|
self.interchange_proc.wait(timeout=timeout)
|
826
834
|
except subprocess.TimeoutExpired:
|
827
|
-
logger.
|
835
|
+
logger.warning("Unable to terminate Interchange process; sending SIGKILL")
|
828
836
|
self.interchange_proc.kill()
|
829
837
|
|
830
838
|
logger.info("Closing ZMQ pipes")
|
@@ -6,7 +6,6 @@ import os
|
|
6
6
|
import pickle
|
7
7
|
import platform
|
8
8
|
import queue
|
9
|
-
import random
|
10
9
|
import signal
|
11
10
|
import sys
|
12
11
|
import threading
|
@@ -19,7 +18,9 @@ from parsl import curvezmq
|
|
19
18
|
from parsl.app.errors import RemoteExceptionWrapper
|
20
19
|
from parsl.executors.high_throughput.errors import ManagerLost, VersionMismatch
|
21
20
|
from parsl.executors.high_throughput.manager_record import ManagerRecord
|
21
|
+
from parsl.executors.high_throughput.manager_selector import ManagerSelector
|
22
22
|
from parsl.monitoring.message_type import MessageType
|
23
|
+
from parsl.monitoring.radios import MonitoringRadioSender, ZMQRadioSender
|
23
24
|
from parsl.process_loggers import wrap_with_logs
|
24
25
|
from parsl.serialize import serialize as serialize_object
|
25
26
|
from parsl.utils import setproctitle
|
@@ -53,6 +54,8 @@ class Interchange:
|
|
53
54
|
logging_level: int,
|
54
55
|
poll_period: int,
|
55
56
|
cert_dir: Optional[str],
|
57
|
+
manager_selector: ManagerSelector,
|
58
|
+
run_id: str,
|
56
59
|
) -> None:
|
57
60
|
"""
|
58
61
|
Parameters
|
@@ -123,6 +126,8 @@ class Interchange:
|
|
123
126
|
self.command_channel.connect("tcp://{}:{}".format(client_address, client_ports[2]))
|
124
127
|
logger.info("Connected to client")
|
125
128
|
|
129
|
+
self.run_id = run_id
|
130
|
+
|
126
131
|
self.hub_address = hub_address
|
127
132
|
self.hub_zmq_port = hub_zmq_port
|
128
133
|
|
@@ -160,6 +165,8 @@ class Interchange:
|
|
160
165
|
|
161
166
|
self.heartbeat_threshold = heartbeat_threshold
|
162
167
|
|
168
|
+
self.manager_selector = manager_selector
|
169
|
+
|
163
170
|
self.current_platform = {'parsl_v': PARSL_VERSION,
|
164
171
|
'python_v': "{}.{}.{}".format(sys.version_info.major,
|
165
172
|
sys.version_info.minor,
|
@@ -216,27 +223,16 @@ class Interchange:
|
|
216
223
|
task_counter += 1
|
217
224
|
logger.debug(f"Fetched {task_counter} tasks so far")
|
218
225
|
|
219
|
-
def
|
220
|
-
if
|
221
|
-
logger.info("Connecting to MonitoringHub")
|
222
|
-
# This is a one-off because monitoring is unencrypted
|
223
|
-
hub_channel = zmq.Context().socket(zmq.DEALER)
|
224
|
-
hub_channel.set_hwm(0)
|
225
|
-
hub_channel.connect("tcp://{}:{}".format(self.hub_address, self.hub_zmq_port))
|
226
|
-
logger.info("Connected to MonitoringHub")
|
227
|
-
return hub_channel
|
228
|
-
else:
|
229
|
-
return None
|
230
|
-
|
231
|
-
def _send_monitoring_info(self, hub_channel: Optional[zmq.Socket], manager: ManagerRecord) -> None:
|
232
|
-
if hub_channel:
|
226
|
+
def _send_monitoring_info(self, monitoring_radio: Optional[MonitoringRadioSender], manager: ManagerRecord) -> None:
|
227
|
+
if monitoring_radio:
|
233
228
|
logger.info("Sending message {} to MonitoringHub".format(manager))
|
234
229
|
|
235
230
|
d: Dict = cast(Dict, manager.copy())
|
236
231
|
d['timestamp'] = datetime.datetime.now()
|
237
232
|
d['last_heartbeat'] = datetime.datetime.fromtimestamp(d['last_heartbeat'])
|
233
|
+
d['run_id'] = self.run_id
|
238
234
|
|
239
|
-
|
235
|
+
monitoring_radio.send((MessageType.NODE_INFO, d))
|
240
236
|
|
241
237
|
@wrap_with_logs(target="interchange")
|
242
238
|
def _command_server(self) -> NoReturn:
|
@@ -244,8 +240,11 @@ class Interchange:
|
|
244
240
|
"""
|
245
241
|
logger.debug("Command Server Starting")
|
246
242
|
|
247
|
-
|
248
|
-
|
243
|
+
if self.hub_address is not None and self.hub_zmq_port is not None:
|
244
|
+
logger.debug("Creating monitoring radio to %s:%s", self.hub_address, self.hub_zmq_port)
|
245
|
+
monitoring_radio = ZMQRadioSender(self.hub_address, self.hub_zmq_port)
|
246
|
+
else:
|
247
|
+
monitoring_radio = None
|
249
248
|
|
250
249
|
reply: Any # the type of reply depends on the command_req received (aka this needs dependent types...)
|
251
250
|
|
@@ -295,7 +294,7 @@ class Interchange:
|
|
295
294
|
if manager_id in self._ready_managers:
|
296
295
|
m = self._ready_managers[manager_id]
|
297
296
|
m['active'] = False
|
298
|
-
self._send_monitoring_info(
|
297
|
+
self._send_monitoring_info(monitoring_radio, m)
|
299
298
|
else:
|
300
299
|
logger.warning("Worker to hold was not in ready managers list")
|
301
300
|
|
@@ -330,9 +329,14 @@ class Interchange:
|
|
330
329
|
# parent-process-inheritance problems.
|
331
330
|
signal.signal(signal.SIGTERM, signal.SIG_DFL)
|
332
331
|
|
333
|
-
logger.info("
|
332
|
+
logger.info("Starting main interchange method")
|
334
333
|
|
335
|
-
|
334
|
+
if self.hub_address is not None and self.hub_zmq_port is not None:
|
335
|
+
logger.debug("Creating monitoring radio to %s:%s", self.hub_address, self.hub_zmq_port)
|
336
|
+
monitoring_radio = ZMQRadioSender(self.hub_address, self.hub_zmq_port)
|
337
|
+
logger.debug("Created monitoring radio")
|
338
|
+
else:
|
339
|
+
monitoring_radio = None
|
336
340
|
|
337
341
|
poll_period = self.poll_period
|
338
342
|
|
@@ -363,10 +367,10 @@ class Interchange:
|
|
363
367
|
while not kill_event.is_set():
|
364
368
|
self.socks = dict(poller.poll(timeout=poll_period))
|
365
369
|
|
366
|
-
self.process_task_outgoing_incoming(interesting_managers,
|
367
|
-
self.process_results_incoming(interesting_managers,
|
368
|
-
self.expire_bad_managers(interesting_managers,
|
369
|
-
self.expire_drained_managers(interesting_managers,
|
370
|
+
self.process_task_outgoing_incoming(interesting_managers, monitoring_radio, kill_event)
|
371
|
+
self.process_results_incoming(interesting_managers, monitoring_radio)
|
372
|
+
self.expire_bad_managers(interesting_managers, monitoring_radio)
|
373
|
+
self.expire_drained_managers(interesting_managers, monitoring_radio)
|
370
374
|
self.process_tasks_to_send(interesting_managers)
|
371
375
|
|
372
376
|
self.zmq_context.destroy()
|
@@ -377,7 +381,7 @@ class Interchange:
|
|
377
381
|
def process_task_outgoing_incoming(
|
378
382
|
self,
|
379
383
|
interesting_managers: Set[bytes],
|
380
|
-
|
384
|
+
monitoring_radio: Optional[MonitoringRadioSender],
|
381
385
|
kill_event: threading.Event
|
382
386
|
) -> None:
|
383
387
|
"""Process one message from manager on the task_outgoing channel.
|
@@ -431,7 +435,7 @@ class Interchange:
|
|
431
435
|
m.update(msg) # type: ignore[typeddict-item]
|
432
436
|
|
433
437
|
logger.info("Registration info for manager {!r}: {}".format(manager_id, msg))
|
434
|
-
self._send_monitoring_info(
|
438
|
+
self._send_monitoring_info(monitoring_radio, m)
|
435
439
|
|
436
440
|
if (msg['python_v'].rsplit(".", 1)[0] != self.current_platform['python_v'].rsplit(".", 1)[0] or
|
437
441
|
msg['parsl_v'] != self.current_platform['parsl_v']):
|
@@ -462,7 +466,7 @@ class Interchange:
|
|
462
466
|
logger.error(f"Unexpected message type received from manager: {msg['type']}")
|
463
467
|
logger.debug("leaving task_outgoing section")
|
464
468
|
|
465
|
-
def expire_drained_managers(self, interesting_managers: Set[bytes],
|
469
|
+
def expire_drained_managers(self, interesting_managers: Set[bytes], monitoring_radio: Optional[MonitoringRadioSender]) -> None:
|
466
470
|
|
467
471
|
for manager_id in list(interesting_managers):
|
468
472
|
# is it always true that a draining manager will be in interesting managers?
|
@@ -475,7 +479,7 @@ class Interchange:
|
|
475
479
|
self._ready_managers.pop(manager_id)
|
476
480
|
|
477
481
|
m['active'] = False
|
478
|
-
self._send_monitoring_info(
|
482
|
+
self._send_monitoring_info(monitoring_radio, m)
|
479
483
|
|
480
484
|
def process_tasks_to_send(self, interesting_managers: Set[bytes]) -> None:
|
481
485
|
# Check if there are tasks that could be sent to managers
|
@@ -485,8 +489,7 @@ class Interchange:
|
|
485
489
|
interesting=len(interesting_managers)))
|
486
490
|
|
487
491
|
if interesting_managers and not self.pending_task_queue.empty():
|
488
|
-
shuffled_managers =
|
489
|
-
random.shuffle(shuffled_managers)
|
492
|
+
shuffled_managers = self.manager_selector.sort_managers(self._ready_managers, interesting_managers)
|
490
493
|
|
491
494
|
while shuffled_managers and not self.pending_task_queue.empty(): # cf. the if statement above...
|
492
495
|
manager_id = shuffled_managers.pop()
|
@@ -519,7 +522,7 @@ class Interchange:
|
|
519
522
|
else:
|
520
523
|
logger.debug("either no interesting managers or no tasks, so skipping manager pass")
|
521
524
|
|
522
|
-
def process_results_incoming(self, interesting_managers: Set[bytes],
|
525
|
+
def process_results_incoming(self, interesting_managers: Set[bytes], monitoring_radio: Optional[MonitoringRadioSender]) -> None:
|
523
526
|
# Receive any results and forward to client
|
524
527
|
if self.results_incoming in self.socks and self.socks[self.results_incoming] == zmq.POLLIN:
|
525
528
|
logger.debug("entering results_incoming section")
|
@@ -539,11 +542,11 @@ class Interchange:
|
|
539
542
|
elif r['type'] == 'monitoring':
|
540
543
|
# the monitoring code makes the assumption that no
|
541
544
|
# monitoring messages will be received if monitoring
|
542
|
-
# is not configured, and that
|
545
|
+
# is not configured, and that monitoring_radio will only
|
543
546
|
# be None when monitoring is not configurated.
|
544
|
-
assert
|
547
|
+
assert monitoring_radio is not None
|
545
548
|
|
546
|
-
|
549
|
+
monitoring_radio.send(r['payload'])
|
547
550
|
elif r['type'] == 'heartbeat':
|
548
551
|
logger.debug(f"Manager {manager_id!r} sent heartbeat via results connection")
|
549
552
|
b_messages.append((p_message, r))
|
@@ -587,7 +590,7 @@ class Interchange:
|
|
587
590
|
interesting_managers.add(manager_id)
|
588
591
|
logger.debug("leaving results_incoming section")
|
589
592
|
|
590
|
-
def expire_bad_managers(self, interesting_managers: Set[bytes],
|
593
|
+
def expire_bad_managers(self, interesting_managers: Set[bytes], monitoring_radio: Optional[MonitoringRadioSender]) -> None:
|
591
594
|
bad_managers = [(manager_id, m) for (manager_id, m) in self._ready_managers.items() if
|
592
595
|
time.time() - m['last_heartbeat'] > self.heartbeat_threshold]
|
593
596
|
for (manager_id, m) in bad_managers:
|
@@ -595,7 +598,7 @@ class Interchange:
|
|
595
598
|
logger.warning(f"Too many heartbeats missed for manager {manager_id!r} - removing manager")
|
596
599
|
if m['active']:
|
597
600
|
m['active'] = False
|
598
|
-
self._send_monitoring_info(
|
601
|
+
self._send_monitoring_info(monitoring_radio, m)
|
599
602
|
|
600
603
|
logger.warning(f"Cancelling htex tasks {m['tasks']} on removed manager")
|
601
604
|
for tid in m['tasks']:
|
@@ -0,0 +1,25 @@
|
|
1
|
+
import random
|
2
|
+
from abc import ABCMeta, abstractmethod
|
3
|
+
from typing import Dict, List, Set
|
4
|
+
|
5
|
+
from parsl.executors.high_throughput.manager_record import ManagerRecord
|
6
|
+
|
7
|
+
|
8
|
+
class ManagerSelector(metaclass=ABCMeta):
|
9
|
+
|
10
|
+
@abstractmethod
|
11
|
+
def sort_managers(self, ready_managers: Dict[bytes, ManagerRecord], manager_list: Set[bytes]) -> List[bytes]:
|
12
|
+
""" Sort a given list of managers.
|
13
|
+
|
14
|
+
Any operations pertaining to the sorting and rearrangement of the
|
15
|
+
interesting_managers Set should be performed here.
|
16
|
+
"""
|
17
|
+
pass
|
18
|
+
|
19
|
+
|
20
|
+
class RandomManagerSelector(ManagerSelector):
|
21
|
+
|
22
|
+
def sort_managers(self, ready_managers: Dict[bytes, ManagerRecord], manager_list: Set[bytes]) -> List[bytes]:
|
23
|
+
c_manager_list = list(manager_list)
|
24
|
+
random.shuffle(c_manager_list)
|
25
|
+
return c_manager_list
|
@@ -12,7 +12,7 @@ from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union
|
|
12
12
|
from parsl.executors.base import ParslExecutor
|
13
13
|
from parsl.executors.errors import BadStateException, ScalingFailed
|
14
14
|
from parsl.jobs.error_handlers import noop_error_handler, simple_error_handler
|
15
|
-
from parsl.jobs.states import JobState, JobStatus
|
15
|
+
from parsl.jobs.states import TERMINAL_STATES, JobState, JobStatus
|
16
16
|
from parsl.monitoring.message_type import MessageType
|
17
17
|
from parsl.providers.base import ExecutionProvider
|
18
18
|
from parsl.utils import AtomicIDCounter
|
@@ -167,40 +167,50 @@ class BlockProviderExecutor(ParslExecutor):
|
|
167
167
|
def provider(self):
|
168
168
|
return self._provider
|
169
169
|
|
170
|
-
def _filter_scale_in_ids(self, to_kill, killed):
|
170
|
+
def _filter_scale_in_ids(self, to_kill: Sequence[Any], killed: Sequence[bool]) -> Sequence[Any]:
|
171
171
|
""" Filter out job id's that were not killed
|
172
172
|
"""
|
173
173
|
assert len(to_kill) == len(killed)
|
174
|
+
|
175
|
+
if False in killed:
|
176
|
+
killed_job_ids = [jid for jid, k in zip(to_kill, killed) if k]
|
177
|
+
not_killed_job_ids = [jid for jid, k in zip(to_kill, killed) if not k]
|
178
|
+
logger.warning("Some jobs were not killed successfully: "
|
179
|
+
f"killed jobs: {killed_job_ids}, "
|
180
|
+
f"not-killed jobs: {not_killed_job_ids}")
|
181
|
+
|
174
182
|
# Filters first iterable by bool values in second
|
175
183
|
return list(compress(to_kill, killed))
|
176
184
|
|
177
185
|
def scale_out_facade(self, n: int) -> List[str]:
|
178
|
-
block_ids = self._scale_out(n)
|
179
|
-
if block_ids is not None:
|
180
|
-
new_status = {}
|
181
|
-
for block_id in block_ids:
|
182
|
-
new_status[block_id] = JobStatus(JobState.PENDING)
|
183
|
-
self.send_monitoring_info(new_status)
|
184
|
-
self._status.update(new_status)
|
185
|
-
return block_ids
|
186
|
-
|
187
|
-
def _scale_out(self, blocks: int = 1) -> List[str]:
|
188
186
|
"""Scales out the number of blocks by "blocks"
|
189
187
|
"""
|
190
188
|
if not self.provider:
|
191
189
|
raise ScalingFailed(self, "No execution provider available")
|
192
190
|
block_ids = []
|
193
|
-
|
194
|
-
|
191
|
+
monitoring_status_changes = {}
|
192
|
+
logger.info(f"Scaling out by {n} blocks")
|
193
|
+
for _ in range(n):
|
195
194
|
block_id = str(self._block_id_counter.get_id())
|
196
195
|
logger.info(f"Allocated block ID {block_id}")
|
197
196
|
try:
|
198
197
|
job_id = self._launch_block(block_id)
|
198
|
+
|
199
|
+
pending_status = JobStatus(JobState.PENDING)
|
200
|
+
|
199
201
|
self.blocks_to_job_id[block_id] = job_id
|
200
202
|
self.job_ids_to_block[job_id] = block_id
|
203
|
+
self._status[block_id] = pending_status
|
204
|
+
|
205
|
+
monitoring_status_changes[block_id] = pending_status
|
201
206
|
block_ids.append(block_id)
|
207
|
+
|
202
208
|
except Exception as ex:
|
203
|
-
|
209
|
+
failed_status = JobStatus(JobState.FAILED, "Failed to start block {}: {}".format(block_id, ex))
|
210
|
+
self._simulated_status[block_id] = failed_status
|
211
|
+
self._status[block_id] = failed_status
|
212
|
+
|
213
|
+
self.send_monitoring_info(monitoring_status_changes)
|
204
214
|
return block_ids
|
205
215
|
|
206
216
|
def scale_in(self, blocks: int) -> List[str]:
|
@@ -215,16 +225,20 @@ class BlockProviderExecutor(ParslExecutor):
|
|
215
225
|
|
216
226
|
:return: A list of block ids corresponding to the blocks that were removed.
|
217
227
|
"""
|
218
|
-
|
219
|
-
|
220
|
-
|
228
|
+
|
229
|
+
active_blocks = [block_id for block_id, status in self._status.items()
|
230
|
+
if status.state not in TERMINAL_STATES]
|
231
|
+
|
232
|
+
block_ids_to_kill = active_blocks[:blocks]
|
233
|
+
|
234
|
+
job_ids_to_kill = [self.blocks_to_job_id[block] for block in block_ids_to_kill]
|
221
235
|
|
222
236
|
# Cancel the blocks provisioned
|
223
237
|
if self.provider:
|
224
|
-
logger.info(f"Scaling in jobs: {
|
225
|
-
r = self.provider.cancel(
|
226
|
-
job_ids = self._filter_scale_in_ids(
|
227
|
-
block_ids_killed = [self.job_ids_to_block[
|
238
|
+
logger.info(f"Scaling in jobs: {job_ids_to_kill}")
|
239
|
+
r = self.provider.cancel(job_ids_to_kill)
|
240
|
+
job_ids = self._filter_scale_in_ids(job_ids_to_kill, r)
|
241
|
+
block_ids_killed = [self.job_ids_to_block[job_id] for job_id in job_ids]
|
228
242
|
return block_ids_killed
|
229
243
|
else:
|
230
244
|
logger.error("No execution provider available to scale in")
|
@@ -262,10 +276,10 @@ class BlockProviderExecutor(ParslExecutor):
|
|
262
276
|
|
263
277
|
def send_monitoring_info(self, status: Dict) -> None:
|
264
278
|
# Send monitoring info for HTEX when monitoring enabled
|
265
|
-
if self.
|
279
|
+
if self.submit_monitoring_radio:
|
266
280
|
msg = self.create_monitoring_info(status)
|
267
281
|
logger.debug("Sending block monitoring message: %r", msg)
|
268
|
-
self.
|
282
|
+
self.submit_monitoring_radio.send((MessageType.BLOCK_INFO, msg))
|
269
283
|
|
270
284
|
def create_monitoring_info(self, status: Dict[str, JobStatus]) -> Sequence[object]:
|
271
285
|
"""Create a monitoring message for each block based on the poll status.
|
@@ -589,11 +589,13 @@ class TaskVineExecutor(BlockProviderExecutor, putils.RepresentationMixin):
|
|
589
589
|
# Join all processes before exiting
|
590
590
|
logger.debug("Joining on submit process")
|
591
591
|
self._submit_process.join()
|
592
|
+
self._submit_process.close()
|
592
593
|
logger.debug("Joining on collector thread")
|
593
594
|
self._collector_thread.join()
|
594
595
|
if self.worker_launch_method == 'factory':
|
595
596
|
logger.debug("Joining on factory process")
|
596
597
|
self._factory_process.join()
|
598
|
+
self._factory_process.close()
|
597
599
|
|
598
600
|
# Shutdown multiprocessing queues
|
599
601
|
self._ready_task_queue.close()
|
@@ -704,6 +704,8 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
|
|
704
704
|
|
705
705
|
logger.debug("Joining on submit process")
|
706
706
|
self.submit_process.join()
|
707
|
+
self.submit_process.close()
|
708
|
+
|
707
709
|
logger.debug("Joining on collector thread")
|
708
710
|
self.collector_thread.join()
|
709
711
|
|
@@ -283,7 +283,7 @@ class DatabaseManager:
|
|
283
283
|
):
|
284
284
|
|
285
285
|
self.workflow_end = False
|
286
|
-
self.workflow_start_message
|
286
|
+
self.workflow_start_message: Optional[MonitoringMessage] = None
|
287
287
|
self.logdir = logdir
|
288
288
|
os.makedirs(self.logdir, exist_ok=True)
|
289
289
|
|
@@ -299,10 +299,10 @@ class DatabaseManager:
|
|
299
299
|
self.batching_interval = batching_interval
|
300
300
|
self.batching_threshold = batching_threshold
|
301
301
|
|
302
|
-
self.pending_priority_queue
|
303
|
-
self.pending_node_queue
|
304
|
-
self.pending_block_queue
|
305
|
-
self.pending_resource_queue
|
302
|
+
self.pending_priority_queue: queue.Queue[TaggedMonitoringMessage] = queue.Queue()
|
303
|
+
self.pending_node_queue: queue.Queue[MonitoringMessage] = queue.Queue()
|
304
|
+
self.pending_block_queue: queue.Queue[MonitoringMessage] = queue.Queue()
|
305
|
+
self.pending_resource_queue: queue.Queue[MonitoringMessage] = queue.Queue()
|
306
306
|
|
307
307
|
def start(self,
|
308
308
|
priority_queue: "queue.Queue[TaggedMonitoringMessage]",
|
@@ -351,18 +351,18 @@ class DatabaseManager:
|
|
351
351
|
If that happens, the message will be added to deferred_resource_messages and processed later.
|
352
352
|
|
353
353
|
"""
|
354
|
-
inserted_tasks = set()
|
354
|
+
inserted_tasks: Set[object] = set()
|
355
355
|
|
356
356
|
"""
|
357
357
|
like inserted_tasks but for task,try tuples
|
358
358
|
"""
|
359
|
-
inserted_tries = set()
|
359
|
+
inserted_tries: Set[Any] = set()
|
360
360
|
|
361
361
|
# for any task ID, we can defer exactly one message, which is the
|
362
362
|
# assumed-to-be-unique first message (with first message flag set).
|
363
363
|
# The code prior to this patch will discard previous message in
|
364
364
|
# the case of multiple messages to defer.
|
365
|
-
deferred_resource_messages = {}
|
365
|
+
deferred_resource_messages: MonitoringMessage = {}
|
366
366
|
|
367
367
|
exception_happened = False
|
368
368
|
|
@@ -505,7 +505,7 @@ class DatabaseManager:
|
|
505
505
|
"Got {} messages from block queue".format(len(block_info_messages)))
|
506
506
|
# block_info_messages is possibly a nested list of dict (at different polling times)
|
507
507
|
# Each dict refers to the info of a job/block at one polling time
|
508
|
-
block_messages_to_insert
|
508
|
+
block_messages_to_insert: List[Any] = []
|
509
509
|
for block_msg in block_info_messages:
|
510
510
|
block_messages_to_insert.extend(block_msg)
|
511
511
|
self._insert(table=BLOCK, messages=block_messages_to_insert)
|
@@ -686,7 +686,7 @@ class DatabaseManager:
|
|
686
686
|
logger.exception("Rollback failed")
|
687
687
|
|
688
688
|
def _get_messages_in_batch(self, msg_queue: "queue.Queue[X]") -> List[X]:
|
689
|
-
messages
|
689
|
+
messages: List[X] = []
|
690
690
|
start = time.time()
|
691
691
|
while True:
|
692
692
|
if time.time() - start >= self.batching_interval or len(messages) >= self.batching_threshold:
|