parsl 2024.3.18__tar.gz → 2024.4.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (458) hide show
  1. {parsl-2024.3.18/parsl.egg-info → parsl-2024.4.1}/PKG-INFO +2 -2
  2. {parsl-2024.3.18 → parsl-2024.4.1}/README.rst +2 -1
  3. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/dataflow/dflow.py +35 -36
  4. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/base.py +11 -1
  5. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/high_throughput/executor.py +8 -20
  6. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/high_throughput/process_worker_pool.py +5 -2
  7. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/status_handling.py +8 -15
  8. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/taskvine/executor.py +35 -11
  9. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/workqueue/executor.py +33 -11
  10. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/jobs/error_handlers.py +1 -1
  11. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/jobs/job_status_poller.py +12 -11
  12. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/jobs/strategy.py +31 -18
  13. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/monitoring.py +27 -237
  14. parsl-2024.4.1/parsl/monitoring/router.py +208 -0
  15. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/site_tests/test_provider.py +1 -1
  16. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_htex/test_disconnected_blocks.py +0 -1
  17. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_htex/test_drain.py +1 -0
  18. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_monitoring/test_fuzz_zmq.py +2 -2
  19. parsl-2024.4.1/parsl/tests/test_monitoring/test_htex_init_blocks_vs_monitoring.py +85 -0
  20. parsl-2024.4.1/parsl/tests/test_python_apps/test_context_manager.py +40 -0
  21. parsl-2024.4.1/parsl/tests/test_scaling/test_shutdown_scalein.py +78 -0
  22. parsl-2024.4.1/parsl/tests/test_shutdown/test_kill_monitoring.py +65 -0
  23. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/version.py +1 -1
  24. {parsl-2024.3.18 → parsl-2024.4.1/parsl.egg-info}/PKG-INFO +2 -2
  25. {parsl-2024.3.18 → parsl-2024.4.1}/parsl.egg-info/SOURCES.txt +10 -5
  26. {parsl-2024.3.18 → parsl-2024.4.1}/parsl.egg-info/requires.txt +2 -2
  27. {parsl-2024.3.18 → parsl-2024.4.1}/setup.py +1 -1
  28. {parsl-2024.3.18 → parsl-2024.4.1}/LICENSE +0 -0
  29. {parsl-2024.3.18 → parsl-2024.4.1}/MANIFEST.in +0 -0
  30. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/__init__.py +0 -0
  31. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/addresses.py +0 -0
  32. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/app/__init__.py +0 -0
  33. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/app/app.py +0 -0
  34. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/app/bash.py +0 -0
  35. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/app/errors.py +0 -0
  36. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/app/futures.py +0 -0
  37. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/app/python.py +0 -0
  38. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/benchmark/__init__.py +0 -0
  39. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/benchmark/perf.py +0 -0
  40. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/channels/__init__.py +0 -0
  41. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/channels/base.py +0 -0
  42. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/channels/errors.py +0 -0
  43. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/channels/local/__init__.py +0 -0
  44. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/channels/local/local.py +0 -0
  45. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/channels/oauth_ssh/__init__.py +0 -0
  46. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/channels/oauth_ssh/oauth_ssh.py +0 -0
  47. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/channels/ssh/__init__.py +0 -0
  48. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/channels/ssh/ssh.py +0 -0
  49. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/channels/ssh_il/__init__.py +0 -0
  50. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/channels/ssh_il/ssh_il.py +0 -0
  51. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/concurrent/__init__.py +0 -0
  52. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/config.py +0 -0
  53. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/configs/ASPIRE1.py +0 -0
  54. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/configs/Azure.py +0 -0
  55. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/configs/__init__.py +0 -0
  56. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/configs/ad_hoc.py +0 -0
  57. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/configs/bridges.py +0 -0
  58. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/configs/cc_in2p3.py +0 -0
  59. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/configs/ec2.py +0 -0
  60. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/configs/expanse.py +0 -0
  61. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/configs/frontera.py +0 -0
  62. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/configs/htex_local.py +0 -0
  63. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/configs/illinoiscluster.py +0 -0
  64. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/configs/kubernetes.py +0 -0
  65. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/configs/local_threads.py +0 -0
  66. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/configs/midway.py +0 -0
  67. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/configs/osg.py +0 -0
  68. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/configs/polaris.py +0 -0
  69. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/configs/stampede2.py +0 -0
  70. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/configs/summit.py +0 -0
  71. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/configs/toss3_llnl.py +0 -0
  72. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/configs/vineex_local.py +0 -0
  73. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/configs/wqex_local.py +0 -0
  74. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/curvezmq.py +0 -0
  75. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/data_provider/__init__.py +0 -0
  76. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/data_provider/data_manager.py +0 -0
  77. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/data_provider/file_noop.py +0 -0
  78. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/data_provider/files.py +0 -0
  79. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/data_provider/ftp.py +0 -0
  80. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/data_provider/globus.py +0 -0
  81. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/data_provider/http.py +0 -0
  82. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/data_provider/rsync.py +0 -0
  83. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/data_provider/staging.py +0 -0
  84. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/dataflow/__init__.py +0 -0
  85. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/dataflow/errors.py +0 -0
  86. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/dataflow/futures.py +0 -0
  87. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/dataflow/memoization.py +0 -0
  88. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/dataflow/rundirs.py +0 -0
  89. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/dataflow/states.py +0 -0
  90. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/dataflow/taskrecord.py +0 -0
  91. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/errors.py +0 -0
  92. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/__init__.py +0 -0
  93. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/errors.py +0 -0
  94. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/flux/__init__.py +0 -0
  95. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/flux/execute_parsl_task.py +0 -0
  96. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/flux/executor.py +0 -0
  97. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/flux/flux_instance_manager.py +0 -0
  98. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/high_throughput/__init__.py +0 -0
  99. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/high_throughput/errors.py +0 -0
  100. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/high_throughput/interchange.py +0 -0
  101. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/high_throughput/manager_record.py +0 -0
  102. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/high_throughput/monitoring_info.py +0 -0
  103. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/high_throughput/mpi_prefix_composer.py +0 -0
  104. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/high_throughput/mpi_resource_management.py +0 -0
  105. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/high_throughput/probe.py +0 -0
  106. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/high_throughput/zmq_pipes.py +0 -0
  107. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/radical/__init__.py +0 -0
  108. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/radical/executor.py +0 -0
  109. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/radical/rpex_master.py +0 -0
  110. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/radical/rpex_resources.py +0 -0
  111. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/radical/rpex_worker.py +0 -0
  112. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/taskvine/__init__.py +0 -0
  113. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/taskvine/errors.py +0 -0
  114. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/taskvine/exec_parsl_function.py +0 -0
  115. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/taskvine/factory.py +0 -0
  116. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/taskvine/factory_config.py +0 -0
  117. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/taskvine/manager.py +0 -0
  118. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/taskvine/manager_config.py +0 -0
  119. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/taskvine/utils.py +0 -0
  120. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/threads.py +0 -0
  121. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/workqueue/__init__.py +0 -0
  122. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/workqueue/errors.py +0 -0
  123. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/workqueue/exec_parsl_function.py +0 -0
  124. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/workqueue/parsl_coprocess.py +0 -0
  125. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/executors/workqueue/parsl_coprocess_stub.py +0 -0
  126. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/jobs/__init__.py +0 -0
  127. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/jobs/errors.py +0 -0
  128. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/jobs/states.py +0 -0
  129. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/launchers/__init__.py +0 -0
  130. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/launchers/base.py +0 -0
  131. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/launchers/errors.py +0 -0
  132. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/launchers/launchers.py +0 -0
  133. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/log_utils.py +0 -0
  134. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/__init__.py +0 -0
  135. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/db_manager.py +0 -0
  136. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/message_type.py +0 -0
  137. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/queries/__init__.py +0 -0
  138. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/queries/pandas.py +0 -0
  139. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/radios.py +0 -0
  140. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/remote.py +0 -0
  141. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/types.py +0 -0
  142. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/visualization/__init__.py +0 -0
  143. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/visualization/app.py +0 -0
  144. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/visualization/models.py +0 -0
  145. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/visualization/plots/__init__.py +0 -0
  146. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/visualization/plots/default/__init__.py +0 -0
  147. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/visualization/plots/default/task_plots.py +0 -0
  148. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/visualization/plots/default/workflow_plots.py +0 -0
  149. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/visualization/plots/default/workflow_resource_plots.py +0 -0
  150. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/visualization/static/parsl-logo-white.png +0 -0
  151. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/visualization/static/parsl-monitor.css +0 -0
  152. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/visualization/templates/app.html +0 -0
  153. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/visualization/templates/dag.html +0 -0
  154. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/visualization/templates/error.html +0 -0
  155. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/visualization/templates/layout.html +0 -0
  156. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/visualization/templates/resource_usage.html +0 -0
  157. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/visualization/templates/task.html +0 -0
  158. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/visualization/templates/workflow.html +0 -0
  159. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/visualization/templates/workflows_summary.html +0 -0
  160. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/visualization/utils.py +0 -0
  161. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/visualization/version.py +0 -0
  162. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/monitoring/visualization/views.py +0 -0
  163. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/multiprocessing.py +0 -0
  164. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/process_loggers.py +0 -0
  165. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/__init__.py +0 -0
  166. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/ad_hoc/__init__.py +0 -0
  167. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/ad_hoc/ad_hoc.py +0 -0
  168. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/aws/__init__.py +0 -0
  169. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/aws/aws.py +0 -0
  170. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/aws/template.py +0 -0
  171. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/azure/__init__.py +0 -0
  172. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/azure/azure.py +0 -0
  173. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/azure/template.py +0 -0
  174. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/base.py +0 -0
  175. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/cluster_provider.py +0 -0
  176. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/cobalt/__init__.py +0 -0
  177. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/cobalt/cobalt.py +0 -0
  178. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/cobalt/template.py +0 -0
  179. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/condor/__init__.py +0 -0
  180. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/condor/condor.py +0 -0
  181. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/condor/template.py +0 -0
  182. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/errors.py +0 -0
  183. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/googlecloud/__init__.py +0 -0
  184. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/googlecloud/googlecloud.py +0 -0
  185. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/grid_engine/__init__.py +0 -0
  186. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/grid_engine/grid_engine.py +0 -0
  187. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/grid_engine/template.py +0 -0
  188. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/kubernetes/__init__.py +0 -0
  189. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/kubernetes/kube.py +0 -0
  190. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/kubernetes/template.py +0 -0
  191. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/local/__init__.py +0 -0
  192. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/local/local.py +0 -0
  193. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/lsf/__init__.py +0 -0
  194. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/lsf/lsf.py +0 -0
  195. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/lsf/template.py +0 -0
  196. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/pbspro/__init__.py +0 -0
  197. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/pbspro/pbspro.py +0 -0
  198. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/pbspro/template.py +0 -0
  199. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/slurm/__init__.py +0 -0
  200. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/slurm/slurm.py +0 -0
  201. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/slurm/template.py +0 -0
  202. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/torque/__init__.py +0 -0
  203. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/torque/template.py +0 -0
  204. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/providers/torque/torque.py +0 -0
  205. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/py.typed +0 -0
  206. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/serialize/__init__.py +0 -0
  207. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/serialize/base.py +0 -0
  208. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/serialize/concretes.py +0 -0
  209. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/serialize/errors.py +0 -0
  210. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/serialize/facade.py +0 -0
  211. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/serialize/proxystore.py +0 -0
  212. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/__init__.py +0 -0
  213. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/callables_helper.py +0 -0
  214. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/__init__.py +0 -0
  215. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/ad_hoc_cluster_htex.py +0 -0
  216. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/azure_single_node.py +0 -0
  217. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/bluewaters.py +0 -0
  218. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/bridges.py +0 -0
  219. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/cc_in2p3.py +0 -0
  220. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/comet.py +0 -0
  221. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/cooley_htex.py +0 -0
  222. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/ec2_single_node.py +0 -0
  223. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/ec2_spot.py +0 -0
  224. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/frontera.py +0 -0
  225. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/htex_ad_hoc_cluster.py +0 -0
  226. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/htex_local.py +0 -0
  227. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/htex_local_alternate.py +0 -0
  228. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/htex_local_intask_staging.py +0 -0
  229. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/htex_local_rsync_staging.py +0 -0
  230. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/local_adhoc.py +0 -0
  231. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/local_radical.py +0 -0
  232. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/local_radical_mpi.py +0 -0
  233. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/local_threads.py +0 -0
  234. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/local_threads_checkpoint.py +0 -0
  235. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/local_threads_checkpoint_dfk_exit.py +0 -0
  236. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/local_threads_checkpoint_periodic.py +0 -0
  237. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/local_threads_checkpoint_task_exit.py +0 -0
  238. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/local_threads_ftp_in_task.py +0 -0
  239. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/local_threads_globus.py +0 -0
  240. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/local_threads_http_in_task.py +0 -0
  241. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/local_threads_monitoring.py +0 -0
  242. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/local_threads_no_cache.py +0 -0
  243. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/midway.py +0 -0
  244. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/nscc_singapore.py +0 -0
  245. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/osg_htex.py +0 -0
  246. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/petrelkube.py +0 -0
  247. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/summit.py +0 -0
  248. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/swan_htex.py +0 -0
  249. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/taskvine_ex.py +0 -0
  250. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/theta.py +0 -0
  251. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/user_opts.py +0 -0
  252. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/configs/workqueue_ex.py +0 -0
  253. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/conftest.py +0 -0
  254. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/integration/__init__.py +0 -0
  255. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/integration/latency.py +0 -0
  256. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/integration/test_apps/__init__.py +0 -0
  257. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/integration/test_channels/__init__.py +0 -0
  258. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/integration/test_channels/test_channels.py +0 -0
  259. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/integration/test_channels/test_local_channel.py +0 -0
  260. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/integration/test_channels/test_scp_1.py +0 -0
  261. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/integration/test_channels/test_ssh_1.py +0 -0
  262. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/integration/test_channels/test_ssh_errors.py +0 -0
  263. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/integration/test_channels/test_ssh_file_transport.py +0 -0
  264. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/integration/test_channels/test_ssh_interactive.py +0 -0
  265. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/integration/test_parsl_load_default_config.py +0 -0
  266. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/integration/test_stress/__init__.py +0 -0
  267. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/integration/test_stress/test_python_simple.py +0 -0
  268. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/integration/test_stress/test_python_threads.py +0 -0
  269. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/manual_tests/__init__.py +0 -0
  270. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/manual_tests/htex_local.py +0 -0
  271. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/manual_tests/test_ad_hoc_htex.py +0 -0
  272. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/manual_tests/test_basic.py +0 -0
  273. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/manual_tests/test_fan_in_out_htex_remote.py +0 -0
  274. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/manual_tests/test_log_filter.py +0 -0
  275. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/manual_tests/test_memory_limits.py +0 -0
  276. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/manual_tests/test_oauth_ssh.py +0 -0
  277. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/manual_tests/test_regression_220.py +0 -0
  278. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/manual_tests/test_udp_simple.py +0 -0
  279. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/manual_tests/test_worker_count.py +0 -0
  280. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/scaling_tests/__init__.py +0 -0
  281. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/scaling_tests/htex_local.py +0 -0
  282. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/scaling_tests/local_threads.py +0 -0
  283. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/scaling_tests/test_scale.py +0 -0
  284. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/scaling_tests/vineex_condor.py +0 -0
  285. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/scaling_tests/vineex_local.py +0 -0
  286. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/scaling_tests/wqex_condor.py +0 -0
  287. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/scaling_tests/wqex_local.py +0 -0
  288. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/site_tests/__init__.py +0 -0
  289. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/site_tests/site_config_selector.py +0 -0
  290. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/site_tests/test_site.py +0 -0
  291. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/sites/__init__.py +0 -0
  292. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/sites/test_affinity.py +0 -0
  293. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/sites/test_concurrent.py +0 -0
  294. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/sites/test_dynamic_executor.py +0 -0
  295. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/sites/test_ec2.py +0 -0
  296. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/sites/test_launchers.py +0 -0
  297. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/sites/test_local_adhoc.py +0 -0
  298. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/sites/test_mpi/__init__.py +0 -0
  299. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/sites/test_worker_info.py +0 -0
  300. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_aalst_patterns.py +0 -0
  301. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_bash_apps/__init__.py +0 -0
  302. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_bash_apps/test_apptimeout.py +0 -0
  303. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_bash_apps/test_basic.py +0 -0
  304. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_bash_apps/test_error_codes.py +0 -0
  305. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_bash_apps/test_keyword_overlaps.py +0 -0
  306. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_bash_apps/test_kwarg_storage.py +0 -0
  307. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_bash_apps/test_memoize.py +0 -0
  308. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_bash_apps/test_memoize_ignore_args.py +0 -0
  309. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_bash_apps/test_memoize_ignore_args_regr.py +0 -0
  310. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_bash_apps/test_multiline.py +0 -0
  311. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_bash_apps/test_pipeline.py +0 -0
  312. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_bash_apps/test_stdout.py +0 -0
  313. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_callables.py +0 -0
  314. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_channels/__init__.py +0 -0
  315. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_channels/test_large_output.py +0 -0
  316. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_checkpointing/__init__.py +0 -0
  317. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_checkpointing/test_periodic.py +0 -0
  318. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_checkpointing/test_python_checkpoint_1.py +0 -0
  319. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_checkpointing/test_python_checkpoint_2.py +0 -0
  320. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_checkpointing/test_python_checkpoint_3.py +0 -0
  321. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_checkpointing/test_regression_232.py +0 -0
  322. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_checkpointing/test_regression_233.py +0 -0
  323. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_checkpointing/test_regression_239.py +0 -0
  324. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_checkpointing/test_task_exit.py +0 -0
  325. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_curvezmq.py +0 -0
  326. {parsl-2024.3.18/parsl/tests/test_data → parsl-2024.4.1/parsl/tests/test_docs}/__init__.py +0 -0
  327. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_docs/test_from_slides.py +0 -0
  328. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_docs/test_kwargs.py +0 -0
  329. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_docs/test_tutorial_1.py +0 -0
  330. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_docs/test_workflow1.py +0 -0
  331. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_docs/test_workflow2.py +0 -0
  332. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_docs/test_workflow4.py +0 -0
  333. {parsl-2024.3.18/parsl/tests/test_docs → parsl-2024.4.1/parsl/tests/test_error_handling}/__init__.py +0 -0
  334. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_error_handling/test_fail.py +0 -0
  335. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_error_handling/test_python_walltime.py +0 -0
  336. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_error_handling/test_rand_fail.py +0 -0
  337. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_error_handling/test_resource_spec.py +0 -0
  338. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_error_handling/test_retries.py +0 -0
  339. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_error_handling/test_retry_handler.py +0 -0
  340. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_error_handling/test_retry_handler_failure.py +0 -0
  341. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_error_handling/test_serialization_fail.py +0 -0
  342. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_error_handling/test_wrap_with_logs.py +0 -0
  343. {parsl-2024.3.18/parsl/tests/test_error_handling → parsl-2024.4.1/parsl/tests/test_flowcontrol}/__init__.py +0 -0
  344. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_flux.py +0 -0
  345. {parsl-2024.3.18/parsl/tests/test_flowcontrol → parsl-2024.4.1/parsl/tests/test_htex}/__init__.py +0 -0
  346. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_htex/test_basic.py +0 -0
  347. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_htex/test_connected_blocks.py +0 -0
  348. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_htex/test_cpu_affinity_explicit.py +0 -0
  349. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_htex/test_htex.py +0 -0
  350. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_htex/test_manager_failure.py +0 -0
  351. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_htex/test_missing_worker.py +0 -0
  352. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_htex/test_multiple_disconnected_blocks.py +0 -0
  353. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_htex/test_worker_failure.py +0 -0
  354. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_htex/test_zmq_binding.py +0 -0
  355. {parsl-2024.3.18/parsl/tests/test_htex → parsl-2024.4.1/parsl/tests/test_monitoring}/__init__.py +0 -0
  356. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_monitoring/test_app_names.py +0 -0
  357. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_monitoring/test_basic.py +0 -0
  358. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_monitoring/test_db_locks.py +0 -0
  359. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_monitoring/test_incomplete_futures.py +0 -0
  360. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_monitoring/test_memoization_representation.py +0 -0
  361. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_monitoring/test_viz_colouring.py +0 -0
  362. {parsl-2024.3.18/parsl/tests/test_monitoring → parsl-2024.4.1/parsl/tests/test_mpi_apps}/__init__.py +0 -0
  363. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_mpi_apps/test_bad_mpi_config.py +0 -0
  364. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_mpi_apps/test_mpi_mode_disabled.py +0 -0
  365. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_mpi_apps/test_mpi_mode_enabled.py +0 -0
  366. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_mpi_apps/test_mpi_prefix.py +0 -0
  367. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_mpi_apps/test_mpi_scheduler.py +0 -0
  368. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_mpi_apps/test_resource_spec.py +0 -0
  369. {parsl-2024.3.18/parsl/tests/test_mpi_apps → parsl-2024.4.1/parsl/tests/test_providers}/__init__.py +0 -0
  370. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_providers/test_cobalt_deprecation_warning.py +0 -0
  371. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_providers/test_local_provider.py +0 -0
  372. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_providers/test_pbspro_template.py +0 -0
  373. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_providers/test_slurm_instantiate.py +0 -0
  374. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_providers/test_slurm_template.py +0 -0
  375. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_providers/test_submiterror_deprecation.py +0 -0
  376. {parsl-2024.3.18/parsl/tests/test_providers → parsl-2024.4.1/parsl/tests/test_python_apps}/__init__.py +0 -0
  377. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_arg_input_types.py +0 -0
  378. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_basic.py +0 -0
  379. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_dep_standard_futures.py +0 -0
  380. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_dependencies.py +0 -0
  381. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_depfail_propagation.py +0 -0
  382. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_fail.py +0 -0
  383. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_fibonacci_iterative.py +0 -0
  384. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_fibonacci_recursive.py +0 -0
  385. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_futures.py +0 -0
  386. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_garbage_collect.py +0 -0
  387. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_import_fail.py +0 -0
  388. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_join.py +0 -0
  389. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_lifted.py +0 -0
  390. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_mapred.py +0 -0
  391. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_memoize_1.py +0 -0
  392. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_memoize_2.py +0 -0
  393. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_memoize_4.py +0 -0
  394. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_memoize_bad_id_for_memo.py +0 -0
  395. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_memoize_ignore_args.py +0 -0
  396. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_memoize_joinapp.py +0 -0
  397. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_outputs.py +0 -0
  398. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_overview.py +0 -0
  399. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_pipeline.py +0 -0
  400. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_simple.py +0 -0
  401. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_timeout.py +0 -0
  402. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_python_apps/test_type5.py +0 -0
  403. {parsl-2024.3.18/parsl/tests/test_python_apps → parsl-2024.4.1/parsl/tests/test_radical}/__init__.py +0 -0
  404. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_radical/test_mpi_funcs.py +0 -0
  405. {parsl-2024.3.18/parsl/tests/test_radical → parsl-2024.4.1/parsl/tests/test_regression}/__init__.py +0 -0
  406. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_regression/test_1480.py +0 -0
  407. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_regression/test_1606_wait_for_current_tasks.py +0 -0
  408. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_regression/test_1653.py +0 -0
  409. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_regression/test_221.py +0 -0
  410. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_regression/test_226.py +0 -0
  411. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_regression/test_2652.py +0 -0
  412. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_regression/test_69a.py +0 -0
  413. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_regression/test_854.py +0 -0
  414. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_regression/test_97_parallelism_0.py +0 -0
  415. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_regression/test_98.py +0 -0
  416. {parsl-2024.3.18/parsl/tests/test_regression → parsl-2024.4.1/parsl/tests/test_scaling}/__init__.py +0 -0
  417. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_scaling/test_block_error_handler.py +0 -0
  418. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_scaling/test_regression_1621.py +0 -0
  419. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_scaling/test_scale_down.py +0 -0
  420. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_scaling/test_scale_down_htex_auto_scale.py +0 -0
  421. {parsl-2024.3.18/parsl/tests/test_scaling → parsl-2024.4.1/parsl/tests/test_serialization}/__init__.py +0 -0
  422. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_serialization/test_2555_caching_deserializer.py +0 -0
  423. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_serialization/test_basic.py +0 -0
  424. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_serialization/test_htex_code_cache.py +0 -0
  425. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_serialization/test_pack_resource_spec.py +0 -0
  426. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_serialization/test_proxystore_configured.py +0 -0
  427. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_serialization/test_proxystore_impl.py +0 -0
  428. {parsl-2024.3.18/parsl/tests/test_serialization → parsl-2024.4.1/parsl/tests/test_shutdown}/__init__.py +0 -0
  429. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_staging/__init__.py +0 -0
  430. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_staging/staging_provider.py +0 -0
  431. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_staging/test_1316.py +0 -0
  432. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_staging/test_docs_1.py +0 -0
  433. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_staging/test_docs_2.py +0 -0
  434. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_staging/test_elaborate_noop_file.py +0 -0
  435. {parsl-2024.3.18/parsl/tests/test_data → parsl-2024.4.1/parsl/tests/test_staging}/test_file.py +0 -0
  436. {parsl-2024.3.18/parsl/tests/test_data → parsl-2024.4.1/parsl/tests/test_staging}/test_file_apps.py +0 -0
  437. {parsl-2024.3.18/parsl/tests/test_data → parsl-2024.4.1/parsl/tests/test_staging}/test_file_staging.py +0 -0
  438. {parsl-2024.3.18/parsl/tests/test_data → parsl-2024.4.1/parsl/tests/test_staging}/test_output_chain_filenames.py +0 -0
  439. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_staging/test_staging_ftp.py +0 -0
  440. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_staging/test_staging_ftp_in_task.py +0 -0
  441. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_staging/test_staging_globus.py +0 -0
  442. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_staging/test_staging_https.py +0 -0
  443. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_summary.py +0 -0
  444. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_thread_parallelism.py +0 -0
  445. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_threads/__init__.py +0 -0
  446. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_threads/test_configs.py +0 -0
  447. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_threads/test_lazy_errors.py +0 -0
  448. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_utils/__init__.py +0 -0
  449. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/test_utils/test_representation_mixin.py +0 -0
  450. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/tests/utils.py +0 -0
  451. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/usage_tracking/__init__.py +0 -0
  452. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/usage_tracking/usage.py +0 -0
  453. {parsl-2024.3.18 → parsl-2024.4.1}/parsl/utils.py +0 -0
  454. {parsl-2024.3.18 → parsl-2024.4.1}/parsl.egg-info/dependency_links.txt +0 -0
  455. {parsl-2024.3.18 → parsl-2024.4.1}/parsl.egg-info/entry_points.txt +0 -0
  456. {parsl-2024.3.18 → parsl-2024.4.1}/parsl.egg-info/top_level.txt +0 -0
  457. {parsl-2024.3.18 → parsl-2024.4.1}/requirements.txt +0 -0
  458. {parsl-2024.3.18 → parsl-2024.4.1}/setup.cfg +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: parsl
3
- Version: 2024.3.18
3
+ Version: 2024.4.1
4
4
  Summary: Simple data dependent workflows in Python
5
5
  Home-page: https://github.com/Parsl/parsl
6
- Download-URL: https://github.com/Parsl/parsl/archive/2024.03.18.tar.gz
6
+ Download-URL: https://github.com/Parsl/parsl/archive/2024.04.01.tar.gz
7
7
  Author: The Parsl Team
8
8
  Author-email: parsl@googlegroups.com
9
9
  License: Apache 2.0
@@ -97,6 +97,7 @@ For Developers
97
97
 
98
98
  2. Build and Test::
99
99
 
100
+ $ cd parsl # navigate to the root directory of the project
100
101
  $ make # show all available makefile targets
101
102
  $ make virtualenv # create a virtual environment
102
103
  $ source .venv/bin/activate # activate the virtual environment
@@ -119,7 +120,7 @@ Parsl is supported in Python 3.8+. Requirements can be found `here <requirements
119
120
  Code of Conduct
120
121
  ===============
121
122
 
122
- Parsl seeks to foster an open and welcoming environment - Please see the `Parsl Code of Conduct <https://github.com/Parsl/parsl/blob/master/CoC.md>`_ for more details.
123
+ Parsl seeks to foster an open and welcoming environment - Please see the `Parsl Code of Conduct <https://github.com/Parsl/parsl/blob/master/CODE_OF_CONDUCT.md>`_ for more details.
123
124
 
124
125
  Contributing
125
126
  ============
@@ -34,12 +34,12 @@ from parsl.dataflow.states import States, FINAL_STATES, FINAL_FAILURE_STATES
34
34
  from parsl.dataflow.taskrecord import TaskRecord
35
35
  from parsl.errors import ConfigurationError, InternalConsistencyError, NoDataFlowKernelError
36
36
  from parsl.jobs.job_status_poller import JobStatusPoller
37
- from parsl.jobs.states import JobStatus, JobState
38
37
  from parsl.usage_tracking.usage import UsageTracker
39
38
  from parsl.executors.base import ParslExecutor
40
39
  from parsl.executors.status_handling import BlockProviderExecutor
41
40
  from parsl.executors.threads import ThreadPoolExecutor
42
41
  from parsl.monitoring import MonitoringHub
42
+ from parsl.monitoring.remote import monitor_wrapper
43
43
  from parsl.process_loggers import wrap_with_logs
44
44
  from parsl.providers.base import ExecutionProvider
45
45
  from parsl.utils import get_version, get_std_fname_mode, get_all_checkpoints, Timer
@@ -108,12 +108,12 @@ class DataFlowKernel:
108
108
 
109
109
  # hub address and port for interchange to connect
110
110
  self.hub_address = None # type: Optional[str]
111
- self.hub_interchange_port = None # type: Optional[int]
111
+ self.hub_zmq_port = None # type: Optional[int]
112
112
  if self.monitoring:
113
113
  if self.monitoring.logdir is None:
114
114
  self.monitoring.logdir = self.run_dir
115
115
  self.hub_address = self.monitoring.hub_address
116
- self.hub_interchange_port = self.monitoring.start(self.run_id, self.run_dir, self.config.run_dir)
116
+ self.hub_zmq_port = self.monitoring.start(self.run_id, self.run_dir, self.config.run_dir)
117
117
 
118
118
  self.time_began = datetime.datetime.now()
119
119
  self.time_completed: Optional[datetime.datetime] = None
@@ -206,6 +206,13 @@ class DataFlowKernel:
206
206
 
207
207
  atexit.register(self.atexit_cleanup)
208
208
 
209
+ def __enter__(self):
210
+ return self
211
+
212
+ def __exit__(self, exc_type, exc_value, traceback):
213
+ logger.debug("Exiting the context manager, calling cleanup for DFK")
214
+ self.cleanup()
215
+
209
216
  def _send_task_log_info(self, task_record: TaskRecord) -> None:
210
217
  if self.monitoring:
211
218
  task_log_info = self._create_task_log_info(task_record)
@@ -707,14 +714,14 @@ class DataFlowKernel:
707
714
 
708
715
  if self.monitoring is not None and self.monitoring.resource_monitoring_enabled:
709
716
  wrapper_logging_level = logging.DEBUG if self.monitoring.monitoring_debug else logging.INFO
710
- (function, args, kwargs) = self.monitoring.monitor_wrapper(function, args, kwargs, try_id, task_id,
711
- self.monitoring.monitoring_hub_url,
712
- self.run_id,
713
- wrapper_logging_level,
714
- self.monitoring.resource_monitoring_interval,
715
- executor.radio_mode,
716
- executor.monitor_resources(),
717
- self.run_dir)
717
+ (function, args, kwargs) = monitor_wrapper(function, args, kwargs, try_id, task_id,
718
+ self.monitoring.monitoring_hub_url,
719
+ self.run_id,
720
+ wrapper_logging_level,
721
+ self.monitoring.resource_monitoring_interval,
722
+ executor.radio_mode,
723
+ executor.monitor_resources(),
724
+ self.run_dir)
718
725
 
719
726
  with self.submitter_lock:
720
727
  exec_fu = executor.submit(function, task_record['resource_specification'], *args, **kwargs)
@@ -1115,12 +1122,12 @@ class DataFlowKernel:
1115
1122
 
1116
1123
  channel.makedirs(channel.script_dir, exist_ok=True)
1117
1124
 
1118
- def add_executors(self, executors):
1125
+ def add_executors(self, executors: Sequence[ParslExecutor]) -> None:
1119
1126
  for executor in executors:
1120
1127
  executor.run_id = self.run_id
1121
1128
  executor.run_dir = self.run_dir
1122
1129
  executor.hub_address = self.hub_address
1123
- executor.hub_port = self.hub_interchange_port
1130
+ executor.hub_port = self.hub_zmq_port
1124
1131
  if hasattr(executor, 'provider'):
1125
1132
  if hasattr(executor.provider, 'script_dir'):
1126
1133
  executor.provider.script_dir = os.path.join(self.run_dir, 'submit_scripts')
@@ -1134,14 +1141,7 @@ class DataFlowKernel:
1134
1141
  self._create_remote_dirs_over_channel(executor.provider, executor.provider.channel)
1135
1142
 
1136
1143
  self.executors[executor.label] = executor
1137
- block_ids = executor.start()
1138
- if self.monitoring and block_ids:
1139
- new_status = {}
1140
- for bid in block_ids:
1141
- new_status[bid] = JobStatus(JobState.PENDING)
1142
- msg = executor.create_monitoring_info(new_status)
1143
- logger.debug("Sending monitoring message {} to hub from DFK".format(msg))
1144
- self.monitoring.send(MessageType.BLOCK_INFO, msg)
1144
+ executor.start()
1145
1145
  block_executors = [e for e in executors if isinstance(e, BlockProviderExecutor)]
1146
1146
  self.job_status_poller.add_executors(block_executors)
1147
1147
 
@@ -1216,22 +1216,21 @@ class DataFlowKernel:
1216
1216
 
1217
1217
  logger.info("Scaling in and shutting down executors")
1218
1218
 
1219
+ for ef in self.job_status_poller._executor_facades:
1220
+ if not ef.executor.bad_state_is_set:
1221
+ logger.info(f"Scaling in executor {ef.executor.label}")
1222
+
1223
+ # this code needs to be at least as many blocks as need
1224
+ # cancelling, but it is safe to be more, as the scaling
1225
+ # code will cope with being asked to cancel more blocks
1226
+ # than exist.
1227
+ block_count = len(ef.status)
1228
+ ef.scale_in(block_count)
1229
+
1230
+ else: # and bad_state_is_set
1231
+ logger.warning(f"Not scaling in executor {ef.executor.label} because it is in bad state")
1232
+
1219
1233
  for executor in self.executors.values():
1220
- if isinstance(executor, BlockProviderExecutor):
1221
- if not executor.bad_state_is_set:
1222
- logger.info(f"Scaling in executor {executor.label}")
1223
- if executor.provider:
1224
- job_ids = executor.provider.resources.keys()
1225
- block_ids = executor.scale_in(len(job_ids))
1226
- if self.monitoring and block_ids:
1227
- new_status = {}
1228
- for bid in block_ids:
1229
- new_status[bid] = JobStatus(JobState.CANCELLED)
1230
- msg = executor.create_monitoring_info(new_status)
1231
- logger.debug("Sending message {} to hub from DFK".format(msg))
1232
- self.monitoring.send(MessageType.BLOCK_INFO, msg)
1233
- else: # and bad_state_is_set
1234
- logger.warning(f"Not shutting down executor {executor.label} because it is in bad state")
1235
1234
  logger.info(f"Shutting down executor {executor.label}")
1236
1235
  executor.shutdown()
1237
1236
  logger.info(f"Shut down executor {executor.label}")
@@ -53,7 +53,7 @@ class ParslExecutor(metaclass=ABCMeta):
53
53
  return False
54
54
 
55
55
  @abstractmethod
56
- def start(self) -> Optional[List[str]]:
56
+ def start(self) -> None:
57
57
  """Start the executor.
58
58
 
59
59
  Any spin-up operations (for example: starting thread pools) should be performed here.
@@ -106,6 +106,16 @@ class ParslExecutor(metaclass=ABCMeta):
106
106
  def run_dir(self, value: str) -> None:
107
107
  self._run_dir = value
108
108
 
109
+ @property
110
+ def run_id(self) -> Optional[str]:
111
+ """UUID for the enclosing DFK.
112
+ """
113
+ return self._run_id
114
+
115
+ @run_id.setter
116
+ def run_id(self, value: Optional[str]) -> None:
117
+ self._run_id = value
118
+
109
119
  @property
110
120
  def hub_address(self) -> Optional[str]:
111
121
  """Address to the Hub for monitoring.
@@ -1,4 +1,5 @@
1
1
  import typing
2
+ from collections import defaultdict
2
3
  from concurrent.futures import Future
3
4
  import typeguard
4
5
  import logging
@@ -400,16 +401,6 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin):
400
401
 
401
402
  logger.debug("Starting HighThroughputExecutor with provider:\n%s", self.provider)
402
403
 
403
- # TODO: why is this a provider property?
404
- block_ids = []
405
- if hasattr(self.provider, 'init_blocks'):
406
- try:
407
- block_ids = self.scale_out(blocks=self.provider.init_blocks)
408
- except Exception as e:
409
- logger.error("Scaling out failed: {}".format(e))
410
- raise e
411
- return block_ids
412
-
413
404
  def start(self):
414
405
  """Create the Interchange process and connect to it.
415
406
  """
@@ -439,8 +430,7 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin):
439
430
 
440
431
  logger.debug("Created management thread: {}".format(self._queue_management_thread))
441
432
 
442
- block_ids = self.initialize_scaling()
443
- return block_ids
433
+ self.initialize_scaling()
444
434
 
445
435
  @wrap_with_logs
446
436
  def _queue_management_worker(self):
@@ -698,7 +688,7 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin):
698
688
  d['status'] = s.status_name
699
689
  d['timestamp'] = datetime.datetime.now()
700
690
  d['executor_label'] = self.label
701
- d['job_id'] = self.blocks.get(bid, None)
691
+ d['job_id'] = self.blocks_to_job_id.get(bid, None)
702
692
  d['block_id'] = bid
703
693
  msg.append(d)
704
694
  return msg
@@ -741,13 +731,11 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin):
741
731
  idle: float # shortest idle time of any manager in this block
742
732
 
743
733
  managers = self.connected_managers()
744
- block_info: Dict[str, BlockInfo] = {}
734
+ block_info: Dict[str, BlockInfo] = defaultdict(lambda: BlockInfo(tasks=0, idle=float('inf')))
745
735
  for manager in managers:
746
736
  if not manager['active']:
747
737
  continue
748
738
  b_id = manager['block_id']
749
- if b_id not in block_info:
750
- block_info[b_id] = BlockInfo(tasks=0, idle=float('inf'))
751
739
  block_info[b_id].tasks += manager['tasks']
752
740
  block_info[b_id].idle = min(block_info[b_id].idle, manager['idle_duration'])
753
741
 
@@ -779,14 +767,14 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin):
779
767
 
780
768
  # Now kill via provider
781
769
  # Potential issue with multiple threads trying to remove the same blocks
782
- to_kill = [self.blocks[bid] for bid in block_ids_to_kill if bid in self.blocks]
770
+ to_kill = [self.blocks_to_job_id[bid] for bid in block_ids_to_kill if bid in self.blocks_to_job_id]
783
771
 
784
772
  r = self.provider.cancel(to_kill)
785
773
  job_ids = self._filter_scale_in_ids(to_kill, r)
786
774
 
787
- # to_kill block_ids are fetched from self.blocks
788
- # If a block_id is in self.block, it must exist in self.block_mapping
789
- block_ids_killed = [self.block_mapping[jid] for jid in job_ids]
775
+ # to_kill block_ids are fetched from self.blocks_to_job_id
776
+ # If a block_id is in self.blocks_to_job_id, it must exist in self.job_ids_to_block
777
+ block_ids_killed = [self.job_ids_to_block[jid] for jid in job_ids]
790
778
 
791
779
  return block_ids_killed
792
780
 
@@ -335,14 +335,17 @@ class Manager:
335
335
  self.heartbeat_to_incoming()
336
336
  last_beat = time.time()
337
337
 
338
- if self.drain_time and time.time() > self.drain_time:
338
+ if time.time() > self.drain_time:
339
339
  logger.info("Requesting drain")
340
340
  self.drain_to_incoming()
341
- self.drain_time = None
342
341
  # This will start the pool draining...
343
342
  # Drained exit behaviour does not happen here. It will be
344
343
  # driven by the interchange sending a DRAINED_CODE message.
345
344
 
345
+ # now set drain time to the far future so we don't send a drain
346
+ # message every iteration.
347
+ self.drain_time = float('inf')
348
+
346
349
  poll_duration_s = max(0, next_interesting_event_time - time.time())
347
350
  socks = dict(poller.poll(timeout=poll_duration_s * 1000))
348
351
 
@@ -61,15 +61,15 @@ class BlockProviderExecutor(ParslExecutor):
61
61
  # errors can happen during the submit call to the provider; this is used
62
62
  # to keep track of such errors so that they can be handled in one place
63
63
  # together with errors reported by status()
64
- self._simulated_status: Dict[Any, JobStatus] = {}
64
+ self._simulated_status: Dict[str, JobStatus] = {}
65
65
  self._executor_bad_state = threading.Event()
66
66
  self._executor_exception: Optional[Exception] = None
67
67
 
68
68
  self._block_id_counter = AtomicIDCounter()
69
69
 
70
70
  self._tasks = {} # type: Dict[object, Future]
71
- self.blocks = {} # type: Dict[str, str]
72
- self.block_mapping = {} # type: Dict[str, str]
71
+ self.blocks_to_job_id = {} # type: Dict[str, str]
72
+ self.job_ids_to_block = {} # type: Dict[str, str]
73
73
 
74
74
  def _make_status_dict(self, block_ids: List[str], status_list: List[JobStatus]) -> Dict[str, JobStatus]:
75
75
  """Given a list of block ids and a list of corresponding status strings,
@@ -102,13 +102,10 @@ class BlockProviderExecutor(ParslExecutor):
102
102
  else:
103
103
  return self._provider.status_polling_interval
104
104
 
105
- def _fail_job_async(self, block_id: Any, message: str):
105
+ def _fail_job_async(self, block_id: str, message: str):
106
106
  """Marks a job that has failed to start but would not otherwise be included in status()
107
107
  as failed and report it in status()
108
108
  """
109
- if block_id is None:
110
- block_id = str(self._block_id_counter.get_id())
111
- logger.info(f"Allocated block ID {block_id} for simulated failure")
112
109
  self._simulated_status[block_id] = JobStatus(JobState.FAILED, message)
113
110
 
114
111
  @abstractproperty
@@ -197,8 +194,8 @@ class BlockProviderExecutor(ParslExecutor):
197
194
  logger.info(f"Allocated block ID {block_id}")
198
195
  try:
199
196
  job_id = self._launch_block(block_id)
200
- self.blocks[block_id] = job_id
201
- self.block_mapping[job_id] = block_id
197
+ self.blocks_to_job_id[block_id] = job_id
198
+ self.job_ids_to_block[job_id] = block_id
202
199
  block_ids.append(block_id)
203
200
  except Exception as ex:
204
201
  self._fail_job_async(block_id,
@@ -211,10 +208,6 @@ class BlockProviderExecutor(ParslExecutor):
211
208
 
212
209
  Cause the executor to reduce the number of blocks by count.
213
210
 
214
- We should have the scale in method simply take resource object
215
- which will have the scaling methods, scale_in itself should be a coroutine, since
216
- scaling tasks can be slow.
217
-
218
211
  :return: A list of block ids corresponding to the blocks that were removed.
219
212
  """
220
213
  pass
@@ -239,10 +232,10 @@ class BlockProviderExecutor(ParslExecutor):
239
232
  # Not using self.blocks.keys() and self.blocks.values() simultaneously
240
233
  # The dictionary may be changed during invoking this function
241
234
  # As scale_in and scale_out are invoked in multiple threads
242
- block_ids = list(self.blocks.keys())
235
+ block_ids = list(self.blocks_to_job_id.keys())
243
236
  job_ids = [] # types: List[Any]
244
237
  for bid in block_ids:
245
- job_ids.append(self.blocks[bid])
238
+ job_ids.append(self.blocks_to_job_id[bid])
246
239
  return block_ids, job_ids
247
240
 
248
241
  @abstractproperty
@@ -4,6 +4,7 @@ high-throughput system for delegating Parsl tasks to thousands of remote machine
4
4
  """
5
5
 
6
6
  # Import Python built-in libraries
7
+ import atexit
7
8
  import threading
8
9
  import multiprocessing
9
10
  import logging
@@ -171,7 +172,7 @@ class TaskVineExecutor(BlockProviderExecutor, putils.RepresentationMixin):
171
172
  # Path to directory that holds all tasks' data and results.
172
173
  self._function_data_dir = ""
173
174
 
174
- # helper scripts to prepare package tarballs for Parsl apps
175
+ # Helper scripts to prepare package tarballs for Parsl apps
175
176
  self._package_analyze_script = shutil.which("poncho_package_analyze")
176
177
  self._package_create_script = shutil.which("poncho_package_create")
177
178
  if self._package_analyze_script is None or self._package_create_script is None:
@@ -179,6 +180,24 @@ class TaskVineExecutor(BlockProviderExecutor, putils.RepresentationMixin):
179
180
  else:
180
181
  self._poncho_available = True
181
182
 
183
+ # Register atexit handler to cleanup when Python shuts down
184
+ atexit.register(self.atexit_cleanup)
185
+
186
+ # Attribute indicating whether this executor was started to shut it down properly.
187
+ # This safeguards cases where an object of this executor is created but
188
+ # the executor never starts, so it shouldn't be shutdowned.
189
+ self._is_started = False
190
+
191
+ # Attribute indicating whether this executor was shutdown before.
192
+ # This safeguards cases where this object is automatically shut down (e.g.,
193
+ # via atexit) and the user also explicitly calls shut down. While this is
194
+ # permitted, the effect of an executor shutdown should happen only once.
195
+ self._is_shutdown = False
196
+
197
+ def atexit_cleanup(self):
198
+ # Calls this executor's shutdown method upon Python exiting the process.
199
+ self.shutdown()
200
+
182
201
  def _get_launch_command(self, block_id):
183
202
  # Implements BlockProviderExecutor's abstract method.
184
203
  # This executor uses different terminology for worker/launch
@@ -238,6 +257,9 @@ class TaskVineExecutor(BlockProviderExecutor, putils.RepresentationMixin):
238
257
  retrieve Parsl tasks within the TaskVine system.
239
258
  """
240
259
 
260
+ # Mark this executor object as started
261
+ self._is_started = True
262
+
241
263
  # Synchronize connection and communication settings between the manager and factory
242
264
  self.__synchronize_manager_factory_comm_settings()
243
265
 
@@ -564,13 +586,6 @@ class TaskVineExecutor(BlockProviderExecutor, putils.RepresentationMixin):
564
586
  self._worker_command = self._construct_worker_command()
565
587
  self._patch_providers()
566
588
 
567
- if hasattr(self.provider, 'init_blocks'):
568
- try:
569
- self.scale_out(blocks=self.provider.init_blocks)
570
- except Exception as e:
571
- logger.error("Initial block scaling out failed: {}".format(e))
572
- raise e
573
-
574
589
  @property
575
590
  def outstanding(self) -> int:
576
591
  """Count the number of outstanding tasks."""
@@ -585,8 +600,8 @@ class TaskVineExecutor(BlockProviderExecutor, putils.RepresentationMixin):
585
600
  """Scale in method. Cancel a given number of blocks
586
601
  """
587
602
  # Obtain list of blocks to kill
588
- to_kill = list(self.blocks.keys())[:count]
589
- kill_ids = [self.blocks[block] for block in to_kill]
603
+ to_kill = list(self.blocks_to_job_id.keys())[:count]
604
+ kill_ids = [self.blocks_to_job_id[block] for block in to_kill]
590
605
 
591
606
  # Cancel the blocks provisioned
592
607
  if self.provider:
@@ -598,11 +613,19 @@ class TaskVineExecutor(BlockProviderExecutor, putils.RepresentationMixin):
598
613
  """Shutdown the executor. Sets flag to cancel the submit process and
599
614
  collector thread, which shuts down the TaskVine system submission.
600
615
  """
616
+ if not self._is_started:
617
+ # Don't shutdown if the executor never starts.
618
+ return
619
+
620
+ if self._is_shutdown:
621
+ # Don't shutdown this executor again.
622
+ return
623
+
601
624
  logger.debug("TaskVine shutdown started")
602
625
  self._should_stop.set()
603
626
 
604
627
  # Remove the workers that are still going
605
- kill_ids = [self.blocks[block] for block in self.blocks.keys()]
628
+ kill_ids = [self.blocks_to_job_id[block] for block in self.blocks_to_job_id.keys()]
606
629
  if self.provider:
607
630
  logger.debug("Cancelling blocks")
608
631
  self.provider.cancel(kill_ids)
@@ -616,6 +639,7 @@ class TaskVineExecutor(BlockProviderExecutor, putils.RepresentationMixin):
616
639
  logger.debug("Joining on factory process")
617
640
  self._factory_process.join()
618
641
 
642
+ self._is_shutdown = True
619
643
  logger.debug("TaskVine shutdown completed")
620
644
 
621
645
  @wrap_with_logs
@@ -3,6 +3,7 @@ Cooperative Computing Lab (CCL) at Notre Dame to provide a fault-tolerant,
3
3
  high-throughput system for delegating Parsl tasks to thousands of remote machines
4
4
  """
5
5
 
6
+ import atexit
6
7
  import threading
7
8
  import multiprocessing
8
9
  import logging
@@ -254,7 +255,6 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
254
255
  self.label = label
255
256
  self.task_queue = multiprocessing.Queue() # type: multiprocessing.Queue
256
257
  self.collector_queue = multiprocessing.Queue() # type: multiprocessing.Queue
257
- self.blocks = {} # type: Dict[str, str]
258
258
  self.address = address
259
259
  self.port = port
260
260
  self.executor_task_counter = -1
@@ -298,6 +298,24 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
298
298
  if self.init_command != "":
299
299
  self.launch_cmd = self.init_command + "; " + self.launch_cmd
300
300
 
301
+ # register atexit handler to cleanup when Python shuts down
302
+ atexit.register(self.atexit_cleanup)
303
+
304
+ # Attribute indicating whether this executor was started to shut it down properly.
305
+ # This safeguards cases where an object of this executor is created but
306
+ # the executor never starts, so it shouldn't be shutdowned.
307
+ self.is_started = False
308
+
309
+ # Attribute indicating whether this executor was shutdown before.
310
+ # This safeguards cases where this object is automatically shut down (e.g.,
311
+ # via atexit) and the user also explicitly calls shut down. While this is
312
+ # permitted, the effect of an executor shutdown should happen only once.
313
+ self.is_shutdown = False
314
+
315
+ def atexit_cleanup(self):
316
+ # Calls this executor's shutdown method upon Python exiting the process.
317
+ self.shutdown()
318
+
301
319
  def _get_launch_command(self, block_id):
302
320
  # this executor uses different terminology for worker/launch
303
321
  # commands than in htex
@@ -307,6 +325,8 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
307
325
  """Create submit process and collector thread to create, send, and
308
326
  retrieve Parsl tasks within the Work Queue system.
309
327
  """
328
+ # Mark this executor object as started
329
+ self.is_started = True
310
330
  self.tasks_lock = threading.Lock()
311
331
 
312
332
  # Create directories for data and results
@@ -654,13 +674,6 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
654
674
  self.worker_command = self._construct_worker_command()
655
675
  self._patch_providers()
656
676
 
657
- if hasattr(self.provider, 'init_blocks'):
658
- try:
659
- self.scale_out(blocks=self.provider.init_blocks)
660
- except Exception as e:
661
- logger.error("Initial block scaling out failed: {}".format(e))
662
- raise e
663
-
664
677
  @property
665
678
  def outstanding(self) -> int:
666
679
  """Count the number of outstanding tasks. This is inefficiently
@@ -682,8 +695,8 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
682
695
  """Scale in method.
683
696
  """
684
697
  # Obtain list of blocks to kill
685
- to_kill = list(self.blocks.keys())[:count]
686
- kill_ids = [self.blocks[block] for block in to_kill]
698
+ to_kill = list(self.blocks_to_job_id.keys())[:count]
699
+ kill_ids = [self.blocks_to_job_id[block] for block in to_kill]
687
700
 
688
701
  # Cancel the blocks provisioned
689
702
  if self.provider:
@@ -695,11 +708,19 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
695
708
  """Shutdown the executor. Sets flag to cancel the submit process and
696
709
  collector thread, which shuts down the Work Queue system submission.
697
710
  """
711
+ if not self.is_started:
712
+ # Don't shutdown if the executor never starts.
713
+ return
714
+
715
+ if self.is_shutdown:
716
+ # Don't shutdown this executor again.
717
+ return
718
+
698
719
  logger.debug("Work Queue shutdown started")
699
720
  self.should_stop.value = True
700
721
 
701
722
  # Remove the workers that are still going
702
- kill_ids = [self.blocks[block] for block in self.blocks.keys()]
723
+ kill_ids = [self.blocks_to_job_id[block] for block in self.blocks_to_job_id.keys()]
703
724
  if self.provider:
704
725
  logger.debug("Cancelling blocks")
705
726
  self.provider.cancel(kill_ids)
@@ -709,6 +730,7 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
709
730
  logger.debug("Joining on collector thread")
710
731
  self.collector_thread.join()
711
732
 
733
+ self.is_shutdown = True
712
734
  logger.debug("Work Queue shutdown completed")
713
735
 
714
736
  @wrap_with_logs
@@ -20,7 +20,7 @@ def simple_error_handler(executor: status_handling.BlockProviderExecutor, status
20
20
  executor.set_bad_state_and_fail_all(_get_error(status))
21
21
 
22
22
 
23
- def windowed_error_handler(executor: status_handling.BlockProviderExecutor, status: Dict[str, JobStatus], threshold: int = 3):
23
+ def windowed_error_handler(executor: status_handling.BlockProviderExecutor, status: Dict[str, JobStatus], threshold: int = 3) -> None:
24
24
  sorted_status = [(key, status[key]) for key in sorted(status, key=lambda x: int(x))]
25
25
  current_window = dict(sorted_status[-threshold:])
26
26
  total, failed = _count_jobs(current_window)
@@ -16,20 +16,21 @@ from parsl.utils import Timer
16
16
  logger = logging.getLogger(__name__)
17
17
 
18
18
 
19
- class PollItem:
19
+ class PolledExecutorFacade:
20
20
  def __init__(self, executor: BlockProviderExecutor, dfk: Optional["parsl.dataflow.dflow.DataFlowKernel"] = None):
21
21
  self._executor = executor
22
22
  self._dfk = dfk
23
23
  self._interval = executor.status_polling_interval
24
24
  self._last_poll_time = 0.0
25
25
  self._status = {} # type: Dict[str, JobStatus]
26
+ self.first = True
26
27
 
27
28
  # Create a ZMQ channel to send poll status to monitoring
28
29
  self.monitoring_enabled = False
29
30
  if self._dfk and self._dfk.monitoring is not None:
30
31
  self.monitoring_enabled = True
31
32
  hub_address = self._dfk.hub_address
32
- hub_port = self._dfk.hub_interchange_port
33
+ hub_port = self._dfk.hub_zmq_port
33
34
  context = zmq.Context()
34
35
  self.hub_channel = context.socket(zmq.DEALER)
35
36
  self.hub_channel.set_hwm(0)
@@ -72,7 +73,7 @@ class PollItem:
72
73
  def executor(self) -> BlockProviderExecutor:
73
74
  return self._executor
74
75
 
75
- def scale_in(self, n, max_idletime=None):
76
+ def scale_in(self, n: int, max_idletime: Optional[float] = None) -> List[str]:
76
77
 
77
78
  if max_idletime is None:
78
79
  block_ids = self._executor.scale_in(n)
@@ -82,7 +83,7 @@ class PollItem:
82
83
  # scale_in method really does come from HighThroughputExecutor,
83
84
  # and so does have an extra max_idletime parameter not present
84
85
  # in the executor interface.
85
- block_ids = self._executor.scale_in(n, max_idletime=max_idletime)
86
+ block_ids = self._executor.scale_in(n, max_idletime=max_idletime) # type: ignore[call-arg]
86
87
  if block_ids is not None:
87
88
  new_status = {}
88
89
  for block_id in block_ids:
@@ -91,7 +92,7 @@ class PollItem:
91
92
  self.send_monitoring_info(new_status)
92
93
  return block_ids
93
94
 
94
- def scale_out(self, n):
95
+ def scale_out(self, n: int) -> List[str]:
95
96
  block_ids = self._executor.scale_out(n)
96
97
  if block_ids is not None:
97
98
  new_status = {}
@@ -109,7 +110,7 @@ class JobStatusPoller(Timer):
109
110
  def __init__(self, *, strategy: Optional[str], max_idletime: float,
110
111
  strategy_period: Union[float, int],
111
112
  dfk: Optional["parsl.dataflow.dflow.DataFlowKernel"] = None) -> None:
112
- self._poll_items = [] # type: List[PollItem]
113
+ self._executor_facades = [] # type: List[PolledExecutorFacade]
113
114
  self.dfk = dfk
114
115
  self._strategy = Strategy(strategy=strategy,
115
116
  max_idletime=max_idletime)
@@ -117,21 +118,21 @@ class JobStatusPoller(Timer):
117
118
 
118
119
  def poll(self) -> None:
119
120
  self._update_state()
120
- self._run_error_handlers(self._poll_items)
121
- self._strategy.strategize(self._poll_items)
121
+ self._run_error_handlers(self._executor_facades)
122
+ self._strategy.strategize(self._executor_facades)
122
123
 
123
- def _run_error_handlers(self, status: List[PollItem]) -> None:
124
+ def _run_error_handlers(self, status: List[PolledExecutorFacade]) -> None:
124
125
  for es in status:
125
126
  es.executor.handle_errors(es.status)
126
127
 
127
128
  def _update_state(self) -> None:
128
129
  now = time.time()
129
- for item in self._poll_items:
130
+ for item in self._executor_facades:
130
131
  item.poll(now)
131
132
 
132
133
  def add_executors(self, executors: Sequence[BlockProviderExecutor]) -> None:
133
134
  for executor in executors:
134
135
  if executor.status_polling_interval > 0:
135
136
  logger.debug("Adding executor {}".format(executor.label))
136
- self._poll_items.append(PollItem(executor, self.dfk))
137
+ self._executor_facades.append(PolledExecutorFacade(executor, self.dfk))
137
138
  self._strategy.add_executors(executors)