parsl 2024.3.25__tar.gz → 2024.4.8__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 (459) hide show
  1. {parsl-2024.3.25/parsl.egg-info → parsl-2024.4.8}/PKG-INFO +2 -2
  2. {parsl-2024.3.25 → parsl-2024.4.8}/README.rst +1 -0
  3. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/dataflow/dflow.py +16 -34
  4. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/base.py +1 -1
  5. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/high_throughput/executor.py +8 -20
  6. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/high_throughput/process_worker_pool.py +5 -2
  7. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/status_handling.py +7 -14
  8. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/taskvine/executor.py +17 -13
  9. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/workqueue/executor.py +17 -14
  10. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/jobs/job_status_poller.py +26 -11
  11. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/jobs/strategy.py +36 -19
  12. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/monitoring.py +1 -20
  13. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/remote.py +2 -1
  14. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/site_tests/test_provider.py +1 -1
  15. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_htex/test_disconnected_blocks.py +0 -1
  16. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_htex/test_drain.py +1 -0
  17. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_monitoring/test_htex_init_blocks_vs_monitoring.py +9 -6
  18. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_context_manager.py +3 -3
  19. parsl-2024.4.8/parsl/tests/test_scaling/test_shutdown_scalein.py +78 -0
  20. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/version.py +1 -1
  21. {parsl-2024.3.25 → parsl-2024.4.8/parsl.egg-info}/PKG-INFO +2 -2
  22. {parsl-2024.3.25 → parsl-2024.4.8}/parsl.egg-info/SOURCES.txt +5 -5
  23. parsl-2024.3.25/parsl/usage_tracking/__init__.py +0 -0
  24. {parsl-2024.3.25 → parsl-2024.4.8}/LICENSE +0 -0
  25. {parsl-2024.3.25 → parsl-2024.4.8}/MANIFEST.in +0 -0
  26. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/__init__.py +0 -0
  27. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/addresses.py +0 -0
  28. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/app/__init__.py +0 -0
  29. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/app/app.py +0 -0
  30. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/app/bash.py +0 -0
  31. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/app/errors.py +0 -0
  32. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/app/futures.py +0 -0
  33. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/app/python.py +0 -0
  34. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/benchmark/__init__.py +0 -0
  35. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/benchmark/perf.py +0 -0
  36. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/channels/__init__.py +0 -0
  37. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/channels/base.py +0 -0
  38. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/channels/errors.py +0 -0
  39. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/channels/local/__init__.py +0 -0
  40. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/channels/local/local.py +0 -0
  41. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/channels/oauth_ssh/__init__.py +0 -0
  42. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/channels/oauth_ssh/oauth_ssh.py +0 -0
  43. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/channels/ssh/__init__.py +0 -0
  44. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/channels/ssh/ssh.py +0 -0
  45. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/channels/ssh_il/__init__.py +0 -0
  46. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/channels/ssh_il/ssh_il.py +0 -0
  47. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/concurrent/__init__.py +0 -0
  48. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/config.py +0 -0
  49. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/configs/ASPIRE1.py +0 -0
  50. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/configs/Azure.py +0 -0
  51. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/configs/__init__.py +0 -0
  52. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/configs/ad_hoc.py +0 -0
  53. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/configs/bridges.py +0 -0
  54. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/configs/cc_in2p3.py +0 -0
  55. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/configs/ec2.py +0 -0
  56. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/configs/expanse.py +0 -0
  57. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/configs/frontera.py +0 -0
  58. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/configs/htex_local.py +0 -0
  59. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/configs/illinoiscluster.py +0 -0
  60. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/configs/kubernetes.py +0 -0
  61. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/configs/local_threads.py +0 -0
  62. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/configs/midway.py +0 -0
  63. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/configs/osg.py +0 -0
  64. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/configs/polaris.py +0 -0
  65. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/configs/stampede2.py +0 -0
  66. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/configs/summit.py +0 -0
  67. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/configs/toss3_llnl.py +0 -0
  68. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/configs/vineex_local.py +0 -0
  69. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/configs/wqex_local.py +0 -0
  70. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/curvezmq.py +0 -0
  71. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/data_provider/__init__.py +0 -0
  72. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/data_provider/data_manager.py +0 -0
  73. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/data_provider/file_noop.py +0 -0
  74. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/data_provider/files.py +0 -0
  75. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/data_provider/ftp.py +0 -0
  76. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/data_provider/globus.py +0 -0
  77. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/data_provider/http.py +0 -0
  78. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/data_provider/rsync.py +0 -0
  79. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/data_provider/staging.py +0 -0
  80. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/dataflow/__init__.py +0 -0
  81. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/dataflow/errors.py +0 -0
  82. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/dataflow/futures.py +0 -0
  83. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/dataflow/memoization.py +0 -0
  84. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/dataflow/rundirs.py +0 -0
  85. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/dataflow/states.py +0 -0
  86. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/dataflow/taskrecord.py +0 -0
  87. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/errors.py +0 -0
  88. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/__init__.py +0 -0
  89. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/errors.py +0 -0
  90. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/flux/__init__.py +0 -0
  91. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/flux/execute_parsl_task.py +0 -0
  92. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/flux/executor.py +0 -0
  93. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/flux/flux_instance_manager.py +0 -0
  94. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/high_throughput/__init__.py +0 -0
  95. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/high_throughput/errors.py +0 -0
  96. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/high_throughput/interchange.py +0 -0
  97. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/high_throughput/manager_record.py +0 -0
  98. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/high_throughput/monitoring_info.py +0 -0
  99. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/high_throughput/mpi_prefix_composer.py +0 -0
  100. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/high_throughput/mpi_resource_management.py +0 -0
  101. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/high_throughput/probe.py +0 -0
  102. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/high_throughput/zmq_pipes.py +0 -0
  103. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/radical/__init__.py +0 -0
  104. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/radical/executor.py +0 -0
  105. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/radical/rpex_master.py +0 -0
  106. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/radical/rpex_resources.py +0 -0
  107. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/radical/rpex_worker.py +0 -0
  108. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/taskvine/__init__.py +0 -0
  109. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/taskvine/errors.py +0 -0
  110. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/taskvine/exec_parsl_function.py +0 -0
  111. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/taskvine/factory.py +0 -0
  112. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/taskvine/factory_config.py +0 -0
  113. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/taskvine/manager.py +0 -0
  114. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/taskvine/manager_config.py +0 -0
  115. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/taskvine/utils.py +0 -0
  116. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/threads.py +0 -0
  117. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/workqueue/__init__.py +0 -0
  118. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/workqueue/errors.py +0 -0
  119. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/workqueue/exec_parsl_function.py +0 -0
  120. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/workqueue/parsl_coprocess.py +0 -0
  121. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/executors/workqueue/parsl_coprocess_stub.py +0 -0
  122. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/jobs/__init__.py +0 -0
  123. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/jobs/error_handlers.py +0 -0
  124. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/jobs/errors.py +0 -0
  125. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/jobs/states.py +0 -0
  126. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/launchers/__init__.py +0 -0
  127. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/launchers/base.py +0 -0
  128. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/launchers/errors.py +0 -0
  129. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/launchers/launchers.py +0 -0
  130. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/log_utils.py +0 -0
  131. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/__init__.py +0 -0
  132. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/db_manager.py +0 -0
  133. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/message_type.py +0 -0
  134. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/queries/__init__.py +0 -0
  135. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/queries/pandas.py +0 -0
  136. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/radios.py +0 -0
  137. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/router.py +0 -0
  138. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/types.py +0 -0
  139. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/visualization/__init__.py +0 -0
  140. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/visualization/app.py +0 -0
  141. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/visualization/models.py +0 -0
  142. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/visualization/plots/__init__.py +0 -0
  143. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/visualization/plots/default/__init__.py +0 -0
  144. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/visualization/plots/default/task_plots.py +0 -0
  145. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/visualization/plots/default/workflow_plots.py +0 -0
  146. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/visualization/plots/default/workflow_resource_plots.py +0 -0
  147. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/visualization/static/parsl-logo-white.png +0 -0
  148. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/visualization/static/parsl-monitor.css +0 -0
  149. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/visualization/templates/app.html +0 -0
  150. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/visualization/templates/dag.html +0 -0
  151. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/visualization/templates/error.html +0 -0
  152. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/visualization/templates/layout.html +0 -0
  153. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/visualization/templates/resource_usage.html +0 -0
  154. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/visualization/templates/task.html +0 -0
  155. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/visualization/templates/workflow.html +0 -0
  156. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/visualization/templates/workflows_summary.html +0 -0
  157. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/visualization/utils.py +0 -0
  158. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/visualization/version.py +0 -0
  159. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/monitoring/visualization/views.py +0 -0
  160. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/multiprocessing.py +0 -0
  161. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/process_loggers.py +0 -0
  162. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/__init__.py +0 -0
  163. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/ad_hoc/__init__.py +0 -0
  164. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/ad_hoc/ad_hoc.py +0 -0
  165. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/aws/__init__.py +0 -0
  166. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/aws/aws.py +0 -0
  167. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/aws/template.py +0 -0
  168. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/azure/__init__.py +0 -0
  169. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/azure/azure.py +0 -0
  170. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/azure/template.py +0 -0
  171. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/base.py +0 -0
  172. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/cluster_provider.py +0 -0
  173. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/cobalt/__init__.py +0 -0
  174. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/cobalt/cobalt.py +0 -0
  175. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/cobalt/template.py +0 -0
  176. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/condor/__init__.py +0 -0
  177. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/condor/condor.py +0 -0
  178. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/condor/template.py +0 -0
  179. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/errors.py +0 -0
  180. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/googlecloud/__init__.py +0 -0
  181. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/googlecloud/googlecloud.py +0 -0
  182. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/grid_engine/__init__.py +0 -0
  183. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/grid_engine/grid_engine.py +0 -0
  184. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/grid_engine/template.py +0 -0
  185. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/kubernetes/__init__.py +0 -0
  186. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/kubernetes/kube.py +0 -0
  187. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/kubernetes/template.py +0 -0
  188. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/local/__init__.py +0 -0
  189. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/local/local.py +0 -0
  190. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/lsf/__init__.py +0 -0
  191. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/lsf/lsf.py +0 -0
  192. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/lsf/template.py +0 -0
  193. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/pbspro/__init__.py +0 -0
  194. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/pbspro/pbspro.py +0 -0
  195. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/pbspro/template.py +0 -0
  196. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/slurm/__init__.py +0 -0
  197. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/slurm/slurm.py +0 -0
  198. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/slurm/template.py +0 -0
  199. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/torque/__init__.py +0 -0
  200. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/torque/template.py +0 -0
  201. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/providers/torque/torque.py +0 -0
  202. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/py.typed +0 -0
  203. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/serialize/__init__.py +0 -0
  204. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/serialize/base.py +0 -0
  205. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/serialize/concretes.py +0 -0
  206. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/serialize/errors.py +0 -0
  207. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/serialize/facade.py +0 -0
  208. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/serialize/proxystore.py +0 -0
  209. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/__init__.py +0 -0
  210. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/callables_helper.py +0 -0
  211. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/__init__.py +0 -0
  212. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/ad_hoc_cluster_htex.py +0 -0
  213. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/azure_single_node.py +0 -0
  214. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/bluewaters.py +0 -0
  215. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/bridges.py +0 -0
  216. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/cc_in2p3.py +0 -0
  217. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/comet.py +0 -0
  218. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/cooley_htex.py +0 -0
  219. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/ec2_single_node.py +0 -0
  220. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/ec2_spot.py +0 -0
  221. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/frontera.py +0 -0
  222. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/htex_ad_hoc_cluster.py +0 -0
  223. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/htex_local.py +0 -0
  224. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/htex_local_alternate.py +0 -0
  225. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/htex_local_intask_staging.py +0 -0
  226. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/htex_local_rsync_staging.py +0 -0
  227. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/local_adhoc.py +0 -0
  228. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/local_radical.py +0 -0
  229. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/local_radical_mpi.py +0 -0
  230. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/local_threads.py +0 -0
  231. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/local_threads_checkpoint.py +0 -0
  232. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/local_threads_checkpoint_dfk_exit.py +0 -0
  233. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/local_threads_checkpoint_periodic.py +0 -0
  234. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/local_threads_checkpoint_task_exit.py +0 -0
  235. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/local_threads_ftp_in_task.py +0 -0
  236. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/local_threads_globus.py +0 -0
  237. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/local_threads_http_in_task.py +0 -0
  238. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/local_threads_monitoring.py +0 -0
  239. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/local_threads_no_cache.py +0 -0
  240. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/midway.py +0 -0
  241. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/nscc_singapore.py +0 -0
  242. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/osg_htex.py +0 -0
  243. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/petrelkube.py +0 -0
  244. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/summit.py +0 -0
  245. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/swan_htex.py +0 -0
  246. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/taskvine_ex.py +0 -0
  247. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/theta.py +0 -0
  248. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/user_opts.py +0 -0
  249. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/configs/workqueue_ex.py +0 -0
  250. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/conftest.py +0 -0
  251. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/integration/__init__.py +0 -0
  252. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/integration/latency.py +0 -0
  253. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/integration/test_apps/__init__.py +0 -0
  254. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/integration/test_channels/__init__.py +0 -0
  255. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/integration/test_channels/test_channels.py +0 -0
  256. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/integration/test_channels/test_local_channel.py +0 -0
  257. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/integration/test_channels/test_scp_1.py +0 -0
  258. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/integration/test_channels/test_ssh_1.py +0 -0
  259. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/integration/test_channels/test_ssh_errors.py +0 -0
  260. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/integration/test_channels/test_ssh_file_transport.py +0 -0
  261. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/integration/test_channels/test_ssh_interactive.py +0 -0
  262. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/integration/test_parsl_load_default_config.py +0 -0
  263. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/integration/test_stress/__init__.py +0 -0
  264. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/integration/test_stress/test_python_simple.py +0 -0
  265. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/integration/test_stress/test_python_threads.py +0 -0
  266. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/manual_tests/__init__.py +0 -0
  267. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/manual_tests/htex_local.py +0 -0
  268. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/manual_tests/test_ad_hoc_htex.py +0 -0
  269. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/manual_tests/test_basic.py +0 -0
  270. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/manual_tests/test_fan_in_out_htex_remote.py +0 -0
  271. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/manual_tests/test_log_filter.py +0 -0
  272. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/manual_tests/test_memory_limits.py +0 -0
  273. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/manual_tests/test_oauth_ssh.py +0 -0
  274. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/manual_tests/test_regression_220.py +0 -0
  275. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/manual_tests/test_udp_simple.py +0 -0
  276. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/manual_tests/test_worker_count.py +0 -0
  277. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/scaling_tests/__init__.py +0 -0
  278. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/scaling_tests/htex_local.py +0 -0
  279. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/scaling_tests/local_threads.py +0 -0
  280. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/scaling_tests/test_scale.py +0 -0
  281. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/scaling_tests/vineex_condor.py +0 -0
  282. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/scaling_tests/vineex_local.py +0 -0
  283. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/scaling_tests/wqex_condor.py +0 -0
  284. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/scaling_tests/wqex_local.py +0 -0
  285. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/site_tests/__init__.py +0 -0
  286. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/site_tests/site_config_selector.py +0 -0
  287. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/site_tests/test_site.py +0 -0
  288. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/sites/__init__.py +0 -0
  289. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/sites/test_affinity.py +0 -0
  290. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/sites/test_concurrent.py +0 -0
  291. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/sites/test_dynamic_executor.py +0 -0
  292. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/sites/test_ec2.py +0 -0
  293. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/sites/test_launchers.py +0 -0
  294. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/sites/test_local_adhoc.py +0 -0
  295. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/sites/test_mpi/__init__.py +0 -0
  296. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/sites/test_worker_info.py +0 -0
  297. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_aalst_patterns.py +0 -0
  298. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_bash_apps/__init__.py +0 -0
  299. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_bash_apps/test_apptimeout.py +0 -0
  300. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_bash_apps/test_basic.py +0 -0
  301. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_bash_apps/test_error_codes.py +0 -0
  302. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_bash_apps/test_keyword_overlaps.py +0 -0
  303. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_bash_apps/test_kwarg_storage.py +0 -0
  304. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_bash_apps/test_memoize.py +0 -0
  305. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_bash_apps/test_memoize_ignore_args.py +0 -0
  306. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_bash_apps/test_memoize_ignore_args_regr.py +0 -0
  307. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_bash_apps/test_multiline.py +0 -0
  308. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_bash_apps/test_pipeline.py +0 -0
  309. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_bash_apps/test_stdout.py +0 -0
  310. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_callables.py +0 -0
  311. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_channels/__init__.py +0 -0
  312. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_channels/test_large_output.py +0 -0
  313. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_checkpointing/__init__.py +0 -0
  314. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_checkpointing/test_periodic.py +0 -0
  315. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_checkpointing/test_python_checkpoint_1.py +0 -0
  316. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_checkpointing/test_python_checkpoint_2.py +0 -0
  317. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_checkpointing/test_python_checkpoint_3.py +0 -0
  318. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_checkpointing/test_regression_232.py +0 -0
  319. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_checkpointing/test_regression_233.py +0 -0
  320. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_checkpointing/test_regression_239.py +0 -0
  321. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_checkpointing/test_task_exit.py +0 -0
  322. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_curvezmq.py +0 -0
  323. {parsl-2024.3.25/parsl/tests/test_data → parsl-2024.4.8/parsl/tests/test_docs}/__init__.py +0 -0
  324. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_docs/test_from_slides.py +0 -0
  325. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_docs/test_kwargs.py +0 -0
  326. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_docs/test_tutorial_1.py +0 -0
  327. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_docs/test_workflow1.py +0 -0
  328. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_docs/test_workflow2.py +0 -0
  329. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_docs/test_workflow4.py +0 -0
  330. {parsl-2024.3.25/parsl/tests/test_docs → parsl-2024.4.8/parsl/tests/test_error_handling}/__init__.py +0 -0
  331. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_error_handling/test_fail.py +0 -0
  332. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_error_handling/test_python_walltime.py +0 -0
  333. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_error_handling/test_rand_fail.py +0 -0
  334. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_error_handling/test_resource_spec.py +0 -0
  335. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_error_handling/test_retries.py +0 -0
  336. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_error_handling/test_retry_handler.py +0 -0
  337. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_error_handling/test_retry_handler_failure.py +0 -0
  338. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_error_handling/test_serialization_fail.py +0 -0
  339. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_error_handling/test_wrap_with_logs.py +0 -0
  340. {parsl-2024.3.25/parsl/tests/test_error_handling → parsl-2024.4.8/parsl/tests/test_flowcontrol}/__init__.py +0 -0
  341. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_flux.py +0 -0
  342. {parsl-2024.3.25/parsl/tests/test_flowcontrol → parsl-2024.4.8/parsl/tests/test_htex}/__init__.py +0 -0
  343. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_htex/test_basic.py +0 -0
  344. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_htex/test_connected_blocks.py +0 -0
  345. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_htex/test_cpu_affinity_explicit.py +0 -0
  346. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_htex/test_htex.py +0 -0
  347. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_htex/test_manager_failure.py +0 -0
  348. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_htex/test_missing_worker.py +0 -0
  349. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_htex/test_multiple_disconnected_blocks.py +0 -0
  350. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_htex/test_worker_failure.py +0 -0
  351. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_htex/test_zmq_binding.py +0 -0
  352. {parsl-2024.3.25/parsl/tests/test_htex → parsl-2024.4.8/parsl/tests/test_monitoring}/__init__.py +0 -0
  353. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_monitoring/test_app_names.py +0 -0
  354. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_monitoring/test_basic.py +0 -0
  355. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_monitoring/test_db_locks.py +0 -0
  356. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_monitoring/test_fuzz_zmq.py +0 -0
  357. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_monitoring/test_incomplete_futures.py +0 -0
  358. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_monitoring/test_memoization_representation.py +0 -0
  359. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_monitoring/test_viz_colouring.py +0 -0
  360. {parsl-2024.3.25/parsl/tests/test_monitoring → parsl-2024.4.8/parsl/tests/test_mpi_apps}/__init__.py +0 -0
  361. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_mpi_apps/test_bad_mpi_config.py +0 -0
  362. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_mpi_apps/test_mpi_mode_disabled.py +0 -0
  363. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_mpi_apps/test_mpi_mode_enabled.py +0 -0
  364. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_mpi_apps/test_mpi_prefix.py +0 -0
  365. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_mpi_apps/test_mpi_scheduler.py +0 -0
  366. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_mpi_apps/test_resource_spec.py +0 -0
  367. {parsl-2024.3.25/parsl/tests/test_mpi_apps → parsl-2024.4.8/parsl/tests/test_providers}/__init__.py +0 -0
  368. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_providers/test_cobalt_deprecation_warning.py +0 -0
  369. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_providers/test_local_provider.py +0 -0
  370. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_providers/test_pbspro_template.py +0 -0
  371. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_providers/test_slurm_instantiate.py +0 -0
  372. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_providers/test_slurm_template.py +0 -0
  373. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_providers/test_submiterror_deprecation.py +0 -0
  374. {parsl-2024.3.25/parsl/tests/test_providers → parsl-2024.4.8/parsl/tests/test_python_apps}/__init__.py +0 -0
  375. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_arg_input_types.py +0 -0
  376. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_basic.py +0 -0
  377. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_dep_standard_futures.py +0 -0
  378. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_dependencies.py +0 -0
  379. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_depfail_propagation.py +0 -0
  380. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_fail.py +0 -0
  381. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_fibonacci_iterative.py +0 -0
  382. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_fibonacci_recursive.py +0 -0
  383. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_futures.py +0 -0
  384. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_garbage_collect.py +0 -0
  385. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_import_fail.py +0 -0
  386. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_join.py +0 -0
  387. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_lifted.py +0 -0
  388. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_mapred.py +0 -0
  389. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_memoize_1.py +0 -0
  390. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_memoize_2.py +0 -0
  391. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_memoize_4.py +0 -0
  392. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_memoize_bad_id_for_memo.py +0 -0
  393. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_memoize_ignore_args.py +0 -0
  394. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_memoize_joinapp.py +0 -0
  395. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_outputs.py +0 -0
  396. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_overview.py +0 -0
  397. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_pipeline.py +0 -0
  398. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_simple.py +0 -0
  399. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_timeout.py +0 -0
  400. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_python_apps/test_type5.py +0 -0
  401. {parsl-2024.3.25/parsl/tests/test_python_apps → parsl-2024.4.8/parsl/tests/test_radical}/__init__.py +0 -0
  402. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_radical/test_mpi_funcs.py +0 -0
  403. {parsl-2024.3.25/parsl/tests/test_radical → parsl-2024.4.8/parsl/tests/test_regression}/__init__.py +0 -0
  404. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_regression/test_1480.py +0 -0
  405. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_regression/test_1606_wait_for_current_tasks.py +0 -0
  406. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_regression/test_1653.py +0 -0
  407. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_regression/test_221.py +0 -0
  408. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_regression/test_226.py +0 -0
  409. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_regression/test_2652.py +0 -0
  410. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_regression/test_69a.py +0 -0
  411. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_regression/test_854.py +0 -0
  412. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_regression/test_97_parallelism_0.py +0 -0
  413. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_regression/test_98.py +0 -0
  414. {parsl-2024.3.25/parsl/tests/test_regression → parsl-2024.4.8/parsl/tests/test_scaling}/__init__.py +0 -0
  415. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_scaling/test_block_error_handler.py +0 -0
  416. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_scaling/test_regression_1621.py +0 -0
  417. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_scaling/test_scale_down.py +0 -0
  418. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_scaling/test_scale_down_htex_auto_scale.py +0 -0
  419. {parsl-2024.3.25/parsl/tests/test_scaling → parsl-2024.4.8/parsl/tests/test_serialization}/__init__.py +0 -0
  420. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_serialization/test_2555_caching_deserializer.py +0 -0
  421. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_serialization/test_basic.py +0 -0
  422. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_serialization/test_htex_code_cache.py +0 -0
  423. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_serialization/test_pack_resource_spec.py +0 -0
  424. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_serialization/test_proxystore_configured.py +0 -0
  425. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_serialization/test_proxystore_impl.py +0 -0
  426. {parsl-2024.3.25/parsl/tests/test_serialization → parsl-2024.4.8/parsl/tests/test_shutdown}/__init__.py +0 -0
  427. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_shutdown/test_kill_monitoring.py +0 -0
  428. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_staging/__init__.py +0 -0
  429. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_staging/staging_provider.py +0 -0
  430. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_staging/test_1316.py +0 -0
  431. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_staging/test_docs_1.py +0 -0
  432. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_staging/test_docs_2.py +0 -0
  433. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_staging/test_elaborate_noop_file.py +0 -0
  434. {parsl-2024.3.25/parsl/tests/test_data → parsl-2024.4.8/parsl/tests/test_staging}/test_file.py +0 -0
  435. {parsl-2024.3.25/parsl/tests/test_data → parsl-2024.4.8/parsl/tests/test_staging}/test_file_apps.py +0 -0
  436. {parsl-2024.3.25/parsl/tests/test_data → parsl-2024.4.8/parsl/tests/test_staging}/test_file_staging.py +0 -0
  437. {parsl-2024.3.25/parsl/tests/test_data → parsl-2024.4.8/parsl/tests/test_staging}/test_output_chain_filenames.py +0 -0
  438. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_staging/test_staging_ftp.py +0 -0
  439. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_staging/test_staging_ftp_in_task.py +0 -0
  440. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_staging/test_staging_globus.py +0 -0
  441. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_staging/test_staging_https.py +0 -0
  442. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_summary.py +0 -0
  443. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_thread_parallelism.py +0 -0
  444. {parsl-2024.3.25/parsl/tests/test_shutdown → parsl-2024.4.8/parsl/tests/test_threads}/__init__.py +0 -0
  445. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_threads/test_configs.py +0 -0
  446. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_threads/test_lazy_errors.py +0 -0
  447. {parsl-2024.3.25/parsl/tests/test_threads → parsl-2024.4.8/parsl/tests/test_utils}/__init__.py +0 -0
  448. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/test_utils/test_representation_mixin.py +0 -0
  449. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/tests/utils.py +0 -0
  450. {parsl-2024.3.25/parsl/tests/test_utils → parsl-2024.4.8/parsl/usage_tracking}/__init__.py +0 -0
  451. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/usage_tracking/usage.py +0 -0
  452. {parsl-2024.3.25 → parsl-2024.4.8}/parsl/utils.py +0 -0
  453. {parsl-2024.3.25 → parsl-2024.4.8}/parsl.egg-info/dependency_links.txt +0 -0
  454. {parsl-2024.3.25 → parsl-2024.4.8}/parsl.egg-info/entry_points.txt +0 -0
  455. {parsl-2024.3.25 → parsl-2024.4.8}/parsl.egg-info/requires.txt +0 -0
  456. {parsl-2024.3.25 → parsl-2024.4.8}/parsl.egg-info/top_level.txt +0 -0
  457. {parsl-2024.3.25 → parsl-2024.4.8}/requirements.txt +0 -0
  458. {parsl-2024.3.25 → parsl-2024.4.8}/setup.cfg +0 -0
  459. {parsl-2024.3.25 → parsl-2024.4.8}/setup.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: parsl
3
- Version: 2024.3.25
3
+ Version: 2024.4.8
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.25.tar.gz
6
+ Download-URL: https://github.com/Parsl/parsl/archive/2024.04.08.tar.gz
7
7
  Author: The Parsl Team
8
8
  Author-email: parsl@googlegroups.com
9
9
  License: Apache 2.0
@@ -97,6 +97,7 @@ For Developers
97
97
 
98
98
  2. Build and Test::
99
99
 
100
+ $ cd parsl # navigate to the root directory of the project
100
101
  $ make # show all available makefile targets
101
102
  $ make virtualenv # create a virtual environment
102
103
  $ source .venv/bin/activate # activate the virtual environment
@@ -34,12 +34,12 @@ from parsl.dataflow.states import States, FINAL_STATES, FINAL_FAILURE_STATES
34
34
  from parsl.dataflow.taskrecord import TaskRecord
35
35
  from parsl.errors import ConfigurationError, InternalConsistencyError, NoDataFlowKernelError
36
36
  from parsl.jobs.job_status_poller import JobStatusPoller
37
- from parsl.jobs.states import JobStatus, JobState
38
37
  from parsl.usage_tracking.usage import UsageTracker
39
38
  from parsl.executors.base import ParslExecutor
40
39
  from parsl.executors.status_handling import BlockProviderExecutor
41
40
  from parsl.executors.threads import ThreadPoolExecutor
42
41
  from parsl.monitoring import MonitoringHub
42
+ from parsl.monitoring.remote import monitor_wrapper
43
43
  from parsl.process_loggers import wrap_with_logs
44
44
  from parsl.providers.base import ExecutionProvider
45
45
  from parsl.utils import get_version, get_std_fname_mode, get_all_checkpoints, Timer
@@ -207,7 +207,7 @@ class DataFlowKernel:
207
207
  atexit.register(self.atexit_cleanup)
208
208
 
209
209
  def __enter__(self):
210
- pass
210
+ return self
211
211
 
212
212
  def __exit__(self, exc_type, exc_value, traceback):
213
213
  logger.debug("Exiting the context manager, calling cleanup for DFK")
@@ -714,14 +714,18 @@ class DataFlowKernel:
714
714
 
715
715
  if self.monitoring is not None and self.monitoring.resource_monitoring_enabled:
716
716
  wrapper_logging_level = logging.DEBUG if self.monitoring.monitoring_debug else logging.INFO
717
- (function, args, kwargs) = self.monitoring.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)
717
+ (function, args, kwargs) = monitor_wrapper(f=function,
718
+ args=args,
719
+ kwargs=kwargs,
720
+ x_try_id=try_id,
721
+ x_task_id=task_id,
722
+ monitoring_hub_url=self.monitoring.monitoring_hub_url,
723
+ run_id=self.run_id,
724
+ logging_level=wrapper_logging_level,
725
+ sleep_dur=self.monitoring.resource_monitoring_interval,
726
+ radio_mode=executor.radio_mode,
727
+ monitor_resources=executor.monitor_resources(),
728
+ run_dir=self.run_dir)
725
729
 
726
730
  with self.submitter_lock:
727
731
  exec_fu = executor.submit(function, task_record['resource_specification'], *args, **kwargs)
@@ -1141,14 +1145,7 @@ class DataFlowKernel:
1141
1145
  self._create_remote_dirs_over_channel(executor.provider, executor.provider.channel)
1142
1146
 
1143
1147
  self.executors[executor.label] = executor
1144
- block_ids = executor.start()
1145
- if self.monitoring and block_ids:
1146
- new_status = {}
1147
- for bid in block_ids:
1148
- new_status[bid] = JobStatus(JobState.PENDING)
1149
- msg = executor.create_monitoring_info(new_status)
1150
- logger.debug("Sending monitoring message {} to hub from DFK".format(msg))
1151
- self.monitoring.send(MessageType.BLOCK_INFO, msg)
1148
+ executor.start()
1152
1149
  block_executors = [e for e in executors if isinstance(e, BlockProviderExecutor)]
1153
1150
  self.job_status_poller.add_executors(block_executors)
1154
1151
 
@@ -1221,24 +1218,9 @@ class DataFlowKernel:
1221
1218
  self.job_status_poller.close()
1222
1219
  logger.info("Terminated job status poller")
1223
1220
 
1224
- logger.info("Scaling in and shutting down executors")
1221
+ logger.info("Shutting down executors")
1225
1222
 
1226
1223
  for executor in self.executors.values():
1227
- if isinstance(executor, BlockProviderExecutor):
1228
- if not executor.bad_state_is_set:
1229
- logger.info(f"Scaling in executor {executor.label}")
1230
- if executor.provider:
1231
- job_ids = executor.provider.resources.keys()
1232
- block_ids = executor.scale_in(len(job_ids))
1233
- if self.monitoring and block_ids:
1234
- new_status = {}
1235
- for bid in block_ids:
1236
- new_status[bid] = JobStatus(JobState.CANCELLED)
1237
- msg = executor.create_monitoring_info(new_status)
1238
- logger.debug("Sending message {} to hub from DFK".format(msg))
1239
- self.monitoring.send(MessageType.BLOCK_INFO, msg)
1240
- else: # and bad_state_is_set
1241
- logger.warning(f"Not shutting down executor {executor.label} because it is in bad state")
1242
1224
  logger.info(f"Shutting down executor {executor.label}")
1243
1225
  executor.shutdown()
1244
1226
  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.
@@ -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
 
@@ -68,8 +68,8 @@ class BlockProviderExecutor(ParslExecutor):
68
68
  self._block_id_counter = AtomicIDCounter()
69
69
 
70
70
  self._tasks = {} # type: Dict[object, Future]
71
- self.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,12 +102,6 @@ class BlockProviderExecutor(ParslExecutor):
102
102
  else:
103
103
  return self._provider.status_polling_interval
104
104
 
105
- def _fail_job_async(self, block_id: str, message: str):
106
- """Marks a job that has failed to start but would not otherwise be included in status()
107
- as failed and report it in status()
108
- """
109
- self._simulated_status[block_id] = JobStatus(JobState.FAILED, message)
110
-
111
105
  @abstractproperty
112
106
  def outstanding(self) -> int:
113
107
  """This should return the number of tasks that the executor has been given to run (waiting to run, and running now)"""
@@ -194,12 +188,11 @@ class BlockProviderExecutor(ParslExecutor):
194
188
  logger.info(f"Allocated block ID {block_id}")
195
189
  try:
196
190
  job_id = self._launch_block(block_id)
197
- self.blocks[block_id] = job_id
198
- self.block_mapping[job_id] = block_id
191
+ self.blocks_to_job_id[block_id] = job_id
192
+ self.job_ids_to_block[job_id] = block_id
199
193
  block_ids.append(block_id)
200
194
  except Exception as ex:
201
- self._fail_job_async(block_id,
202
- "Failed to start block {}: {}".format(block_id, ex))
195
+ self._simulated_status[block_id] = JobStatus(JobState.FAILED, "Failed to start block {}: {}".format(block_id, ex))
203
196
  return block_ids
204
197
 
205
198
  @abstractmethod
@@ -232,10 +225,10 @@ class BlockProviderExecutor(ParslExecutor):
232
225
  # Not using self.blocks.keys() and self.blocks.values() simultaneously
233
226
  # The dictionary may be changed during invoking this function
234
227
  # As scale_in and scale_out are invoked in multiple threads
235
- block_ids = list(self.blocks.keys())
228
+ block_ids = list(self.blocks_to_job_id.keys())
236
229
  job_ids = [] # types: List[Any]
237
230
  for bid in block_ids:
238
- job_ids.append(self.blocks[bid])
231
+ job_ids.append(self.blocks_to_job_id[bid])
239
232
  return block_ids, job_ids
240
233
 
241
234
  @abstractproperty
@@ -186,7 +186,13 @@ class TaskVineExecutor(BlockProviderExecutor, putils.RepresentationMixin):
186
186
  # Attribute indicating whether this executor was started to shut it down properly.
187
187
  # This safeguards cases where an object of this executor is created but
188
188
  # the executor never starts, so it shouldn't be shutdowned.
189
- self._started = False
189
+ self._is_started = False
190
+
191
+ # Attribute indicating whether this executor was shutdown before.
192
+ # This safeguards cases where this object is automatically shut down (e.g.,
193
+ # via atexit) and the user also explicitly calls shut down. While this is
194
+ # permitted, the effect of an executor shutdown should happen only once.
195
+ self._is_shutdown = False
190
196
 
191
197
  def atexit_cleanup(self):
192
198
  # Calls this executor's shutdown method upon Python exiting the process.
@@ -252,7 +258,7 @@ class TaskVineExecutor(BlockProviderExecutor, putils.RepresentationMixin):
252
258
  """
253
259
 
254
260
  # Mark this executor object as started
255
- self._started = True
261
+ self._is_started = True
256
262
 
257
263
  # Synchronize connection and communication settings between the manager and factory
258
264
  self.__synchronize_manager_factory_comm_settings()
@@ -580,13 +586,6 @@ class TaskVineExecutor(BlockProviderExecutor, putils.RepresentationMixin):
580
586
  self._worker_command = self._construct_worker_command()
581
587
  self._patch_providers()
582
588
 
583
- if hasattr(self.provider, 'init_blocks'):
584
- try:
585
- self.scale_out(blocks=self.provider.init_blocks)
586
- except Exception as e:
587
- logger.error("Initial block scaling out failed: {}".format(e))
588
- raise e
589
-
590
589
  @property
591
590
  def outstanding(self) -> int:
592
591
  """Count the number of outstanding tasks."""
@@ -601,8 +600,8 @@ class TaskVineExecutor(BlockProviderExecutor, putils.RepresentationMixin):
601
600
  """Scale in method. Cancel a given number of blocks
602
601
  """
603
602
  # Obtain list of blocks to kill
604
- to_kill = list(self.blocks.keys())[:count]
605
- 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]
606
605
 
607
606
  # Cancel the blocks provisioned
608
607
  if self.provider:
@@ -614,15 +613,19 @@ class TaskVineExecutor(BlockProviderExecutor, putils.RepresentationMixin):
614
613
  """Shutdown the executor. Sets flag to cancel the submit process and
615
614
  collector thread, which shuts down the TaskVine system submission.
616
615
  """
617
- if not self._started:
616
+ if not self._is_started:
618
617
  # Don't shutdown if the executor never starts.
619
618
  return
620
619
 
620
+ if self._is_shutdown:
621
+ # Don't shutdown this executor again.
622
+ return
623
+
621
624
  logger.debug("TaskVine shutdown started")
622
625
  self._should_stop.set()
623
626
 
624
627
  # Remove the workers that are still going
625
- kill_ids = [self.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()]
626
629
  if self.provider:
627
630
  logger.debug("Cancelling blocks")
628
631
  self.provider.cancel(kill_ids)
@@ -636,6 +639,7 @@ class TaskVineExecutor(BlockProviderExecutor, putils.RepresentationMixin):
636
639
  logger.debug("Joining on factory process")
637
640
  self._factory_process.join()
638
641
 
642
+ self._is_shutdown = True
639
643
  logger.debug("TaskVine shutdown completed")
640
644
 
641
645
  @wrap_with_logs
@@ -255,7 +255,6 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
255
255
  self.label = label
256
256
  self.task_queue = multiprocessing.Queue() # type: multiprocessing.Queue
257
257
  self.collector_queue = multiprocessing.Queue() # type: multiprocessing.Queue
258
- self.blocks = {} # type: Dict[str, str]
259
258
  self.address = address
260
259
  self.port = port
261
260
  self.executor_task_counter = -1
@@ -305,7 +304,13 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
305
304
  # Attribute indicating whether this executor was started to shut it down properly.
306
305
  # This safeguards cases where an object of this executor is created but
307
306
  # the executor never starts, so it shouldn't be shutdowned.
308
- self.started = False
307
+ self.is_started = False
308
+
309
+ # Attribute indicating whether this executor was shutdown before.
310
+ # This safeguards cases where this object is automatically shut down (e.g.,
311
+ # via atexit) and the user also explicitly calls shut down. While this is
312
+ # permitted, the effect of an executor shutdown should happen only once.
313
+ self.is_shutdown = False
309
314
 
310
315
  def atexit_cleanup(self):
311
316
  # Calls this executor's shutdown method upon Python exiting the process.
@@ -321,7 +326,7 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
321
326
  retrieve Parsl tasks within the Work Queue system.
322
327
  """
323
328
  # Mark this executor object as started
324
- self.started = True
329
+ self.is_started = True
325
330
  self.tasks_lock = threading.Lock()
326
331
 
327
332
  # Create directories for data and results
@@ -669,13 +674,6 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
669
674
  self.worker_command = self._construct_worker_command()
670
675
  self._patch_providers()
671
676
 
672
- if hasattr(self.provider, 'init_blocks'):
673
- try:
674
- self.scale_out(blocks=self.provider.init_blocks)
675
- except Exception as e:
676
- logger.error("Initial block scaling out failed: {}".format(e))
677
- raise e
678
-
679
677
  @property
680
678
  def outstanding(self) -> int:
681
679
  """Count the number of outstanding tasks. This is inefficiently
@@ -697,8 +695,8 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
697
695
  """Scale in method.
698
696
  """
699
697
  # Obtain list of blocks to kill
700
- to_kill = list(self.blocks.keys())[:count]
701
- 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]
702
700
 
703
701
  # Cancel the blocks provisioned
704
702
  if self.provider:
@@ -710,15 +708,19 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
710
708
  """Shutdown the executor. Sets flag to cancel the submit process and
711
709
  collector thread, which shuts down the Work Queue system submission.
712
710
  """
713
- if not self.started:
711
+ if not self.is_started:
714
712
  # Don't shutdown if the executor never starts.
715
713
  return
716
714
 
715
+ if self.is_shutdown:
716
+ # Don't shutdown this executor again.
717
+ return
718
+
717
719
  logger.debug("Work Queue shutdown started")
718
720
  self.should_stop.value = True
719
721
 
720
722
  # Remove the workers that are still going
721
- kill_ids = [self.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()]
722
724
  if self.provider:
723
725
  logger.debug("Cancelling blocks")
724
726
  self.provider.cancel(kill_ids)
@@ -728,6 +730,7 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
728
730
  logger.debug("Joining on collector thread")
729
731
  self.collector_thread.join()
730
732
 
733
+ self.is_shutdown = True
731
734
  logger.debug("Work Queue shutdown completed")
732
735
 
733
736
  @wrap_with_logs
@@ -16,20 +16,19 @@ 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
- self._dfk = dfk
23
22
  self._interval = executor.status_polling_interval
24
23
  self._last_poll_time = 0.0
25
24
  self._status = {} # type: Dict[str, JobStatus]
26
25
 
27
26
  # Create a ZMQ channel to send poll status to monitoring
28
27
  self.monitoring_enabled = False
29
- if self._dfk and self._dfk.monitoring is not None:
28
+ if dfk and dfk.monitoring is not None:
30
29
  self.monitoring_enabled = True
31
- hub_address = self._dfk.hub_address
32
- hub_port = self._dfk.hub_zmq_port
30
+ hub_address = dfk.hub_address
31
+ hub_port = dfk.hub_zmq_port
33
32
  context = zmq.Context()
34
33
  self.hub_channel = context.socket(zmq.DEALER)
35
34
  self.hub_channel.set_hwm(0)
@@ -109,7 +108,7 @@ class JobStatusPoller(Timer):
109
108
  def __init__(self, *, strategy: Optional[str], max_idletime: float,
110
109
  strategy_period: Union[float, int],
111
110
  dfk: Optional["parsl.dataflow.dflow.DataFlowKernel"] = None) -> None:
112
- self._poll_items = [] # type: List[PollItem]
111
+ self._executor_facades = [] # type: List[PolledExecutorFacade]
113
112
  self.dfk = dfk
114
113
  self._strategy = Strategy(strategy=strategy,
115
114
  max_idletime=max_idletime)
@@ -117,21 +116,37 @@ class JobStatusPoller(Timer):
117
116
 
118
117
  def poll(self) -> None:
119
118
  self._update_state()
120
- self._run_error_handlers(self._poll_items)
121
- self._strategy.strategize(self._poll_items)
119
+ self._run_error_handlers(self._executor_facades)
120
+ self._strategy.strategize(self._executor_facades)
122
121
 
123
- def _run_error_handlers(self, status: List[PollItem]) -> None:
122
+ def _run_error_handlers(self, status: List[PolledExecutorFacade]) -> None:
124
123
  for es in status:
125
124
  es.executor.handle_errors(es.status)
126
125
 
127
126
  def _update_state(self) -> None:
128
127
  now = time.time()
129
- for item in self._poll_items:
128
+ for item in self._executor_facades:
130
129
  item.poll(now)
131
130
 
132
131
  def add_executors(self, executors: Sequence[BlockProviderExecutor]) -> None:
133
132
  for executor in executors:
134
133
  if executor.status_polling_interval > 0:
135
134
  logger.debug("Adding executor {}".format(executor.label))
136
- self._poll_items.append(PollItem(executor, self.dfk))
135
+ self._executor_facades.append(PolledExecutorFacade(executor, self.dfk))
137
136
  self._strategy.add_executors(executors)
137
+
138
+ def close(self):
139
+ super().close()
140
+ for ef in self._executor_facades:
141
+ if not ef.executor.bad_state_is_set:
142
+ logger.info(f"Scaling in executor {ef.executor.label}")
143
+
144
+ # this code needs to be at least as many blocks as need
145
+ # cancelling, but it is safe to be more, as the scaling
146
+ # code will cope with being asked to cancel more blocks
147
+ # than exist.
148
+ block_count = len(ef.status)
149
+ ef.scale_in(block_count)
150
+
151
+ else: # and bad_state_is_set
152
+ logger.warning(f"Not scaling in executor {ef.executor.label} because it is in bad state")
@@ -26,6 +26,10 @@ class ExecutorState(TypedDict):
26
26
  If the executor is not idle, then None.
27
27
  """
28
28
 
29
+ first: bool
30
+ """True if this executor has not yet had a strategy poll.
31
+ """
32
+
29
33
 
30
34
  class Strategy:
31
35
  """Scaling strategy.
@@ -129,8 +133,8 @@ class Strategy:
129
133
  self.executors = {}
130
134
  self.max_idletime = max_idletime
131
135
 
132
- self.strategies = {None: self._strategy_noop,
133
- 'none': self._strategy_noop,
136
+ self.strategies = {None: self._strategy_init_only,
137
+ 'none': self._strategy_init_only,
134
138
  'simple': self._strategy_simple,
135
139
  'htex_auto_scale': self._strategy_htex_auto_scale}
136
140
 
@@ -144,17 +148,24 @@ class Strategy:
144
148
 
145
149
  def add_executors(self, executors: Sequence[ParslExecutor]) -> None:
146
150
  for executor in executors:
147
- self.executors[executor.label] = {'idle_since': None}
151
+ self.executors[executor.label] = {'idle_since': None, 'first': True}
148
152
 
149
- def _strategy_noop(self, status: List[jsp.PollItem]) -> None:
150
- """Do nothing.
153
+ def _strategy_init_only(self, executor_facades: List[jsp.PolledExecutorFacade]) -> None:
154
+ """Scale up to init_blocks at the start, then nothing more.
151
155
  """
152
- logger.debug("strategy_noop: doing nothing")
156
+ for ef in executor_facades:
157
+ executor = ef.executor
158
+ if self.executors[executor.label]['first']:
159
+ logger.debug(f"strategy_init_only: scaling out {executor.provider.init_blocks} initial blocks for {executor.label}")
160
+ ef.scale_out(executor.provider.init_blocks)
161
+ self.executors[executor.label]['first'] = False
162
+ else:
163
+ logger.debug("strategy_init_only: doing nothing")
153
164
 
154
- def _strategy_simple(self, status_list: List[jsp.PollItem]) -> None:
155
- self._general_strategy(status_list, strategy_type='simple')
165
+ def _strategy_simple(self, executor_facades: List[jsp.PolledExecutorFacade]) -> None:
166
+ self._general_strategy(executor_facades, strategy_type='simple')
156
167
 
157
- def _strategy_htex_auto_scale(self, status_list: List[jsp.PollItem]) -> None:
168
+ def _strategy_htex_auto_scale(self, executor_facades: List[jsp.PolledExecutorFacade]) -> None:
158
169
  """HTEX specific auto scaling strategy
159
170
 
160
171
  This strategy works only for HTEX. This strategy will scale out by
@@ -169,24 +180,30 @@ class Strategy:
169
180
  expected to scale in effectively only when # of workers, or tasks executing
170
181
  per block is close to 1.
171
182
  """
172
- self._general_strategy(status_list, strategy_type='htex')
183
+ self._general_strategy(executor_facades, strategy_type='htex')
173
184
 
174
185
  @wrap_with_logs
175
- def _general_strategy(self, status_list, *, strategy_type):
176
- logger.debug(f"general strategy starting with strategy_type {strategy_type} for {len(status_list)} executors")
186
+ def _general_strategy(self, executor_facades, *, strategy_type):
187
+ logger.debug(f"general strategy starting with strategy_type {strategy_type} for {len(executor_facades)} executors")
177
188
 
178
- for exec_status in status_list:
179
- executor = exec_status.executor
189
+ for ef in executor_facades:
190
+ executor = ef.executor
180
191
  label = executor.label
181
192
  if not isinstance(executor, BlockProviderExecutor):
182
193
  logger.debug(f"Not strategizing for executor {label} because scaling not enabled")
183
194
  continue
184
195
  logger.debug(f"Strategizing for executor {label}")
185
196
 
197
+ if self.executors[label]['first']:
198
+ executor = ef.executor
199
+ logger.debug(f"Scaling out {executor.provider.init_blocks} initial blocks for {label}")
200
+ ef.scale_out(executor.provider.init_blocks)
201
+ self.executors[label]['first'] = False
202
+
186
203
  # Tasks that are either pending completion
187
204
  active_tasks = executor.outstanding
188
205
 
189
- status = exec_status.status
206
+ status = ef.status
190
207
 
191
208
  # FIXME we need to handle case where provider does not define these
192
209
  # FIXME probably more of this logic should be moved to the provider
@@ -242,7 +259,7 @@ class Strategy:
242
259
  # We have resources idle for the max duration,
243
260
  # we have to scale_in now.
244
261
  logger.debug(f"Idle time has reached {self.max_idletime}s for executor {label}; scaling in")
245
- exec_status.scale_in(active_blocks - min_blocks)
262
+ ef.scale_in(active_blocks - min_blocks)
246
263
 
247
264
  else:
248
265
  logger.debug(
@@ -265,7 +282,7 @@ class Strategy:
265
282
  excess_blocks = math.ceil(float(excess_slots) / (tasks_per_node * nodes_per_block))
266
283
  excess_blocks = min(excess_blocks, max_blocks - active_blocks)
267
284
  logger.debug(f"Requesting {excess_blocks} more blocks")
268
- exec_status.scale_out(excess_blocks)
285
+ ef.scale_out(excess_blocks)
269
286
 
270
287
  elif active_slots == 0 and active_tasks > 0:
271
288
  logger.debug("Strategy case 4a: No active slots but some active tasks - could scale out by a single block")
@@ -274,7 +291,7 @@ class Strategy:
274
291
  if active_blocks < max_blocks:
275
292
  logger.debug("Requesting single block")
276
293
 
277
- exec_status.scale_out(1)
294
+ ef.scale_out(1)
278
295
  else:
279
296
  logger.debug("Not requesting single block, because at maxblocks already")
280
297
 
@@ -290,7 +307,7 @@ class Strategy:
290
307
  excess_blocks = math.ceil(float(excess_slots) / (tasks_per_node * nodes_per_block))
291
308
  excess_blocks = min(excess_blocks, active_blocks - min_blocks)
292
309
  logger.debug(f"Requesting scaling in by {excess_blocks} blocks with idle time {self.max_idletime}s")
293
- exec_status.scale_in(excess_blocks, max_idletime=self.max_idletime)
310
+ ef.scale_in(excess_blocks, max_idletime=self.max_idletime)
294
311
  else:
295
312
  logger.error("This strategy does not support scaling in except for HighThroughputExecutor - taking no action")
296
313
  else: