parsl 2024.3.11__tar.gz → 2024.3.18__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 (453) hide show
  1. {parsl-2024.3.11/parsl.egg-info → parsl-2024.3.18}/PKG-INFO +2 -2
  2. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/addresses.py +3 -1
  3. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/config.py +4 -0
  4. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/dataflow/dflow.py +3 -1
  5. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/high_throughput/executor.py +12 -0
  6. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/high_throughput/interchange.py +30 -8
  7. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/high_throughput/manager_record.py +1 -0
  8. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/high_throughput/process_worker_pool.py +41 -5
  9. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/taskvine/executor.py +3 -2
  10. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/taskvine/manager.py +1 -0
  11. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/taskvine/manager_config.py +3 -4
  12. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/jobs/job_status_poller.py +4 -3
  13. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/launchers/launchers.py +6 -6
  14. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/log_utils.py +8 -4
  15. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/db_manager.py +4 -2
  16. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/monitoring.py +9 -52
  17. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/visualization/plots/default/workflow_plots.py +3 -0
  18. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/visualization/views.py +2 -1
  19. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/cluster_provider.py +1 -3
  20. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/user_opts.py +2 -1
  21. parsl-2024.3.18/parsl/tests/test_htex/test_drain.py +78 -0
  22. parsl-2024.3.18/parsl/tests/test_monitoring/test_app_names.py +86 -0
  23. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_scaling/test_scale_down_htex_auto_scale.py +1 -10
  24. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/utils.py +2 -2
  25. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/version.py +1 -1
  26. {parsl-2024.3.11 → parsl-2024.3.18/parsl.egg-info}/PKG-INFO +2 -2
  27. {parsl-2024.3.11 → parsl-2024.3.18}/parsl.egg-info/SOURCES.txt +2 -0
  28. {parsl-2024.3.11 → parsl-2024.3.18}/LICENSE +0 -0
  29. {parsl-2024.3.11 → parsl-2024.3.18}/MANIFEST.in +0 -0
  30. {parsl-2024.3.11 → parsl-2024.3.18}/README.rst +0 -0
  31. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/__init__.py +0 -0
  32. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/app/__init__.py +0 -0
  33. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/app/app.py +0 -0
  34. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/app/bash.py +0 -0
  35. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/app/errors.py +0 -0
  36. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/app/futures.py +0 -0
  37. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/app/python.py +0 -0
  38. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/benchmark/__init__.py +0 -0
  39. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/benchmark/perf.py +0 -0
  40. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/channels/__init__.py +0 -0
  41. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/channels/base.py +0 -0
  42. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/channels/errors.py +0 -0
  43. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/channels/local/__init__.py +0 -0
  44. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/channels/local/local.py +0 -0
  45. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/channels/oauth_ssh/__init__.py +0 -0
  46. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/channels/oauth_ssh/oauth_ssh.py +0 -0
  47. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/channels/ssh/__init__.py +0 -0
  48. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/channels/ssh/ssh.py +0 -0
  49. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/channels/ssh_il/__init__.py +0 -0
  50. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/channels/ssh_il/ssh_il.py +0 -0
  51. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/concurrent/__init__.py +0 -0
  52. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/configs/ASPIRE1.py +0 -0
  53. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/configs/Azure.py +0 -0
  54. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/configs/__init__.py +0 -0
  55. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/configs/ad_hoc.py +0 -0
  56. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/configs/bridges.py +0 -0
  57. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/configs/cc_in2p3.py +0 -0
  58. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/configs/ec2.py +0 -0
  59. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/configs/expanse.py +0 -0
  60. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/configs/frontera.py +0 -0
  61. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/configs/htex_local.py +0 -0
  62. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/configs/illinoiscluster.py +0 -0
  63. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/configs/kubernetes.py +0 -0
  64. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/configs/local_threads.py +0 -0
  65. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/configs/midway.py +0 -0
  66. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/configs/osg.py +0 -0
  67. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/configs/polaris.py +0 -0
  68. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/configs/stampede2.py +0 -0
  69. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/configs/summit.py +0 -0
  70. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/configs/toss3_llnl.py +0 -0
  71. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/configs/vineex_local.py +0 -0
  72. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/configs/wqex_local.py +0 -0
  73. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/curvezmq.py +0 -0
  74. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/data_provider/__init__.py +0 -0
  75. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/data_provider/data_manager.py +0 -0
  76. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/data_provider/file_noop.py +0 -0
  77. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/data_provider/files.py +0 -0
  78. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/data_provider/ftp.py +0 -0
  79. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/data_provider/globus.py +0 -0
  80. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/data_provider/http.py +0 -0
  81. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/data_provider/rsync.py +0 -0
  82. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/data_provider/staging.py +0 -0
  83. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/dataflow/__init__.py +0 -0
  84. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/dataflow/errors.py +0 -0
  85. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/dataflow/futures.py +0 -0
  86. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/dataflow/memoization.py +0 -0
  87. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/dataflow/rundirs.py +0 -0
  88. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/dataflow/states.py +0 -0
  89. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/dataflow/taskrecord.py +0 -0
  90. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/errors.py +0 -0
  91. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/__init__.py +0 -0
  92. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/base.py +0 -0
  93. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/errors.py +0 -0
  94. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/flux/__init__.py +0 -0
  95. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/flux/execute_parsl_task.py +0 -0
  96. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/flux/executor.py +0 -0
  97. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/flux/flux_instance_manager.py +0 -0
  98. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/high_throughput/__init__.py +0 -0
  99. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/high_throughput/errors.py +0 -0
  100. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/high_throughput/monitoring_info.py +0 -0
  101. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/high_throughput/mpi_prefix_composer.py +0 -0
  102. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/high_throughput/mpi_resource_management.py +0 -0
  103. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/high_throughput/probe.py +0 -0
  104. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/high_throughput/zmq_pipes.py +0 -0
  105. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/radical/__init__.py +0 -0
  106. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/radical/executor.py +0 -0
  107. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/radical/rpex_master.py +0 -0
  108. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/radical/rpex_resources.py +0 -0
  109. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/radical/rpex_worker.py +0 -0
  110. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/status_handling.py +0 -0
  111. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/taskvine/__init__.py +0 -0
  112. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/taskvine/errors.py +0 -0
  113. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/taskvine/exec_parsl_function.py +0 -0
  114. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/taskvine/factory.py +0 -0
  115. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/taskvine/factory_config.py +0 -0
  116. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/taskvine/utils.py +0 -0
  117. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/threads.py +0 -0
  118. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/workqueue/__init__.py +0 -0
  119. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/workqueue/errors.py +0 -0
  120. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/workqueue/exec_parsl_function.py +0 -0
  121. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/workqueue/executor.py +0 -0
  122. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/workqueue/parsl_coprocess.py +0 -0
  123. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/executors/workqueue/parsl_coprocess_stub.py +0 -0
  124. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/jobs/__init__.py +0 -0
  125. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/jobs/error_handlers.py +0 -0
  126. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/jobs/errors.py +0 -0
  127. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/jobs/states.py +0 -0
  128. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/jobs/strategy.py +0 -0
  129. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/launchers/__init__.py +0 -0
  130. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/launchers/base.py +0 -0
  131. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/launchers/errors.py +0 -0
  132. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/__init__.py +0 -0
  133. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/message_type.py +0 -0
  134. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/queries/__init__.py +0 -0
  135. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/queries/pandas.py +0 -0
  136. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/radios.py +0 -0
  137. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/remote.py +0 -0
  138. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/types.py +0 -0
  139. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/visualization/__init__.py +0 -0
  140. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/visualization/app.py +0 -0
  141. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/visualization/models.py +0 -0
  142. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/visualization/plots/__init__.py +0 -0
  143. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/visualization/plots/default/__init__.py +0 -0
  144. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/visualization/plots/default/task_plots.py +0 -0
  145. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/visualization/plots/default/workflow_resource_plots.py +0 -0
  146. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/visualization/static/parsl-logo-white.png +0 -0
  147. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/visualization/static/parsl-monitor.css +0 -0
  148. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/visualization/templates/app.html +0 -0
  149. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/visualization/templates/dag.html +0 -0
  150. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/visualization/templates/error.html +0 -0
  151. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/visualization/templates/layout.html +0 -0
  152. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/visualization/templates/resource_usage.html +0 -0
  153. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/visualization/templates/task.html +0 -0
  154. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/visualization/templates/workflow.html +0 -0
  155. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/visualization/templates/workflows_summary.html +0 -0
  156. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/visualization/utils.py +0 -0
  157. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/monitoring/visualization/version.py +0 -0
  158. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/multiprocessing.py +0 -0
  159. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/process_loggers.py +0 -0
  160. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/__init__.py +0 -0
  161. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/ad_hoc/__init__.py +0 -0
  162. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/ad_hoc/ad_hoc.py +0 -0
  163. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/aws/__init__.py +0 -0
  164. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/aws/aws.py +0 -0
  165. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/aws/template.py +0 -0
  166. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/azure/__init__.py +0 -0
  167. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/azure/azure.py +0 -0
  168. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/azure/template.py +0 -0
  169. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/base.py +0 -0
  170. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/cobalt/__init__.py +0 -0
  171. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/cobalt/cobalt.py +0 -0
  172. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/cobalt/template.py +0 -0
  173. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/condor/__init__.py +0 -0
  174. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/condor/condor.py +0 -0
  175. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/condor/template.py +0 -0
  176. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/errors.py +0 -0
  177. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/googlecloud/__init__.py +0 -0
  178. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/googlecloud/googlecloud.py +0 -0
  179. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/grid_engine/__init__.py +0 -0
  180. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/grid_engine/grid_engine.py +0 -0
  181. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/grid_engine/template.py +0 -0
  182. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/kubernetes/__init__.py +0 -0
  183. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/kubernetes/kube.py +0 -0
  184. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/kubernetes/template.py +0 -0
  185. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/local/__init__.py +0 -0
  186. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/local/local.py +0 -0
  187. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/lsf/__init__.py +0 -0
  188. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/lsf/lsf.py +0 -0
  189. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/lsf/template.py +0 -0
  190. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/pbspro/__init__.py +0 -0
  191. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/pbspro/pbspro.py +0 -0
  192. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/pbspro/template.py +0 -0
  193. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/slurm/__init__.py +0 -0
  194. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/slurm/slurm.py +0 -0
  195. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/slurm/template.py +0 -0
  196. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/torque/__init__.py +0 -0
  197. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/torque/template.py +0 -0
  198. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/providers/torque/torque.py +0 -0
  199. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/py.typed +0 -0
  200. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/serialize/__init__.py +0 -0
  201. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/serialize/base.py +0 -0
  202. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/serialize/concretes.py +0 -0
  203. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/serialize/errors.py +0 -0
  204. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/serialize/facade.py +0 -0
  205. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/serialize/proxystore.py +0 -0
  206. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/__init__.py +0 -0
  207. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/callables_helper.py +0 -0
  208. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/__init__.py +0 -0
  209. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/ad_hoc_cluster_htex.py +0 -0
  210. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/azure_single_node.py +0 -0
  211. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/bluewaters.py +0 -0
  212. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/bridges.py +0 -0
  213. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/cc_in2p3.py +0 -0
  214. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/comet.py +0 -0
  215. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/cooley_htex.py +0 -0
  216. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/ec2_single_node.py +0 -0
  217. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/ec2_spot.py +0 -0
  218. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/frontera.py +0 -0
  219. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/htex_ad_hoc_cluster.py +0 -0
  220. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/htex_local.py +0 -0
  221. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/htex_local_alternate.py +0 -0
  222. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/htex_local_intask_staging.py +0 -0
  223. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/htex_local_rsync_staging.py +0 -0
  224. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/local_adhoc.py +0 -0
  225. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/local_radical.py +0 -0
  226. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/local_radical_mpi.py +0 -0
  227. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/local_threads.py +0 -0
  228. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/local_threads_checkpoint.py +0 -0
  229. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/local_threads_checkpoint_dfk_exit.py +0 -0
  230. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/local_threads_checkpoint_periodic.py +0 -0
  231. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/local_threads_checkpoint_task_exit.py +0 -0
  232. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/local_threads_ftp_in_task.py +0 -0
  233. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/local_threads_globus.py +0 -0
  234. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/local_threads_http_in_task.py +0 -0
  235. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/local_threads_monitoring.py +0 -0
  236. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/local_threads_no_cache.py +0 -0
  237. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/midway.py +0 -0
  238. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/nscc_singapore.py +0 -0
  239. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/osg_htex.py +0 -0
  240. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/petrelkube.py +0 -0
  241. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/summit.py +0 -0
  242. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/swan_htex.py +0 -0
  243. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/taskvine_ex.py +0 -0
  244. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/theta.py +0 -0
  245. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/configs/workqueue_ex.py +0 -0
  246. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/conftest.py +0 -0
  247. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/integration/__init__.py +0 -0
  248. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/integration/latency.py +0 -0
  249. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/integration/test_apps/__init__.py +0 -0
  250. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/integration/test_channels/__init__.py +0 -0
  251. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/integration/test_channels/test_channels.py +0 -0
  252. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/integration/test_channels/test_local_channel.py +0 -0
  253. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/integration/test_channels/test_scp_1.py +0 -0
  254. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/integration/test_channels/test_ssh_1.py +0 -0
  255. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/integration/test_channels/test_ssh_errors.py +0 -0
  256. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/integration/test_channels/test_ssh_file_transport.py +0 -0
  257. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/integration/test_channels/test_ssh_interactive.py +0 -0
  258. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/integration/test_parsl_load_default_config.py +0 -0
  259. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/integration/test_stress/__init__.py +0 -0
  260. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/integration/test_stress/test_python_simple.py +0 -0
  261. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/integration/test_stress/test_python_threads.py +0 -0
  262. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/manual_tests/__init__.py +0 -0
  263. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/manual_tests/htex_local.py +0 -0
  264. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/manual_tests/test_ad_hoc_htex.py +0 -0
  265. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/manual_tests/test_basic.py +0 -0
  266. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/manual_tests/test_fan_in_out_htex_remote.py +0 -0
  267. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/manual_tests/test_log_filter.py +0 -0
  268. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/manual_tests/test_memory_limits.py +0 -0
  269. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/manual_tests/test_oauth_ssh.py +0 -0
  270. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/manual_tests/test_regression_220.py +0 -0
  271. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/manual_tests/test_udp_simple.py +0 -0
  272. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/manual_tests/test_worker_count.py +0 -0
  273. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/scaling_tests/__init__.py +0 -0
  274. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/scaling_tests/htex_local.py +0 -0
  275. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/scaling_tests/local_threads.py +0 -0
  276. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/scaling_tests/test_scale.py +0 -0
  277. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/scaling_tests/vineex_condor.py +0 -0
  278. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/scaling_tests/vineex_local.py +0 -0
  279. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/scaling_tests/wqex_condor.py +0 -0
  280. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/scaling_tests/wqex_local.py +0 -0
  281. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/site_tests/__init__.py +0 -0
  282. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/site_tests/site_config_selector.py +0 -0
  283. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/site_tests/test_provider.py +0 -0
  284. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/site_tests/test_site.py +0 -0
  285. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/sites/__init__.py +0 -0
  286. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/sites/test_affinity.py +0 -0
  287. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/sites/test_concurrent.py +0 -0
  288. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/sites/test_dynamic_executor.py +0 -0
  289. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/sites/test_ec2.py +0 -0
  290. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/sites/test_launchers.py +0 -0
  291. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/sites/test_local_adhoc.py +0 -0
  292. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/sites/test_mpi/__init__.py +0 -0
  293. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/sites/test_worker_info.py +0 -0
  294. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_aalst_patterns.py +0 -0
  295. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_bash_apps/__init__.py +0 -0
  296. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_bash_apps/test_apptimeout.py +0 -0
  297. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_bash_apps/test_basic.py +0 -0
  298. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_bash_apps/test_error_codes.py +0 -0
  299. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_bash_apps/test_keyword_overlaps.py +0 -0
  300. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_bash_apps/test_kwarg_storage.py +0 -0
  301. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_bash_apps/test_memoize.py +0 -0
  302. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_bash_apps/test_memoize_ignore_args.py +0 -0
  303. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_bash_apps/test_memoize_ignore_args_regr.py +0 -0
  304. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_bash_apps/test_multiline.py +0 -0
  305. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_bash_apps/test_pipeline.py +0 -0
  306. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_bash_apps/test_stdout.py +0 -0
  307. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_callables.py +0 -0
  308. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_channels/__init__.py +0 -0
  309. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_channels/test_large_output.py +0 -0
  310. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_checkpointing/__init__.py +0 -0
  311. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_checkpointing/test_periodic.py +0 -0
  312. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_checkpointing/test_python_checkpoint_1.py +0 -0
  313. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_checkpointing/test_python_checkpoint_2.py +0 -0
  314. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_checkpointing/test_python_checkpoint_3.py +0 -0
  315. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_checkpointing/test_regression_232.py +0 -0
  316. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_checkpointing/test_regression_233.py +0 -0
  317. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_checkpointing/test_regression_239.py +0 -0
  318. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_checkpointing/test_task_exit.py +0 -0
  319. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_curvezmq.py +0 -0
  320. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_data/__init__.py +0 -0
  321. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_data/test_file.py +0 -0
  322. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_data/test_file_apps.py +0 -0
  323. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_data/test_file_staging.py +0 -0
  324. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_data/test_output_chain_filenames.py +0 -0
  325. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_docs/__init__.py +0 -0
  326. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_docs/test_from_slides.py +0 -0
  327. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_docs/test_kwargs.py +0 -0
  328. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_docs/test_tutorial_1.py +0 -0
  329. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_docs/test_workflow1.py +0 -0
  330. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_docs/test_workflow2.py +0 -0
  331. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_docs/test_workflow4.py +0 -0
  332. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_error_handling/__init__.py +0 -0
  333. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_error_handling/test_fail.py +0 -0
  334. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_error_handling/test_python_walltime.py +0 -0
  335. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_error_handling/test_rand_fail.py +0 -0
  336. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_error_handling/test_resource_spec.py +0 -0
  337. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_error_handling/test_retries.py +0 -0
  338. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_error_handling/test_retry_handler.py +0 -0
  339. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_error_handling/test_retry_handler_failure.py +0 -0
  340. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_error_handling/test_serialization_fail.py +0 -0
  341. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_error_handling/test_wrap_with_logs.py +0 -0
  342. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_flowcontrol/__init__.py +0 -0
  343. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_flux.py +0 -0
  344. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_htex/__init__.py +0 -0
  345. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_htex/test_basic.py +0 -0
  346. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_htex/test_connected_blocks.py +0 -0
  347. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_htex/test_cpu_affinity_explicit.py +0 -0
  348. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_htex/test_disconnected_blocks.py +0 -0
  349. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_htex/test_htex.py +0 -0
  350. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_htex/test_manager_failure.py +0 -0
  351. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_htex/test_missing_worker.py +0 -0
  352. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_htex/test_multiple_disconnected_blocks.py +0 -0
  353. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_htex/test_worker_failure.py +0 -0
  354. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_htex/test_zmq_binding.py +0 -0
  355. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_monitoring/__init__.py +0 -0
  356. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_monitoring/test_basic.py +0 -0
  357. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_monitoring/test_db_locks.py +0 -0
  358. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_monitoring/test_fuzz_zmq.py +0 -0
  359. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_monitoring/test_incomplete_futures.py +0 -0
  360. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_monitoring/test_memoization_representation.py +0 -0
  361. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_monitoring/test_viz_colouring.py +0 -0
  362. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_mpi_apps/__init__.py +0 -0
  363. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_mpi_apps/test_bad_mpi_config.py +0 -0
  364. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_mpi_apps/test_mpi_mode_disabled.py +0 -0
  365. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_mpi_apps/test_mpi_mode_enabled.py +0 -0
  366. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_mpi_apps/test_mpi_prefix.py +0 -0
  367. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_mpi_apps/test_mpi_scheduler.py +0 -0
  368. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_mpi_apps/test_resource_spec.py +0 -0
  369. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_providers/__init__.py +0 -0
  370. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_providers/test_cobalt_deprecation_warning.py +0 -0
  371. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_providers/test_local_provider.py +0 -0
  372. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_providers/test_pbspro_template.py +0 -0
  373. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_providers/test_slurm_instantiate.py +0 -0
  374. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_providers/test_slurm_template.py +0 -0
  375. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_providers/test_submiterror_deprecation.py +0 -0
  376. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/__init__.py +0 -0
  377. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/test_arg_input_types.py +0 -0
  378. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/test_basic.py +0 -0
  379. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/test_dep_standard_futures.py +0 -0
  380. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/test_dependencies.py +0 -0
  381. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/test_depfail_propagation.py +0 -0
  382. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/test_fail.py +0 -0
  383. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/test_fibonacci_iterative.py +0 -0
  384. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/test_fibonacci_recursive.py +0 -0
  385. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/test_futures.py +0 -0
  386. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/test_garbage_collect.py +0 -0
  387. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/test_import_fail.py +0 -0
  388. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/test_join.py +0 -0
  389. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/test_lifted.py +0 -0
  390. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/test_mapred.py +0 -0
  391. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/test_memoize_1.py +0 -0
  392. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/test_memoize_2.py +0 -0
  393. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/test_memoize_4.py +0 -0
  394. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/test_memoize_bad_id_for_memo.py +0 -0
  395. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/test_memoize_ignore_args.py +0 -0
  396. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/test_memoize_joinapp.py +0 -0
  397. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/test_outputs.py +0 -0
  398. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/test_overview.py +0 -0
  399. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/test_pipeline.py +0 -0
  400. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/test_simple.py +0 -0
  401. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/test_timeout.py +0 -0
  402. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_python_apps/test_type5.py +0 -0
  403. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_radical/__init__.py +0 -0
  404. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_radical/test_mpi_funcs.py +0 -0
  405. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_regression/__init__.py +0 -0
  406. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_regression/test_1480.py +0 -0
  407. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_regression/test_1606_wait_for_current_tasks.py +0 -0
  408. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_regression/test_1653.py +0 -0
  409. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_regression/test_221.py +0 -0
  410. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_regression/test_226.py +0 -0
  411. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_regression/test_2652.py +0 -0
  412. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_regression/test_69a.py +0 -0
  413. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_regression/test_854.py +0 -0
  414. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_regression/test_97_parallelism_0.py +0 -0
  415. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_regression/test_98.py +0 -0
  416. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_scaling/__init__.py +0 -0
  417. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_scaling/test_block_error_handler.py +0 -0
  418. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_scaling/test_regression_1621.py +0 -0
  419. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_scaling/test_scale_down.py +0 -0
  420. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_serialization/__init__.py +0 -0
  421. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_serialization/test_2555_caching_deserializer.py +0 -0
  422. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_serialization/test_basic.py +0 -0
  423. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_serialization/test_htex_code_cache.py +0 -0
  424. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_serialization/test_pack_resource_spec.py +0 -0
  425. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_serialization/test_proxystore_configured.py +0 -0
  426. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_serialization/test_proxystore_impl.py +0 -0
  427. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_staging/__init__.py +0 -0
  428. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_staging/staging_provider.py +0 -0
  429. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_staging/test_1316.py +0 -0
  430. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_staging/test_docs_1.py +0 -0
  431. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_staging/test_docs_2.py +0 -0
  432. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_staging/test_elaborate_noop_file.py +0 -0
  433. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_staging/test_staging_ftp.py +0 -0
  434. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_staging/test_staging_ftp_in_task.py +0 -0
  435. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_staging/test_staging_globus.py +0 -0
  436. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_staging/test_staging_https.py +0 -0
  437. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_summary.py +0 -0
  438. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_thread_parallelism.py +0 -0
  439. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_threads/__init__.py +0 -0
  440. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_threads/test_configs.py +0 -0
  441. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_threads/test_lazy_errors.py +0 -0
  442. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_utils/__init__.py +0 -0
  443. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/test_utils/test_representation_mixin.py +0 -0
  444. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/tests/utils.py +0 -0
  445. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/usage_tracking/__init__.py +0 -0
  446. {parsl-2024.3.11 → parsl-2024.3.18}/parsl/usage_tracking/usage.py +0 -0
  447. {parsl-2024.3.11 → parsl-2024.3.18}/parsl.egg-info/dependency_links.txt +0 -0
  448. {parsl-2024.3.11 → parsl-2024.3.18}/parsl.egg-info/entry_points.txt +0 -0
  449. {parsl-2024.3.11 → parsl-2024.3.18}/parsl.egg-info/requires.txt +0 -0
  450. {parsl-2024.3.11 → parsl-2024.3.18}/parsl.egg-info/top_level.txt +0 -0
  451. {parsl-2024.3.11 → parsl-2024.3.18}/requirements.txt +0 -0
  452. {parsl-2024.3.11 → parsl-2024.3.18}/setup.cfg +0 -0
  453. {parsl-2024.3.11 → parsl-2024.3.18}/setup.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: parsl
3
- Version: 2024.3.11
3
+ Version: 2024.3.18
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.11.tar.gz
6
+ Download-URL: https://github.com/Parsl/parsl/archive/2024.03.18.tar.gz
7
7
  Author: The Parsl Team
8
8
  Author-email: parsl@googlegroups.com
9
9
  License: Apache 2.0
@@ -81,7 +81,9 @@ def address_by_hostname() -> str:
81
81
  def address_by_interface(ifname: str) -> str:
82
82
  """Returns the IP address of the given interface name, e.g. 'eth0'
83
83
 
84
- This is from a Stack Overflow answer: https://stackoverflow.com/questions/24196932/how-can-i-get-the-ip-address-of-eth0-in-python#24196955
84
+ This is taken from a Stack Overflow answer:
85
+ https://stackoverflow.com/questions/24196932/how-can-i-get-the-ip-address-of-eth0-in-python#24196955
86
+
85
87
 
86
88
  Parameters
87
89
  ----------
@@ -55,6 +55,8 @@ class Config(RepresentationMixin):
55
55
  or `None`.
56
56
  If 'none' or `None`, dynamic scaling will be disabled. Default is 'simple'. The literal value `None` is
57
57
  deprecated.
58
+ strategy_period : float or int, optional
59
+ How often the scaling strategy should be executed. Default is 5 seconds.
58
60
  max_idletime : float, optional
59
61
  The maximum idle time allowed for an executor before strategy could shut down unused blocks. Default is 120.0 seconds.
60
62
  usage_tracking : bool, optional
@@ -88,6 +90,7 @@ class Config(RepresentationMixin):
88
90
  retry_handler: Optional[Callable[[Exception, TaskRecord], float]] = None,
89
91
  run_dir: str = 'runinfo',
90
92
  strategy: Optional[str] = 'simple',
93
+ strategy_period: Union[float, int] = 5,
91
94
  max_idletime: float = 120.0,
92
95
  monitoring: Optional[MonitoringHub] = None,
93
96
  usage_tracking: bool = False,
@@ -121,6 +124,7 @@ class Config(RepresentationMixin):
121
124
  self.retry_handler = retry_handler
122
125
  self.run_dir = run_dir
123
126
  self.strategy = strategy
127
+ self.strategy_period = strategy_period
124
128
  self.max_idletime = max_idletime
125
129
  self.usage_tracking = usage_tracking
126
130
  self.initialize_logging = initialize_logging
@@ -178,6 +178,7 @@ class DataFlowKernel:
178
178
  # this must be set before executors are added since add_executors calls
179
179
  # job_status_poller.add_executors.
180
180
  self.job_status_poller = JobStatusPoller(strategy=self.config.strategy,
181
+ strategy_period=self.config.strategy_period,
181
182
  max_idletime=self.config.max_idletime,
182
183
  dfk=self)
183
184
 
@@ -1170,7 +1171,8 @@ class DataFlowKernel:
1170
1171
  fut = task_record['app_fu']
1171
1172
  if not fut.done():
1172
1173
  fut.exception()
1173
- # now app future is done, poll until DFK state is final: a DFK state being final and the app future being done do not imply each other.
1174
+ # now app future is done, poll until DFK state is final: a
1175
+ # DFK state being final and the app future being done do not imply each other.
1174
1176
  while task_record['status'] not in FINAL_STATES:
1175
1177
  time.sleep(0.1)
1176
1178
 
@@ -55,6 +55,7 @@ DEFAULT_LAUNCH_CMD = ("process_worker_pool.py {debug} {max_workers_per_node} "
55
55
  "--hb_period={heartbeat_period} "
56
56
  "{address_probe_timeout_string} "
57
57
  "--hb_threshold={heartbeat_threshold} "
58
+ "--drain_period={drain_period} "
58
59
  "--cpu-affinity {cpu_affinity} "
59
60
  "{enable_mpi_mode} "
60
61
  "--mpi-launcher={mpi_launcher} "
@@ -201,6 +202,14 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin):
201
202
  Timeout period to be used by the executor components in milliseconds. Increasing poll_periods
202
203
  trades performance for cpu efficiency. Default: 10ms
203
204
 
205
+ drain_period : int
206
+ The number of seconds after start when workers will begin to drain
207
+ and then exit. Set this to a time that is slightly less than the
208
+ maximum walltime of batch jobs to avoid killing tasks while they
209
+ execute. For example, you could set this to the walltime minus a grace
210
+ period for the batch job to start the workers, minus the expected
211
+ maximum length of an individual task.
212
+
204
213
  worker_logdir_root : string
205
214
  In case of a remote file system, specify the path to where logs will be kept.
206
215
 
@@ -240,6 +249,7 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin):
240
249
  prefetch_capacity: int = 0,
241
250
  heartbeat_threshold: int = 120,
242
251
  heartbeat_period: int = 30,
252
+ drain_period: Optional[int] = None,
243
253
  poll_period: int = 10,
244
254
  address_probe_timeout: Optional[int] = None,
245
255
  worker_logdir_root: Optional[str] = None,
@@ -303,6 +313,7 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin):
303
313
  self.interchange_port_range = interchange_port_range
304
314
  self.heartbeat_threshold = heartbeat_threshold
305
315
  self.heartbeat_period = heartbeat_period
316
+ self.drain_period = drain_period
306
317
  self.poll_period = poll_period
307
318
  self.run_dir = '.'
308
319
  self.worker_logdir_root = worker_logdir_root
@@ -376,6 +387,7 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin):
376
387
  nodes_per_block=self.provider.nodes_per_block,
377
388
  heartbeat_period=self.heartbeat_period,
378
389
  heartbeat_threshold=self.heartbeat_threshold,
390
+ drain_period=self.drain_period,
379
391
  poll_period=self.poll_period,
380
392
  cert_dir=self.cert_dir,
381
393
  logdir=self.worker_logdir,
@@ -28,6 +28,7 @@ from parsl.process_loggers import wrap_with_logs
28
28
 
29
29
 
30
30
  PKL_HEARTBEAT_CODE = pickle.dumps((2 ** 32) - 1)
31
+ PKL_DRAINED_CODE = pickle.dumps((2 ** 32) - 2)
31
32
 
32
33
  LOGGER_NAME = "interchange"
33
34
  logger = logging.getLogger(LOGGER_NAME)
@@ -101,12 +102,12 @@ class Interchange:
101
102
  This is overridden when the worker_ports option is set. Default: (54000, 55000)
102
103
 
103
104
  hub_address : str
104
- The ip address at which the interchange can send info about managers to when monitoring is enabled.
105
- This is passed via dfk and executor automatically. Default: None (meaning monitoring disabled)
105
+ The IP address at which the interchange can send info about managers to when monitoring is enabled.
106
+ Default: None (meaning monitoring disabled)
106
107
 
107
108
  hub_port : str
108
109
  The port at which the interchange can send info about managers to when monitoring is enabled.
109
- This is passed via dfk and executor automatically. Default: None (meaning monitoring disabled)
110
+ Default: None (meaning monitoring disabled)
110
111
 
111
112
  heartbeat_threshold : int
112
113
  Number of seconds since the last heartbeat after which worker is considered lost.
@@ -244,19 +245,19 @@ class Interchange:
244
245
 
245
246
  def _create_monitoring_channel(self) -> Optional[zmq.Socket]:
246
247
  if self.hub_address and self.hub_port:
247
- logger.info("Connecting to monitoring")
248
+ logger.info("Connecting to MonitoringHub")
248
249
  # This is a one-off because monitoring is unencrypted
249
250
  hub_channel = zmq.Context().socket(zmq.DEALER)
250
251
  hub_channel.set_hwm(0)
251
252
  hub_channel.connect("tcp://{}:{}".format(self.hub_address, self.hub_port))
252
- logger.info("Monitoring enabled and connected to hub")
253
+ logger.info("Connected to MonitoringHub")
253
254
  return hub_channel
254
255
  else:
255
256
  return None
256
257
 
257
258
  def _send_monitoring_info(self, hub_channel: Optional[zmq.Socket], manager: ManagerRecord) -> None:
258
259
  if hub_channel:
259
- logger.info("Sending message {} to hub".format(manager))
260
+ logger.info("Sending message {} to MonitoringHub".format(manager))
260
261
 
261
262
  d: Dict = cast(Dict, manager.copy())
262
263
  d['timestamp'] = datetime.datetime.now()
@@ -308,7 +309,8 @@ class Interchange:
308
309
  'worker_count': m['worker_count'],
309
310
  'tasks': len(m['tasks']),
310
311
  'idle_duration': idle_duration,
311
- 'active': m['active']}
312
+ 'active': m['active'],
313
+ 'draining': m['draining']}
312
314
  reply.append(resp)
313
315
 
314
316
  elif command_req.startswith("HOLD_WORKER"):
@@ -385,6 +387,7 @@ class Interchange:
385
387
  self.process_task_outgoing_incoming(interesting_managers, hub_channel, kill_event)
386
388
  self.process_results_incoming(interesting_managers, hub_channel)
387
389
  self.expire_bad_managers(interesting_managers, hub_channel)
390
+ self.expire_drained_managers(interesting_managers, hub_channel)
388
391
  self.process_tasks_to_send(interesting_managers)
389
392
 
390
393
  self.zmq_context.destroy()
@@ -431,6 +434,7 @@ class Interchange:
431
434
  'max_capacity': 0,
432
435
  'worker_count': 0,
433
436
  'active': True,
437
+ 'draining': False,
434
438
  'tasks': []}
435
439
  self.connected_block_history.append(msg['block_id'])
436
440
 
@@ -469,10 +473,28 @@ class Interchange:
469
473
  self._ready_managers[manager_id]['last_heartbeat'] = time.time()
470
474
  logger.debug("Manager {!r} sent heartbeat via tasks connection".format(manager_id))
471
475
  self.task_outgoing.send_multipart([manager_id, b'', PKL_HEARTBEAT_CODE])
476
+ elif msg['type'] == 'drain':
477
+ self._ready_managers[manager_id]['draining'] = True
478
+ logger.debug(f"Manager {manager_id!r} requested drain")
472
479
  else:
473
480
  logger.error(f"Unexpected message type received from manager: {msg['type']}")
474
481
  logger.debug("leaving task_outgoing section")
475
482
 
483
+ def expire_drained_managers(self, interesting_managers: Set[bytes], hub_channel: Optional[zmq.Socket]) -> None:
484
+
485
+ for manager_id in list(interesting_managers):
486
+ # is it always true that a draining manager will be in interesting managers?
487
+ # i think so because it will have outstanding capacity?
488
+ m = self._ready_managers[manager_id]
489
+ if m['draining'] and len(m['tasks']) == 0:
490
+ logger.info(f"Manager {manager_id!r} is drained - sending drained message to manager")
491
+ self.task_outgoing.send_multipart([manager_id, b'', PKL_DRAINED_CODE])
492
+ interesting_managers.remove(manager_id)
493
+ self._ready_managers.pop(manager_id)
494
+
495
+ m['active'] = False
496
+ self._send_monitoring_info(hub_channel, m)
497
+
476
498
  def process_tasks_to_send(self, interesting_managers: Set[bytes]) -> None:
477
499
  # Check if there are tasks that could be sent to managers
478
500
 
@@ -490,7 +512,7 @@ class Interchange:
490
512
  tasks_inflight = len(m['tasks'])
491
513
  real_capacity = m['max_capacity'] - tasks_inflight
492
514
 
493
- if (real_capacity and m['active']):
515
+ if (real_capacity and m['active'] and not m['draining']):
494
516
  tasks = self.get_tasks(real_capacity)
495
517
  if tasks:
496
518
  self.task_outgoing.send_multipart([manager_id, b'', pickle.dumps(tasks)])
@@ -9,6 +9,7 @@ class ManagerRecord(TypedDict, total=False):
9
9
  worker_count: int
10
10
  max_capacity: int
11
11
  active: bool
12
+ draining: bool
12
13
  hostname: str
13
14
  last_heartbeat: float
14
15
  idle_since: Optional[float]
@@ -36,6 +36,7 @@ from parsl.executors.high_throughput.mpi_resource_management import (
36
36
  from parsl.executors.high_throughput.mpi_prefix_composer import compose_all, VALID_LAUNCHERS
37
37
 
38
38
  HEARTBEAT_CODE = (2 ** 32) - 1
39
+ DRAINED_CODE = (2 ** 32) - 2
39
40
 
40
41
 
41
42
  class Manager:
@@ -73,7 +74,8 @@ class Manager:
73
74
  enable_mpi_mode: bool = False,
74
75
  mpi_launcher: str = "mpiexec",
75
76
  available_accelerators: Sequence[str],
76
- cert_dir: Optional[str]):
77
+ cert_dir: Optional[str],
78
+ drain_period: Optional[int]):
77
79
  """
78
80
  Parameters
79
81
  ----------
@@ -138,6 +140,9 @@ class Manager:
138
140
 
139
141
  cert_dir : str | None
140
142
  Path to the certificate directory.
143
+
144
+ drain_period: int | None
145
+ Number of seconds to drain after TODO: could be a nicer timespec involving m,s,h qualifiers for user friendliness?
141
146
  """
142
147
 
143
148
  logger.info("Manager initializing")
@@ -227,6 +232,14 @@ class Manager:
227
232
  self.heartbeat_period = heartbeat_period
228
233
  self.heartbeat_threshold = heartbeat_threshold
229
234
  self.poll_period = poll_period
235
+
236
+ self.drain_time: float
237
+ if drain_period:
238
+ self.drain_time = self._start_time + drain_period
239
+ logger.info(f"Will request drain at {self.drain_time}")
240
+ else:
241
+ self.drain_time = float('inf')
242
+
230
243
  self.cpu_affinity = cpu_affinity
231
244
 
232
245
  # Define accelerator available, adjust worker count accordingly
@@ -262,10 +275,19 @@ class Manager:
262
275
  """ Send heartbeat to the incoming task queue
263
276
  """
264
277
  msg = {'type': 'heartbeat'}
278
+ # don't need to dumps and encode this every time - could do as a global on import?
265
279
  b_msg = json.dumps(msg).encode('utf-8')
266
280
  self.task_incoming.send(b_msg)
267
281
  logger.debug("Sent heartbeat")
268
282
 
283
+ def drain_to_incoming(self):
284
+ """ Send heartbeat to the incoming task queue
285
+ """
286
+ msg = {'type': 'drain'}
287
+ b_msg = json.dumps(msg).encode('utf-8')
288
+ self.task_incoming.send(b_msg)
289
+ logger.debug("Sent drain")
290
+
269
291
  @wrap_with_logs
270
292
  def pull_tasks(self, kill_event):
271
293
  """ Pull tasks from the incoming tasks zmq pipe onto the internal
@@ -298,6 +320,7 @@ class Manager:
298
320
  # time here are correctly copy-pasted from the relevant if
299
321
  # statements.
300
322
  next_interesting_event_time = min(last_beat + self.heartbeat_period,
323
+ self.drain_time,
301
324
  last_interchange_contact + self.heartbeat_threshold)
302
325
  try:
303
326
  pending_task_count = self.pending_task_queue.qsize()
@@ -312,6 +335,14 @@ class Manager:
312
335
  self.heartbeat_to_incoming()
313
336
  last_beat = time.time()
314
337
 
338
+ if self.drain_time and time.time() > self.drain_time:
339
+ logger.info("Requesting drain")
340
+ self.drain_to_incoming()
341
+ self.drain_time = None
342
+ # This will start the pool draining...
343
+ # Drained exit behaviour does not happen here. It will be
344
+ # driven by the interchange sending a DRAINED_CODE message.
345
+
315
346
  poll_duration_s = max(0, next_interesting_event_time - time.time())
316
347
  socks = dict(poller.poll(timeout=poll_duration_s * 1000))
317
348
 
@@ -322,7 +353,9 @@ class Manager:
322
353
 
323
354
  if tasks == HEARTBEAT_CODE:
324
355
  logger.debug("Got heartbeat from interchange")
325
-
356
+ elif tasks == DRAINED_CODE:
357
+ logger.info("Got fulled drained message from interchange - setting kill flag")
358
+ kill_event.set()
326
359
  else:
327
360
  task_recv_counter += len(tasks)
328
361
  logger.debug("Got executor tasks: {}, cumulative count of tasks: {}".format([t['task_id'] for t in tasks], task_recv_counter))
@@ -490,9 +523,8 @@ class Manager:
490
523
  self._worker_watchdog_thread.start()
491
524
  self._monitoring_handler_thread.start()
492
525
 
493
- logger.info("Loop start")
526
+ logger.info("Manager threads started")
494
527
 
495
- # TODO : Add mechanism in this loop to stop the worker pool
496
528
  # This might need a multiprocessing event to signal back.
497
529
  self._kill_event.wait()
498
530
  logger.critical("Received kill event, terminating worker processes")
@@ -804,6 +836,8 @@ if __name__ == "__main__":
804
836
  help="Heartbeat period in seconds. Uses manager default unless set")
805
837
  parser.add_argument("--hb_threshold", default=120,
806
838
  help="Heartbeat threshold in seconds. Uses manager default unless set")
839
+ parser.add_argument("--drain_period", default=None,
840
+ help="Drain this pool after specified number of seconds. By default, does not drain.")
807
841
  parser.add_argument("--address_probe_timeout", default=30,
808
842
  help="Timeout to probe for viable address to interchange. Default: 30s")
809
843
  parser.add_argument("--poll", default=10,
@@ -824,7 +858,7 @@ if __name__ == "__main__":
824
858
  required=True,
825
859
  help="Whether/how workers should control CPU affinity.")
826
860
  parser.add_argument("--available-accelerators", type=str, nargs="*",
827
- help="Names of available accelerators")
861
+ help="Names of available accelerators, if not given assumed to be zero accelerators available", default=[])
828
862
  parser.add_argument("--enable_mpi_mode", action='store_true',
829
863
  help="Enable MPI mode")
830
864
  parser.add_argument("--mpi-launcher", type=str, choices=VALID_LAUNCHERS,
@@ -856,6 +890,7 @@ if __name__ == "__main__":
856
890
  logger.info("Prefetch capacity: {}".format(args.prefetch_capacity))
857
891
  logger.info("Heartbeat threshold: {}".format(args.hb_threshold))
858
892
  logger.info("Heartbeat period: {}".format(args.hb_period))
893
+ logger.info("Drain period: {}".format(args.drain_period))
859
894
  logger.info("CPU affinity: {}".format(args.cpu_affinity))
860
895
  logger.info("Accelerators: {}".format(" ".join(args.available_accelerators)))
861
896
  logger.info("enable_mpi_mode: {}".format(args.enable_mpi_mode))
@@ -876,6 +911,7 @@ if __name__ == "__main__":
876
911
  prefetch_capacity=int(args.prefetch_capacity),
877
912
  heartbeat_threshold=int(args.hb_threshold),
878
913
  heartbeat_period=int(args.hb_period),
914
+ drain_period=None if args.drain_period == "None" else int(args.drain_period),
879
915
  poll_period=int(args.poll),
880
916
  cpu_affinity=args.cpu_affinity,
881
917
  enable_mpi_mode=args.enable_mpi_mode,
@@ -196,8 +196,9 @@ class TaskVineExecutor(BlockProviderExecutor, putils.RepresentationMixin):
196
196
  if self.manager_config.port == 0 and self.manager_config.project_name is None:
197
197
  self.manager_config.project_name = "parsl-vine-" + str(uuid.uuid4())
198
198
 
199
- # guess the host name if the project name is not given
200
- if not self.manager_config.project_name:
199
+ # guess the host name if the project name is not given and none has been supplied
200
+ # explicitly in the manager config.
201
+ if not self.manager_config.project_name and self.manager_config.address is None:
201
202
  self.manager_config.address = get_any_address()
202
203
 
203
204
  # Factory communication settings are overridden by manager communication settings.
@@ -376,6 +376,7 @@ def _taskvine_submit_wait(ready_task_queue=None,
376
376
  task_out_file = parsl_file_name_to_vine_file[spec.parsl_name]
377
377
  else:
378
378
  task_out_file = m.declare_file(spec.parsl_name, cache=spec.cache, peer_transfer=True)
379
+ parsl_file_name_to_vine_file[spec.parsl_name] = task_out_file
379
380
  t.add_output(task_out_file, spec.parsl_name)
380
381
 
381
382
  # Submit the task to the TaskVine object
@@ -1,4 +1,3 @@
1
- import socket
2
1
  from dataclasses import dataclass
3
2
  from typing import Optional
4
3
 
@@ -23,9 +22,9 @@ class TaskVineManagerConfig:
23
22
  A value of 0 means TaskVine chooses any available port.
24
23
  Default is VINE_DEFAULT_PORT.
25
24
 
26
- address: str
25
+ address: Optional[str]
27
26
  Address of the local machine.
28
- Default is socket.gethostname().
27
+ If None, socket.gethostname() will be used to determine the address.
29
28
 
30
29
  project_name: Optional[str]
31
30
  If given, TaskVine will periodically report its status and performance
@@ -161,7 +160,7 @@ class TaskVineManagerConfig:
161
160
 
162
161
  # Connection and communication settings
163
162
  port: int = VINE_DEFAULT_PORT
164
- address: str = socket.gethostname()
163
+ address: Optional[str] = None
165
164
  project_name: Optional[str] = None
166
165
  project_password_file: Optional[str] = None
167
166
 
@@ -2,7 +2,7 @@ import logging
2
2
  import parsl
3
3
  import time
4
4
  import zmq
5
- from typing import Dict, List, Sequence, Optional
5
+ from typing import Dict, List, Sequence, Optional, Union
6
6
 
7
7
  from parsl.jobs.states import JobStatus, JobState
8
8
  from parsl.jobs.strategy import Strategy
@@ -106,13 +106,14 @@ class PollItem:
106
106
 
107
107
 
108
108
  class JobStatusPoller(Timer):
109
- def __init__(self, strategy: Optional[str] = None, max_idletime: float = 0.0,
109
+ def __init__(self, *, strategy: Optional[str], max_idletime: float,
110
+ strategy_period: Union[float, int],
110
111
  dfk: Optional["parsl.dataflow.dflow.DataFlowKernel"] = None) -> None:
111
112
  self._poll_items = [] # type: List[PollItem]
112
113
  self.dfk = dfk
113
114
  self._strategy = Strategy(strategy=strategy,
114
115
  max_idletime=max_idletime)
115
- super().__init__(self.poll, interval=5, name="JobStatusPoller")
116
+ super().__init__(self.poll, interval=strategy_period, name="JobStatusPoller")
116
117
 
117
118
  def poll(self) -> None:
118
119
  self._update_state()
@@ -8,16 +8,16 @@ logger = logging.getLogger(__name__)
8
8
  class SimpleLauncher(Launcher):
9
9
  """ Does no wrapping. Just returns the command as-is
10
10
  """
11
- def __init_(self, debug: bool = True) -> None:
11
+ def __init__(self, debug: bool = True) -> None:
12
12
  super().__init__(debug=debug)
13
13
 
14
14
  def __call__(self, command: str, tasks_per_node: int, nodes_per_block: int) -> str:
15
- """
16
- Args:
17
- - command (string): The command string to be launched
18
- - task_block (string) : bash evaluated string.
19
15
 
20
- """
16
+ if nodes_per_block > 1:
17
+ logger.warning('Simple Launcher only supports single node per block. '
18
+ f'Requested nodes: {nodes_per_block}. '
19
+ 'You may be getting fewer workers than expected')
20
+
21
21
  return command
22
22
 
23
23
 
@@ -28,7 +28,7 @@ DEFAULT_FORMAT = (
28
28
  def set_stream_logger(name: str = 'parsl',
29
29
  level: int = logging.DEBUG,
30
30
  format_string: Optional[str] = None,
31
- stream: Optional[io.TextIOWrapper] = None) -> None:
31
+ stream: Optional[io.TextIOWrapper] = None) -> logging.Logger:
32
32
  """Add a stream log handler.
33
33
 
34
34
  Args:
@@ -39,7 +39,7 @@ def set_stream_logger(name: str = 'parsl',
39
39
  If not specified, the default stream for logging.StreamHandler is used.
40
40
 
41
41
  Returns:
42
- - None
42
+ - logger for specified name
43
43
  """
44
44
  if format_string is None:
45
45
  # format_string = "%(asctime)s %(name)s [%(levelname)s] Thread:%(thread)d %(message)s"
@@ -59,12 +59,14 @@ def set_stream_logger(name: str = 'parsl',
59
59
  futures_logger = logging.getLogger("concurrent.futures")
60
60
  futures_logger.addHandler(handler)
61
61
 
62
+ return logger
63
+
62
64
 
63
65
  @typeguard.typechecked
64
66
  def set_file_logger(filename: str,
65
67
  name: str = 'parsl',
66
68
  level: int = logging.DEBUG,
67
- format_string: Optional[str] = None) -> None:
69
+ format_string: Optional[str] = None) -> logging.Logger:
68
70
  """Add a file log handler.
69
71
 
70
72
  Args:
@@ -74,7 +76,7 @@ def set_file_logger(filename: str,
74
76
  - format_string (string): Set the format string
75
77
 
76
78
  Returns:
77
- - None
79
+ - logger for specified name
78
80
  """
79
81
  if format_string is None:
80
82
  format_string = DEFAULT_FORMAT
@@ -91,3 +93,5 @@ def set_file_logger(filename: str,
91
93
  # concurrent.futures
92
94
  futures_logger = logging.getLogger("concurrent.futures")
93
95
  futures_logger.addHandler(handler)
96
+
97
+ return logger
@@ -633,7 +633,8 @@ class DatabaseManager:
633
633
  # if retried - for example, the database being locked because someone else is readying
634
634
  # the tables we are trying to write to. If that assumption is wrong, then this loop
635
635
  # may go on forever.
636
- logger.warning("Got a database OperationalError. Ignoring and retrying on the assumption that it is recoverable: {}".format(e))
636
+ logger.warning("Got a database OperationalError. "
637
+ "Ignoring and retrying on the assumption that it is recoverable: {}".format(e))
637
638
  self.db.rollback()
638
639
  time.sleep(1) # hard coded 1s wait - this should be configurable or exponential backoff or something
639
640
 
@@ -660,7 +661,8 @@ class DatabaseManager:
660
661
  done = True
661
662
  except sa.exc.OperationalError as e:
662
663
  # hoping that this is a database locked error during _update, not some other problem
663
- logger.warning("Got a database OperationalError. Ignoring and retrying on the assumption that it is recoverable: {}".format(e))
664
+ logger.warning("Got a database OperationalError. "
665
+ "Ignoring and retrying on the assumption that it is recoverable: {}".format(e))
664
666
  self.db.rollback()
665
667
  time.sleep(1) # hard coded 1s wait - this should be configurable or exponential backoff or something
666
668
  except KeyboardInterrupt:
@@ -15,6 +15,7 @@ import parsl.monitoring.remote
15
15
  from parsl.multiprocessing import ForkProcess, SizedQueue
16
16
  from multiprocessing import Process
17
17
  from multiprocessing.queues import Queue
18
+ from parsl.log_utils import set_file_logger
18
19
  from parsl.utils import RepresentationMixin
19
20
  from parsl.process_loggers import wrap_with_logs
20
21
  from parsl.utils import setproctitle
@@ -38,40 +39,6 @@ else:
38
39
  logger = logging.getLogger(__name__)
39
40
 
40
41
 
41
- def start_file_logger(filename: str, name: str = 'monitoring', level: int = logging.DEBUG, format_string: Optional[str] = None) -> logging.Logger:
42
- """Add a stream log handler.
43
-
44
- Parameters
45
- ---------
46
-
47
- filename: string
48
- Name of the file to write logs to. Required.
49
- name: string
50
- Logger name.
51
- level: logging.LEVEL
52
- Set the logging level. Default=logging.DEBUG
53
- - format_string (string): Set the format string
54
- format_string: string
55
- Format string to use.
56
-
57
- Returns
58
- -------
59
- None.
60
- """
61
- if format_string is None:
62
- format_string = "%(asctime)s.%(msecs)03d %(name)s:%(lineno)d [%(levelname)s] %(message)s"
63
-
64
- logger = logging.getLogger(name)
65
- logger.setLevel(level)
66
- logger.propagate = False
67
- handler = logging.FileHandler(filename)
68
- handler.setLevel(level)
69
- formatter = logging.Formatter(format_string, datefmt='%Y-%m-%d %H:%M:%S')
70
- handler.setFormatter(formatter)
71
- logger.addHandler(handler)
72
- return logger
73
-
74
-
75
42
  @typeguard.typechecked
76
43
  class MonitoringHub(RepresentationMixin):
77
44
  def __init__(self,
@@ -79,9 +46,6 @@ class MonitoringHub(RepresentationMixin):
79
46
  hub_port: Optional[int] = None,
80
47
  hub_port_range: Tuple[int, int] = (55050, 56000),
81
48
 
82
- client_address: str = "127.0.0.1",
83
- client_port_range: Tuple[int, int] = (55000, 56000),
84
-
85
49
  workflow_name: Optional[str] = None,
86
50
  workflow_version: Optional[str] = None,
87
51
  logging_endpoint: Optional[str] = None,
@@ -106,11 +70,6 @@ class MonitoringHub(RepresentationMixin):
106
70
  to deliver monitoring messages to the monitoring router.
107
71
  Note that despite the similar name, this is not related to hub_port.
108
72
  Default: (55050, 56000)
109
- client_address : str
110
- The ip address at which the dfk will be able to reach Hub. Default: "127.0.0.1"
111
- client_port_range : tuple(int, int)
112
- The MonitoringHub picks ports at random from the range which will be used by Hub.
113
- Default: (55000, 56000)
114
73
  workflow_name : str
115
74
  The name for the workflow. Default to the name of the parsl script
116
75
  workflow_version : str
@@ -145,9 +104,6 @@ class MonitoringHub(RepresentationMixin):
145
104
  if _db_manager_excepts:
146
105
  raise _db_manager_excepts
147
106
 
148
- self.client_address = client_address
149
- self.client_port_range = client_port_range
150
-
151
107
  self.hub_address = hub_address
152
108
  self.hub_port = hub_port
153
109
  self.hub_port_range = hub_port_range
@@ -337,9 +293,9 @@ class MonitoringHub(RepresentationMixin):
337
293
 
338
294
  @wrap_with_logs
339
295
  def filesystem_receiver(logdir: str, q: "queue.Queue[AddressedMonitoringMessage]", run_dir: str) -> None:
340
- logger = start_file_logger("{}/monitoring_filesystem_radio.log".format(logdir),
341
- name="monitoring_filesystem_radio",
342
- level=logging.INFO)
296
+ logger = set_file_logger("{}/monitoring_filesystem_radio.log".format(logdir),
297
+ name="monitoring_filesystem_radio",
298
+ level=logging.INFO)
343
299
 
344
300
  logger.info("Starting filesystem radio receiver")
345
301
  setproctitle("parsl: monitoring filesystem receiver")
@@ -405,9 +361,9 @@ class MonitoringRouter:
405
361
 
406
362
  """
407
363
  os.makedirs(logdir, exist_ok=True)
408
- self.logger = start_file_logger("{}/monitoring_router.log".format(logdir),
409
- name="monitoring_router",
410
- level=logging_level)
364
+ self.logger = set_file_logger("{}/monitoring_router.log".format(logdir),
365
+ name="monitoring_router",
366
+ level=logging_level)
411
367
  self.logger.debug("Monitoring router starting")
412
368
 
413
369
  self.hub_address = hub_address
@@ -493,7 +449,8 @@ class MonitoringRouter:
493
449
  # but there is no verification that the message
494
450
  # received from ic_channel.recv_pyobj() is actually
495
451
  # of that type.
496
- self.logger.error(f"Discarding message from interchange with unknown type {msg[0].value}") # type: ignore[unreachable]
452
+ self.logger.error("Discarding message " # type: ignore[unreachable]
453
+ f"from interchange with unknown type {msg[0].value}")
497
454
  except zmq.Again:
498
455
  pass
499
456
  except Exception: