parsl 2024.4.8__tar.gz → 2024.4.22__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 (464) hide show
  1. {parsl-2024.4.8/parsl.egg-info → parsl-2024.4.22}/PKG-INFO +2 -2
  2. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/addresses.py +2 -2
  3. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/app/bash.py +10 -2
  4. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/app/errors.py +3 -5
  5. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/data_provider/data_manager.py +2 -1
  6. parsl-2024.4.22/parsl/data_provider/zip.py +104 -0
  7. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/dataflow/dflow.py +92 -43
  8. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/dataflow/futures.py +26 -12
  9. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/base.py +28 -9
  10. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/high_throughput/executor.py +14 -19
  11. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/high_throughput/process_worker_pool.py +3 -1
  12. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/status_handling.py +81 -1
  13. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/taskvine/executor.py +13 -2
  14. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/workqueue/executor.py +14 -3
  15. parsl-2024.4.22/parsl/jobs/job_status_poller.py +58 -0
  16. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/jobs/strategy.py +22 -27
  17. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/monitoring.py +29 -23
  18. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/radios.py +15 -0
  19. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/router.py +7 -6
  20. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/local/local.py +1 -1
  21. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/htex_local_alternate.py +2 -1
  22. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/taskvine_ex.py +1 -2
  23. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/workqueue_ex.py +1 -2
  24. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/conftest.py +6 -7
  25. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_bash_apps/test_basic.py +7 -4
  26. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_bash_apps/test_error_codes.py +0 -3
  27. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_bash_apps/test_kwarg_storage.py +0 -1
  28. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_bash_apps/test_memoize.py +0 -2
  29. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_bash_apps/test_memoize_ignore_args.py +0 -1
  30. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_bash_apps/test_memoize_ignore_args_regr.py +0 -1
  31. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_bash_apps/test_multiline.py +0 -1
  32. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_bash_apps/test_stdout.py +11 -6
  33. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_checkpointing/test_task_exit.py +1 -1
  34. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_htex/test_zmq_binding.py +1 -0
  35. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_monitoring/test_basic.py +46 -21
  36. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_monitoring/test_fuzz_zmq.py +10 -1
  37. parsl-2024.4.22/parsl/tests/test_monitoring/test_stdouterr.py +137 -0
  38. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_context_manager.py +3 -3
  39. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_outputs.py +0 -1
  40. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_scaling/test_regression_1621.py +11 -11
  41. parsl-2024.4.22/parsl/tests/test_scaling/test_scale_down_htex_unregistered.py +74 -0
  42. parsl-2024.4.22/parsl/tests/test_staging/test_staging_stdout.py +61 -0
  43. parsl-2024.4.22/parsl/tests/test_staging/test_zip_out.py +113 -0
  44. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/utils.py +11 -2
  45. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/version.py +1 -1
  46. {parsl-2024.4.8 → parsl-2024.4.22/parsl.egg-info}/PKG-INFO +2 -2
  47. {parsl-2024.4.8 → parsl-2024.4.22}/parsl.egg-info/SOURCES.txt +5 -0
  48. {parsl-2024.4.8 → parsl-2024.4.22}/parsl.egg-info/requires.txt +3 -2
  49. {parsl-2024.4.8 → parsl-2024.4.22}/requirements.txt +1 -0
  50. {parsl-2024.4.8 → parsl-2024.4.22}/setup.py +1 -1
  51. parsl-2024.4.8/parsl/jobs/job_status_poller.py +0 -152
  52. {parsl-2024.4.8 → parsl-2024.4.22}/LICENSE +0 -0
  53. {parsl-2024.4.8 → parsl-2024.4.22}/MANIFEST.in +0 -0
  54. {parsl-2024.4.8 → parsl-2024.4.22}/README.rst +0 -0
  55. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/__init__.py +0 -0
  56. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/app/__init__.py +0 -0
  57. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/app/app.py +0 -0
  58. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/app/futures.py +0 -0
  59. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/app/python.py +0 -0
  60. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/benchmark/__init__.py +0 -0
  61. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/benchmark/perf.py +0 -0
  62. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/channels/__init__.py +0 -0
  63. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/channels/base.py +0 -0
  64. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/channels/errors.py +0 -0
  65. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/channels/local/__init__.py +0 -0
  66. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/channels/local/local.py +0 -0
  67. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/channels/oauth_ssh/__init__.py +0 -0
  68. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/channels/oauth_ssh/oauth_ssh.py +0 -0
  69. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/channels/ssh/__init__.py +0 -0
  70. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/channels/ssh/ssh.py +0 -0
  71. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/channels/ssh_il/__init__.py +0 -0
  72. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/channels/ssh_il/ssh_il.py +0 -0
  73. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/concurrent/__init__.py +0 -0
  74. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/config.py +0 -0
  75. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/ASPIRE1.py +0 -0
  76. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/Azure.py +0 -0
  77. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/__init__.py +0 -0
  78. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/ad_hoc.py +0 -0
  79. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/bridges.py +0 -0
  80. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/cc_in2p3.py +0 -0
  81. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/ec2.py +0 -0
  82. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/expanse.py +0 -0
  83. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/frontera.py +0 -0
  84. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/htex_local.py +0 -0
  85. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/illinoiscluster.py +0 -0
  86. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/kubernetes.py +0 -0
  87. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/local_threads.py +0 -0
  88. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/midway.py +0 -0
  89. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/osg.py +0 -0
  90. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/polaris.py +0 -0
  91. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/stampede2.py +0 -0
  92. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/summit.py +0 -0
  93. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/toss3_llnl.py +0 -0
  94. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/vineex_local.py +0 -0
  95. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/wqex_local.py +0 -0
  96. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/curvezmq.py +0 -0
  97. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/data_provider/__init__.py +0 -0
  98. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/data_provider/file_noop.py +0 -0
  99. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/data_provider/files.py +0 -0
  100. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/data_provider/ftp.py +0 -0
  101. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/data_provider/globus.py +0 -0
  102. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/data_provider/http.py +0 -0
  103. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/data_provider/rsync.py +0 -0
  104. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/data_provider/staging.py +0 -0
  105. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/dataflow/__init__.py +0 -0
  106. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/dataflow/errors.py +0 -0
  107. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/dataflow/memoization.py +0 -0
  108. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/dataflow/rundirs.py +0 -0
  109. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/dataflow/states.py +0 -0
  110. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/dataflow/taskrecord.py +0 -0
  111. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/errors.py +0 -0
  112. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/__init__.py +0 -0
  113. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/errors.py +0 -0
  114. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/flux/__init__.py +0 -0
  115. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/flux/execute_parsl_task.py +0 -0
  116. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/flux/executor.py +0 -0
  117. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/flux/flux_instance_manager.py +0 -0
  118. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/high_throughput/__init__.py +0 -0
  119. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/high_throughput/errors.py +0 -0
  120. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/high_throughput/interchange.py +0 -0
  121. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/high_throughput/manager_record.py +0 -0
  122. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/high_throughput/monitoring_info.py +0 -0
  123. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/high_throughput/mpi_prefix_composer.py +0 -0
  124. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/high_throughput/mpi_resource_management.py +0 -0
  125. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/high_throughput/probe.py +0 -0
  126. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/high_throughput/zmq_pipes.py +0 -0
  127. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/radical/__init__.py +0 -0
  128. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/radical/executor.py +0 -0
  129. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/radical/rpex_master.py +0 -0
  130. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/radical/rpex_resources.py +0 -0
  131. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/radical/rpex_worker.py +0 -0
  132. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/taskvine/__init__.py +0 -0
  133. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/taskvine/errors.py +0 -0
  134. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/taskvine/exec_parsl_function.py +0 -0
  135. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/taskvine/factory.py +0 -0
  136. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/taskvine/factory_config.py +0 -0
  137. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/taskvine/manager.py +0 -0
  138. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/taskvine/manager_config.py +0 -0
  139. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/taskvine/utils.py +0 -0
  140. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/threads.py +0 -0
  141. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/workqueue/__init__.py +0 -0
  142. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/workqueue/errors.py +0 -0
  143. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/workqueue/exec_parsl_function.py +0 -0
  144. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/workqueue/parsl_coprocess.py +0 -0
  145. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/workqueue/parsl_coprocess_stub.py +0 -0
  146. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/jobs/__init__.py +0 -0
  147. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/jobs/error_handlers.py +0 -0
  148. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/jobs/errors.py +0 -0
  149. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/jobs/states.py +0 -0
  150. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/launchers/__init__.py +0 -0
  151. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/launchers/base.py +0 -0
  152. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/launchers/errors.py +0 -0
  153. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/launchers/launchers.py +0 -0
  154. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/log_utils.py +0 -0
  155. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/__init__.py +0 -0
  156. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/db_manager.py +0 -0
  157. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/message_type.py +0 -0
  158. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/queries/__init__.py +0 -0
  159. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/queries/pandas.py +0 -0
  160. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/remote.py +0 -0
  161. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/types.py +0 -0
  162. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/__init__.py +0 -0
  163. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/app.py +0 -0
  164. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/models.py +0 -0
  165. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/plots/__init__.py +0 -0
  166. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/plots/default/__init__.py +0 -0
  167. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/plots/default/task_plots.py +0 -0
  168. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/plots/default/workflow_plots.py +0 -0
  169. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/plots/default/workflow_resource_plots.py +0 -0
  170. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/static/parsl-logo-white.png +0 -0
  171. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/static/parsl-monitor.css +0 -0
  172. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/templates/app.html +0 -0
  173. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/templates/dag.html +0 -0
  174. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/templates/error.html +0 -0
  175. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/templates/layout.html +0 -0
  176. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/templates/resource_usage.html +0 -0
  177. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/templates/task.html +0 -0
  178. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/templates/workflow.html +0 -0
  179. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/templates/workflows_summary.html +0 -0
  180. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/utils.py +0 -0
  181. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/version.py +0 -0
  182. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/views.py +0 -0
  183. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/multiprocessing.py +0 -0
  184. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/process_loggers.py +0 -0
  185. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/__init__.py +0 -0
  186. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/ad_hoc/__init__.py +0 -0
  187. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/ad_hoc/ad_hoc.py +0 -0
  188. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/aws/__init__.py +0 -0
  189. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/aws/aws.py +0 -0
  190. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/aws/template.py +0 -0
  191. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/azure/__init__.py +0 -0
  192. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/azure/azure.py +0 -0
  193. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/azure/template.py +0 -0
  194. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/base.py +0 -0
  195. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/cluster_provider.py +0 -0
  196. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/cobalt/__init__.py +0 -0
  197. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/cobalt/cobalt.py +0 -0
  198. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/cobalt/template.py +0 -0
  199. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/condor/__init__.py +0 -0
  200. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/condor/condor.py +0 -0
  201. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/condor/template.py +0 -0
  202. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/errors.py +0 -0
  203. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/googlecloud/__init__.py +0 -0
  204. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/googlecloud/googlecloud.py +0 -0
  205. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/grid_engine/__init__.py +0 -0
  206. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/grid_engine/grid_engine.py +0 -0
  207. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/grid_engine/template.py +0 -0
  208. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/kubernetes/__init__.py +0 -0
  209. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/kubernetes/kube.py +0 -0
  210. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/kubernetes/template.py +0 -0
  211. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/local/__init__.py +0 -0
  212. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/lsf/__init__.py +0 -0
  213. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/lsf/lsf.py +0 -0
  214. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/lsf/template.py +0 -0
  215. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/pbspro/__init__.py +0 -0
  216. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/pbspro/pbspro.py +0 -0
  217. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/pbspro/template.py +0 -0
  218. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/slurm/__init__.py +0 -0
  219. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/slurm/slurm.py +0 -0
  220. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/slurm/template.py +0 -0
  221. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/torque/__init__.py +0 -0
  222. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/torque/template.py +0 -0
  223. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/torque/torque.py +0 -0
  224. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/py.typed +0 -0
  225. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/serialize/__init__.py +0 -0
  226. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/serialize/base.py +0 -0
  227. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/serialize/concretes.py +0 -0
  228. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/serialize/errors.py +0 -0
  229. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/serialize/facade.py +0 -0
  230. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/serialize/proxystore.py +0 -0
  231. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/__init__.py +0 -0
  232. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/callables_helper.py +0 -0
  233. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/__init__.py +0 -0
  234. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/ad_hoc_cluster_htex.py +0 -0
  235. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/azure_single_node.py +0 -0
  236. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/bluewaters.py +0 -0
  237. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/bridges.py +0 -0
  238. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/cc_in2p3.py +0 -0
  239. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/comet.py +0 -0
  240. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/cooley_htex.py +0 -0
  241. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/ec2_single_node.py +0 -0
  242. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/ec2_spot.py +0 -0
  243. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/frontera.py +0 -0
  244. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/htex_ad_hoc_cluster.py +0 -0
  245. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/htex_local.py +0 -0
  246. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/htex_local_intask_staging.py +0 -0
  247. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/htex_local_rsync_staging.py +0 -0
  248. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/local_adhoc.py +0 -0
  249. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/local_radical.py +0 -0
  250. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/local_radical_mpi.py +0 -0
  251. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/local_threads.py +0 -0
  252. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/local_threads_checkpoint.py +0 -0
  253. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/local_threads_checkpoint_dfk_exit.py +0 -0
  254. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/local_threads_checkpoint_periodic.py +0 -0
  255. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/local_threads_checkpoint_task_exit.py +0 -0
  256. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/local_threads_ftp_in_task.py +0 -0
  257. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/local_threads_globus.py +0 -0
  258. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/local_threads_http_in_task.py +0 -0
  259. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/local_threads_monitoring.py +0 -0
  260. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/local_threads_no_cache.py +0 -0
  261. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/midway.py +0 -0
  262. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/nscc_singapore.py +0 -0
  263. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/osg_htex.py +0 -0
  264. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/petrelkube.py +0 -0
  265. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/summit.py +0 -0
  266. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/swan_htex.py +0 -0
  267. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/theta.py +0 -0
  268. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/user_opts.py +0 -0
  269. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/__init__.py +0 -0
  270. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/latency.py +0 -0
  271. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/test_apps/__init__.py +0 -0
  272. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/test_channels/__init__.py +0 -0
  273. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/test_channels/test_channels.py +0 -0
  274. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/test_channels/test_local_channel.py +0 -0
  275. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/test_channels/test_scp_1.py +0 -0
  276. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/test_channels/test_ssh_1.py +0 -0
  277. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/test_channels/test_ssh_errors.py +0 -0
  278. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/test_channels/test_ssh_file_transport.py +0 -0
  279. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/test_channels/test_ssh_interactive.py +0 -0
  280. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/test_parsl_load_default_config.py +0 -0
  281. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/test_stress/__init__.py +0 -0
  282. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/test_stress/test_python_simple.py +0 -0
  283. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/test_stress/test_python_threads.py +0 -0
  284. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/manual_tests/__init__.py +0 -0
  285. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/manual_tests/htex_local.py +0 -0
  286. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/manual_tests/test_ad_hoc_htex.py +0 -0
  287. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/manual_tests/test_basic.py +0 -0
  288. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/manual_tests/test_fan_in_out_htex_remote.py +0 -0
  289. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/manual_tests/test_log_filter.py +0 -0
  290. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/manual_tests/test_memory_limits.py +0 -0
  291. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/manual_tests/test_oauth_ssh.py +0 -0
  292. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/manual_tests/test_regression_220.py +0 -0
  293. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/manual_tests/test_udp_simple.py +0 -0
  294. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/manual_tests/test_worker_count.py +0 -0
  295. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/scaling_tests/__init__.py +0 -0
  296. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/scaling_tests/htex_local.py +0 -0
  297. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/scaling_tests/local_threads.py +0 -0
  298. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/scaling_tests/test_scale.py +0 -0
  299. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/scaling_tests/vineex_condor.py +0 -0
  300. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/scaling_tests/vineex_local.py +0 -0
  301. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/scaling_tests/wqex_condor.py +0 -0
  302. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/scaling_tests/wqex_local.py +0 -0
  303. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/site_tests/__init__.py +0 -0
  304. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/site_tests/site_config_selector.py +0 -0
  305. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/site_tests/test_provider.py +0 -0
  306. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/site_tests/test_site.py +0 -0
  307. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/sites/__init__.py +0 -0
  308. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/sites/test_affinity.py +0 -0
  309. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/sites/test_concurrent.py +0 -0
  310. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/sites/test_dynamic_executor.py +0 -0
  311. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/sites/test_ec2.py +0 -0
  312. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/sites/test_launchers.py +0 -0
  313. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/sites/test_local_adhoc.py +0 -0
  314. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/sites/test_mpi/__init__.py +0 -0
  315. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/sites/test_worker_info.py +0 -0
  316. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_aalst_patterns.py +0 -0
  317. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_bash_apps/__init__.py +0 -0
  318. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_bash_apps/test_apptimeout.py +0 -0
  319. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_bash_apps/test_keyword_overlaps.py +0 -0
  320. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_bash_apps/test_pipeline.py +0 -0
  321. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_callables.py +0 -0
  322. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_channels/__init__.py +0 -0
  323. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_channels/test_large_output.py +0 -0
  324. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_checkpointing/__init__.py +0 -0
  325. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_checkpointing/test_periodic.py +0 -0
  326. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_checkpointing/test_python_checkpoint_1.py +0 -0
  327. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_checkpointing/test_python_checkpoint_2.py +0 -0
  328. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_checkpointing/test_python_checkpoint_3.py +0 -0
  329. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_checkpointing/test_regression_232.py +0 -0
  330. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_checkpointing/test_regression_233.py +0 -0
  331. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_checkpointing/test_regression_239.py +0 -0
  332. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_curvezmq.py +0 -0
  333. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_docs/__init__.py +0 -0
  334. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_docs/test_from_slides.py +0 -0
  335. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_docs/test_kwargs.py +0 -0
  336. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_docs/test_tutorial_1.py +0 -0
  337. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_docs/test_workflow1.py +0 -0
  338. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_docs/test_workflow2.py +0 -0
  339. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_docs/test_workflow4.py +0 -0
  340. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_error_handling/__init__.py +0 -0
  341. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_error_handling/test_fail.py +0 -0
  342. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_error_handling/test_python_walltime.py +0 -0
  343. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_error_handling/test_rand_fail.py +0 -0
  344. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_error_handling/test_resource_spec.py +0 -0
  345. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_error_handling/test_retries.py +0 -0
  346. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_error_handling/test_retry_handler.py +0 -0
  347. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_error_handling/test_retry_handler_failure.py +0 -0
  348. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_error_handling/test_serialization_fail.py +0 -0
  349. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_error_handling/test_wrap_with_logs.py +0 -0
  350. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_flowcontrol/__init__.py +0 -0
  351. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_flux.py +0 -0
  352. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_htex/__init__.py +0 -0
  353. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_htex/test_basic.py +0 -0
  354. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_htex/test_connected_blocks.py +0 -0
  355. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_htex/test_cpu_affinity_explicit.py +0 -0
  356. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_htex/test_disconnected_blocks.py +0 -0
  357. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_htex/test_drain.py +0 -0
  358. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_htex/test_htex.py +0 -0
  359. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_htex/test_manager_failure.py +0 -0
  360. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_htex/test_missing_worker.py +0 -0
  361. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_htex/test_multiple_disconnected_blocks.py +0 -0
  362. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_htex/test_worker_failure.py +0 -0
  363. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_monitoring/__init__.py +0 -0
  364. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_monitoring/test_app_names.py +0 -0
  365. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_monitoring/test_db_locks.py +0 -0
  366. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_monitoring/test_htex_init_blocks_vs_monitoring.py +0 -0
  367. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_monitoring/test_incomplete_futures.py +0 -0
  368. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_monitoring/test_memoization_representation.py +0 -0
  369. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_monitoring/test_viz_colouring.py +0 -0
  370. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_mpi_apps/__init__.py +0 -0
  371. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_mpi_apps/test_bad_mpi_config.py +0 -0
  372. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_mpi_apps/test_mpi_mode_disabled.py +0 -0
  373. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_mpi_apps/test_mpi_mode_enabled.py +0 -0
  374. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_mpi_apps/test_mpi_prefix.py +0 -0
  375. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_mpi_apps/test_mpi_scheduler.py +0 -0
  376. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_mpi_apps/test_resource_spec.py +0 -0
  377. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_providers/__init__.py +0 -0
  378. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_providers/test_cobalt_deprecation_warning.py +0 -0
  379. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_providers/test_local_provider.py +0 -0
  380. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_providers/test_pbspro_template.py +0 -0
  381. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_providers/test_slurm_instantiate.py +0 -0
  382. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_providers/test_slurm_template.py +0 -0
  383. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_providers/test_submiterror_deprecation.py +0 -0
  384. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/__init__.py +0 -0
  385. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_arg_input_types.py +0 -0
  386. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_basic.py +0 -0
  387. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_dep_standard_futures.py +0 -0
  388. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_dependencies.py +0 -0
  389. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_depfail_propagation.py +0 -0
  390. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_fail.py +0 -0
  391. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_fibonacci_iterative.py +0 -0
  392. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_fibonacci_recursive.py +0 -0
  393. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_futures.py +0 -0
  394. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_garbage_collect.py +0 -0
  395. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_import_fail.py +0 -0
  396. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_join.py +0 -0
  397. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_lifted.py +0 -0
  398. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_mapred.py +0 -0
  399. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_memoize_1.py +0 -0
  400. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_memoize_2.py +0 -0
  401. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_memoize_4.py +0 -0
  402. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_memoize_bad_id_for_memo.py +0 -0
  403. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_memoize_ignore_args.py +0 -0
  404. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_memoize_joinapp.py +0 -0
  405. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_overview.py +0 -0
  406. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_pipeline.py +0 -0
  407. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_simple.py +0 -0
  408. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_timeout.py +0 -0
  409. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_type5.py +0 -0
  410. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_radical/__init__.py +0 -0
  411. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_radical/test_mpi_funcs.py +0 -0
  412. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_regression/__init__.py +0 -0
  413. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_regression/test_1480.py +0 -0
  414. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_regression/test_1606_wait_for_current_tasks.py +0 -0
  415. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_regression/test_1653.py +0 -0
  416. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_regression/test_221.py +0 -0
  417. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_regression/test_226.py +0 -0
  418. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_regression/test_2652.py +0 -0
  419. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_regression/test_69a.py +0 -0
  420. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_regression/test_854.py +0 -0
  421. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_regression/test_97_parallelism_0.py +0 -0
  422. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_regression/test_98.py +0 -0
  423. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_scaling/__init__.py +0 -0
  424. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_scaling/test_block_error_handler.py +0 -0
  425. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_scaling/test_scale_down.py +0 -0
  426. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_scaling/test_scale_down_htex_auto_scale.py +0 -0
  427. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_scaling/test_shutdown_scalein.py +0 -0
  428. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_serialization/__init__.py +0 -0
  429. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_serialization/test_2555_caching_deserializer.py +0 -0
  430. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_serialization/test_basic.py +0 -0
  431. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_serialization/test_htex_code_cache.py +0 -0
  432. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_serialization/test_pack_resource_spec.py +0 -0
  433. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_serialization/test_proxystore_configured.py +0 -0
  434. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_serialization/test_proxystore_impl.py +0 -0
  435. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_shutdown/__init__.py +0 -0
  436. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_shutdown/test_kill_monitoring.py +0 -0
  437. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/__init__.py +0 -0
  438. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/staging_provider.py +0 -0
  439. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/test_1316.py +0 -0
  440. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/test_docs_1.py +0 -0
  441. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/test_docs_2.py +0 -0
  442. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/test_elaborate_noop_file.py +0 -0
  443. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/test_file.py +0 -0
  444. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/test_file_apps.py +0 -0
  445. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/test_file_staging.py +0 -0
  446. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/test_output_chain_filenames.py +0 -0
  447. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/test_staging_ftp.py +0 -0
  448. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/test_staging_ftp_in_task.py +0 -0
  449. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/test_staging_globus.py +0 -0
  450. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/test_staging_https.py +0 -0
  451. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_summary.py +0 -0
  452. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_thread_parallelism.py +0 -0
  453. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_threads/__init__.py +0 -0
  454. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_threads/test_configs.py +0 -0
  455. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_threads/test_lazy_errors.py +0 -0
  456. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_utils/__init__.py +0 -0
  457. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_utils/test_representation_mixin.py +0 -0
  458. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/utils.py +0 -0
  459. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/usage_tracking/__init__.py +0 -0
  460. {parsl-2024.4.8 → parsl-2024.4.22}/parsl/usage_tracking/usage.py +0 -0
  461. {parsl-2024.4.8 → parsl-2024.4.22}/parsl.egg-info/dependency_links.txt +0 -0
  462. {parsl-2024.4.8 → parsl-2024.4.22}/parsl.egg-info/entry_points.txt +0 -0
  463. {parsl-2024.4.8 → parsl-2024.4.22}/parsl.egg-info/top_level.txt +0 -0
  464. {parsl-2024.4.8 → parsl-2024.4.22}/setup.cfg +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: parsl
3
- Version: 2024.4.8
3
+ Version: 2024.4.22
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.04.08.tar.gz
6
+ Download-URL: https://github.com/Parsl/parsl/archive/2024.04.22.tar.gz
7
7
  Author: The Parsl Team
8
8
  Author-email: parsl@googlegroups.com
9
9
  License: Apache 2.0
@@ -113,7 +113,7 @@ def get_all_addresses() -> Set[str]:
113
113
  try:
114
114
  s_addresses.add(address_by_interface(interface))
115
115
  except Exception:
116
- logger.info("Ignoring failure to fetch address from interface {}".format(interface))
116
+ logger.debug("Ignoring failure to fetch address from interface {}".format(interface))
117
117
 
118
118
  resolution_functions: List[Callable[[], str]]
119
119
  resolution_functions = [address_by_hostname, address_by_route, address_by_query]
@@ -121,7 +121,7 @@ def get_all_addresses() -> Set[str]:
121
121
  try:
122
122
  s_addresses.add(f())
123
123
  except Exception:
124
- logger.info("Ignoring an address finder exception")
124
+ logger.debug("Ignoring an address finder exception")
125
125
 
126
126
  return s_addresses
127
127
 
@@ -5,6 +5,7 @@ import logging
5
5
 
6
6
  from parsl.app.errors import wrap_error
7
7
  from parsl.app.app import AppBase
8
+ from parsl.data_provider.files import File
8
9
  from parsl.dataflow.dflow import DataFlowKernelLoader
9
10
 
10
11
  logger = logging.getLogger(__name__)
@@ -54,13 +55,20 @@ def remote_side_bash_executor(func, *args, **kwargs):
54
55
  if stdfspec is None:
55
56
  return None
56
57
 
57
- fname, mode = get_std_fname_mode(fdname, stdfspec)
58
+ if isinstance(stdfspec, File):
59
+ # a File is an os.PathLike and so we can use it directly for
60
+ # the subsequent file operations
61
+ fname = stdfspec
62
+ mode = "w"
63
+ else:
64
+ fname, mode = get_std_fname_mode(fdname, stdfspec)
65
+
58
66
  try:
59
67
  if os.path.dirname(fname):
60
68
  os.makedirs(os.path.dirname(fname), exist_ok=True)
61
69
  fd = open(fname, mode)
62
70
  except Exception as e:
63
- raise pe.BadStdStreamFile(fname, e)
71
+ raise pe.BadStdStreamFile(str(fname)) from e
64
72
  return fd
65
73
 
66
74
  std_out = open_std_fd('stdout')
@@ -78,16 +78,14 @@ class BadStdStreamFile(ParslError):
78
78
 
79
79
  Contains:
80
80
  reason(string)
81
- exception object
82
81
  """
83
82
 
84
- def __init__(self, reason: str, exception: Exception) -> None:
85
- super().__init__(reason, exception)
83
+ def __init__(self, reason: str) -> None:
84
+ super().__init__(reason)
86
85
  self._reason = reason
87
- self._exception = exception
88
86
 
89
87
  def __repr__(self) -> str:
90
- return "Bad Stream File: {} Exception: {}".format(self._reason, self._exception)
88
+ return "Bad Stream File: {}".format(self._reason)
91
89
 
92
90
  def __str__(self) -> str:
93
91
  return self.__repr__()
@@ -7,6 +7,7 @@ from parsl.data_provider.files import File
7
7
  from parsl.data_provider.file_noop import NoOpFileStaging
8
8
  from parsl.data_provider.ftp import FTPSeparateTaskStaging
9
9
  from parsl.data_provider.http import HTTPSeparateTaskStaging
10
+ from parsl.data_provider.zip import ZipFileStaging
10
11
  from parsl.data_provider.staging import Staging
11
12
 
12
13
  if TYPE_CHECKING:
@@ -17,7 +18,7 @@ logger = logging.getLogger(__name__)
17
18
  # these will be shared between all executors that do not explicitly
18
19
  # override, so should not contain executor-specific state
19
20
  default_staging: List[Staging]
20
- default_staging = [NoOpFileStaging(), FTPSeparateTaskStaging(), HTTPSeparateTaskStaging()]
21
+ default_staging = [NoOpFileStaging(), FTPSeparateTaskStaging(), HTTPSeparateTaskStaging(), ZipFileStaging()]
21
22
 
22
23
 
23
24
  class DataManager:
@@ -0,0 +1,104 @@
1
+ import filelock
2
+ import logging
3
+ import os
4
+ import parsl
5
+ import zipfile
6
+
7
+ from typing import Tuple
8
+
9
+ from parsl.data_provider.staging import Staging
10
+ from parsl.data_provider.files import File
11
+ from parsl.errors import ParslError
12
+
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ class ZipAuthorityError(ParslError):
18
+ def __init__(self, file):
19
+ self.file = file
20
+
21
+ def __str__(self):
22
+ return f"ZipFileStaging cannot stage Files with an authority (netloc) section ({self.file.netloc}), for {self.file.url}"
23
+
24
+
25
+ class ZipFileStaging(Staging):
26
+ """A stage-out provider for zip files.
27
+
28
+ This provider will stage out files by writing them into the specified zip
29
+ file.
30
+
31
+ The filename of both the zip file and the file contained in that zip are
32
+ specified using a zip: URL, like this:
33
+
34
+ zip:/tmp/foo/this.zip/inside/here.txt
35
+
36
+ This URL names a zip file ``/tmp/foo/this.zip`` containing a file
37
+ ``inside/here.txt``.
38
+
39
+ The provider will use the Python filelock package to lock the zip file so
40
+ that it does not conflict with other instances of itself. This lock will
41
+ not protect against other modifications to the zip file.
42
+ """
43
+
44
+ def can_stage_out(self, file: File) -> bool:
45
+ logger.debug("archive provider checking File {}".format(repr(file)))
46
+
47
+ # First check if this is the scheme we care about
48
+ if file.scheme != "zip":
49
+ return False
50
+
51
+ # This is some basic validation to check that the user isn't specifying
52
+ # an authority section and expecting it to mean something.
53
+ if file.netloc != "":
54
+ raise ZipAuthorityError(file)
55
+
56
+ # If we got this far, we can stage this file
57
+ return True
58
+
59
+ def stage_out(self, dm, executor, file, parent_fut):
60
+ assert file.scheme == 'zip'
61
+
62
+ zip_path, inside_path = zip_path_split(file.path)
63
+
64
+ working_dir = dm.dfk.executors[executor].working_dir
65
+
66
+ if working_dir:
67
+ file.local_path = os.path.join(working_dir, inside_path)
68
+
69
+ # TODO: I think its the right behaviour that a staging out provider should create the directory structure
70
+ # for the file to be placed in?
71
+ os.makedirs(os.path.dirname(file.local_path), exist_ok=True)
72
+ else:
73
+ raise RuntimeError("zip file staging requires a working_dir to be specified")
74
+
75
+ stage_out_app = _zip_stage_out_app(dm)
76
+ app_fut = stage_out_app(zip_path, inside_path, working_dir, inputs=[file], _parsl_staging_inhibit=True, parent_fut=parent_fut)
77
+ return app_fut
78
+
79
+
80
+ def _zip_stage_out(zip_file, inside_path, working_dir, parent_fut=None, inputs=[], _parsl_staging_inhibit=True):
81
+ file = inputs[0]
82
+
83
+ os.makedirs(os.path.dirname(zip_file), exist_ok=True)
84
+
85
+ with filelock.FileLock(zip_file + ".lock"):
86
+ with zipfile.ZipFile(zip_file, mode='a', compression=zipfile.ZIP_DEFLATED) as z:
87
+ z.write(file, arcname=inside_path)
88
+
89
+ os.remove(file)
90
+
91
+
92
+ def _zip_stage_out_app(dm):
93
+ return parsl.python_app(executors=['_parsl_internal'], data_flow_kernel=dm.dfk)(_zip_stage_out)
94
+
95
+
96
+ def zip_path_split(path: str) -> Tuple[str, str]:
97
+ """Split zip: path into a zipfile name and a contained-file name.
98
+ """
99
+ index = path.find(".zip/")
100
+
101
+ zip_path = path[:index + 4]
102
+ inside_path = path[index + 5:]
103
+
104
+ return (zip_path, inside_path)
@@ -177,10 +177,11 @@ class DataFlowKernel:
177
177
 
178
178
  # this must be set before executors are added since add_executors calls
179
179
  # job_status_poller.add_executors.
180
+ radio = self.monitoring.radio if self.monitoring else None
180
181
  self.job_status_poller = JobStatusPoller(strategy=self.config.strategy,
181
182
  strategy_period=self.config.strategy_period,
182
183
  max_idletime=self.config.max_idletime,
183
- dfk=self)
184
+ monitoring=radio)
184
185
 
185
186
  self.executors: Dict[str, ParslExecutor] = {}
186
187
 
@@ -218,14 +219,18 @@ class DataFlowKernel:
218
219
  task_log_info = self._create_task_log_info(task_record)
219
220
  self.monitoring.send(MessageType.TASK_INFO, task_log_info)
220
221
 
221
- def _create_task_log_info(self, task_record):
222
+ def _create_task_log_info(self, task_record: TaskRecord) -> Dict[str, Any]:
222
223
  """
223
224
  Create the dictionary that will be included in the log.
224
225
  """
225
226
  info_to_monitor = ['func_name', 'memoize', 'hashsum', 'fail_count', 'fail_cost', 'status',
226
227
  'id', 'time_invoked', 'try_time_launched', 'time_returned', 'try_time_returned', 'executor']
227
228
 
228
- task_log_info = {"task_" + k: task_record[k] for k in info_to_monitor}
229
+ # mypy cannot verify that these task_record[k] references are valid:
230
+ # They are valid if all entries in info_to_monitor are declared in the definition of TaskRecord
231
+ # This type: ignore[literal-required] asserts that fact.
232
+ task_log_info = {"task_" + k: task_record[k] for k in info_to_monitor} # type: ignore[literal-required]
233
+
229
234
  task_log_info['run_id'] = self.run_id
230
235
  task_log_info['try_id'] = task_record['try_id']
231
236
  task_log_info['timestamp'] = datetime.datetime.now()
@@ -237,20 +242,28 @@ class DataFlowKernel:
237
242
  task_log_info['task_inputs'] = str(task_record['kwargs'].get('inputs', None))
238
243
  task_log_info['task_outputs'] = str(task_record['kwargs'].get('outputs', None))
239
244
  task_log_info['task_stdin'] = task_record['kwargs'].get('stdin', None)
240
- stdout_spec = task_record['kwargs'].get('stdout', None)
241
- stderr_spec = task_record['kwargs'].get('stderr', None)
242
- try:
243
- stdout_name, _ = get_std_fname_mode('stdout', stdout_spec)
244
- except Exception as e:
245
- logger.warning("Incorrect stdout format {} for Task {}".format(stdout_spec, task_record['id']))
246
- stdout_name = str(e)
247
- try:
248
- stderr_name, _ = get_std_fname_mode('stderr', stderr_spec)
249
- except Exception as e:
250
- logger.warning("Incorrect stderr format {} for Task {}".format(stderr_spec, task_record['id']))
251
- stderr_name = str(e)
252
- task_log_info['task_stdout'] = stdout_name
253
- task_log_info['task_stderr'] = stderr_name
245
+
246
+ def std_spec_to_name(name, spec):
247
+ if spec is None:
248
+ name = ""
249
+ elif isinstance(spec, File):
250
+ name = spec.url
251
+ else:
252
+ # fallthrough case is various str, os.PathLike, tuple modes that
253
+ # can be interpreted by get_std_fname_mode.
254
+ try:
255
+ name, _ = get_std_fname_mode(name, spec)
256
+ except Exception:
257
+ logger.exception(f"Could not parse {name} specification {spec} for task {task_record['id']}")
258
+ name = ""
259
+ return name
260
+
261
+ stdout_spec = task_record['kwargs'].get('stdout')
262
+ task_log_info['task_stdout'] = std_spec_to_name('stdout', stdout_spec)
263
+
264
+ stderr_spec = task_record['kwargs'].get('stderr')
265
+ task_log_info['task_stderr'] = std_spec_to_name('stderr', stderr_spec)
266
+
254
267
  task_log_info['task_fail_history'] = ",".join(task_record['fail_history'])
255
268
  task_log_info['task_depends'] = None
256
269
  if task_record['depends'] is not None:
@@ -674,14 +687,6 @@ class DataFlowKernel:
674
687
  def launch_task(self, task_record: TaskRecord) -> Future:
675
688
  """Handle the actual submission of the task to the executor layer.
676
689
 
677
- If the app task has the executors attributes not set (default=='all')
678
- the task is launched on a randomly selected executor from the
679
- list of executors. This behavior could later be updated to support
680
- binding to executors based on user specified criteria.
681
-
682
- If the app task specifies a particular set of executors, it will be
683
- targeted at those specific executors.
684
-
685
690
  Args:
686
691
  task_record : The task record
687
692
 
@@ -768,6 +773,10 @@ class DataFlowKernel:
768
773
  (inputs[idx], func) = self.data_manager.optionally_stage_in(f, func, executor)
769
774
 
770
775
  for kwarg, f in kwargs.items():
776
+ # stdout and stderr files should not be staging in (they will be staged *out*
777
+ # in _add_output_deps)
778
+ if kwarg in ['stdout', 'stderr']:
779
+ continue
771
780
  (kwargs[kwarg], func) = self.data_manager.optionally_stage_in(f, func, executor)
772
781
 
773
782
  newargs = list(args)
@@ -780,33 +789,56 @@ class DataFlowKernel:
780
789
  logger.debug("Adding output dependencies")
781
790
  outputs = kwargs.get('outputs', [])
782
791
  app_fut._outputs = []
783
- for idx, f in enumerate(outputs):
784
- if isinstance(f, File) and not self.check_staging_inhibited(kwargs):
792
+
793
+ # Pass over all possible outputs: the outputs kwarg, stdout and stderr
794
+ # and for each of those, perform possible stage-out. This can result in:
795
+ # a DataFuture to be exposed in app_fut to represent the completion of
796
+ # that stageout (sometimes backed by a new sub-workflow for separate-task
797
+ # stageout), a replacement for the function to be executed (intended to
798
+ # be the original function wrapped with an in-task stageout wrapper), a
799
+ # rewritten File object to be passed to task to be executed
800
+
801
+ @typechecked
802
+ def stageout_one_file(file: File, rewritable_func: Callable):
803
+ if not self.check_staging_inhibited(kwargs):
785
804
  # replace a File with a DataFuture - either completing when the stageout
786
805
  # future completes, or if no stage out future is returned, then when the
787
806
  # app itself completes.
788
807
 
789
808
  # The staging code will get a clean copy which it is allowed to mutate,
790
809
  # while the DataFuture-contained original will not be modified by any staging.
791
- f_copy = f.cleancopy()
792
- outputs[idx] = f_copy
810
+ f_copy = file.cleancopy()
793
811
 
794
- logger.debug("Submitting stage out for output file {}".format(repr(f)))
812
+ logger.debug("Submitting stage out for output file {}".format(repr(file)))
795
813
  stageout_fut = self.data_manager.stage_out(f_copy, executor, app_fut)
796
814
  if stageout_fut:
797
- logger.debug("Adding a dependency on stageout future for {}".format(repr(f)))
798
- app_fut._outputs.append(DataFuture(stageout_fut, f, tid=app_fut.tid))
815
+ logger.debug("Adding a dependency on stageout future for {}".format(repr(file)))
816
+ df = DataFuture(stageout_fut, file, tid=app_fut.tid)
799
817
  else:
800
- logger.debug("No stageout dependency for {}".format(repr(f)))
801
- app_fut._outputs.append(DataFuture(app_fut, f, tid=app_fut.tid))
818
+ logger.debug("No stageout dependency for {}".format(repr(file)))
819
+ df = DataFuture(app_fut, file, tid=app_fut.tid)
802
820
 
803
821
  # this is a hook for post-task stageout
804
822
  # note that nothing depends on the output - which is maybe a bug
805
823
  # in the not-very-tested stageout system?
806
- func = self.data_manager.replace_task_stage_out(f_copy, func, executor)
824
+ rewritable_func = self.data_manager.replace_task_stage_out(f_copy, rewritable_func, executor)
825
+ return rewritable_func, f_copy, df
807
826
  else:
808
- logger.debug("Not performing output staging for: {}".format(repr(f)))
809
- app_fut._outputs.append(DataFuture(app_fut, f, tid=app_fut.tid))
827
+ logger.debug("Not performing output staging for: {}".format(repr(file)))
828
+ return rewritable_func, file, DataFuture(app_fut, file, tid=app_fut.tid)
829
+
830
+ for idx, file in enumerate(outputs):
831
+ func, outputs[idx], o = stageout_one_file(file, func)
832
+ app_fut._outputs.append(o)
833
+
834
+ file = kwargs.get('stdout')
835
+ if isinstance(file, File):
836
+ func, kwargs['stdout'], app_fut._stdout_future = stageout_one_file(file, func)
837
+
838
+ file = kwargs.get('stderr')
839
+ if isinstance(file, File):
840
+ func, kwargs['stderr'], app_fut._stderr_future = stageout_one_file(file, func)
841
+
810
842
  return func
811
843
 
812
844
  def _gather_all_deps(self, args: Sequence[Any], kwargs: Dict[str, Any]) -> List[Future]:
@@ -1132,6 +1164,8 @@ class DataFlowKernel:
1132
1164
  executor.run_dir = self.run_dir
1133
1165
  executor.hub_address = self.hub_address
1134
1166
  executor.hub_port = self.hub_zmq_port
1167
+ if self.monitoring:
1168
+ executor.monitoring_radio = self.monitoring.radio
1135
1169
  if hasattr(executor, 'provider'):
1136
1170
  if hasattr(executor.provider, 'script_dir'):
1137
1171
  executor.provider.script_dir = os.path.join(self.run_dir, 'submit_scripts')
@@ -1235,8 +1269,7 @@ class DataFlowKernel:
1235
1269
  'tasks_completed_count': self.task_state_counts[States.exec_done],
1236
1270
  "time_began": self.time_began,
1237
1271
  'time_completed': self.time_completed,
1238
- 'run_id': self.run_id, 'rundir': self.run_dir,
1239
- 'exit_now': True})
1272
+ 'run_id': self.run_id, 'rundir': self.run_dir})
1240
1273
 
1241
1274
  logger.info("Terminating monitoring")
1242
1275
  self.monitoring.close()
@@ -1386,10 +1419,26 @@ class DataFlowKernel:
1386
1419
 
1387
1420
  @staticmethod
1388
1421
  def _log_std_streams(task_record: TaskRecord) -> None:
1389
- if task_record['app_fu'].stdout is not None:
1390
- logger.info("Standard output for task {} available at {}".format(task_record['id'], task_record['app_fu'].stdout))
1391
- if task_record['app_fu'].stderr is not None:
1392
- logger.info("Standard error for task {} available at {}".format(task_record['id'], task_record['app_fu'].stderr))
1422
+ tid = task_record['id']
1423
+
1424
+ def log_std_stream(name: str, target) -> None:
1425
+ if target is None:
1426
+ logger.info(f"{name} for task {tid} will not be redirected.")
1427
+ elif isinstance(target, str):
1428
+ logger.info(f"{name} for task {tid} will be redirected to {target}")
1429
+ elif isinstance(target, os.PathLike):
1430
+ logger.info(f"{name} for task {tid} will be redirected to {os.fspath(target)}")
1431
+ elif isinstance(target, tuple) and len(target) == 2 and isinstance(target[0], str):
1432
+ logger.info(f"{name} for task {tid} will be redirected to {target[0]} with mode {target[1]}")
1433
+ elif isinstance(target, tuple) and len(target) == 2 and isinstance(target[0], os.PathLike):
1434
+ logger.info(f"{name} for task {tid} will be redirected to {os.fspath(target[0])} with mode {target[1]}")
1435
+ elif isinstance(target, DataFuture):
1436
+ logger.info(f"{name} for task {tid} will staged to {target.file_obj.url}")
1437
+ else:
1438
+ logger.error(f"{name} for task {tid} has unknown specification: {target!r}")
1439
+
1440
+ log_std_stream("Standard out", task_record['app_fu'].stdout)
1441
+ log_std_stream("Standard error", task_record['app_fu'].stderr)
1393
1442
 
1394
1443
 
1395
1444
  class DataFlowKernelLoader:
@@ -1,16 +1,9 @@
1
- """This module implements the AppFutures.
2
-
3
- We have two basic types of futures:
4
- 1. DataFutures which represent data objects
5
- 2. AppFutures which represent the futures on App/Leaf tasks.
6
-
7
- """
8
1
  from __future__ import annotations
9
2
 
10
3
  from concurrent.futures import Future
11
4
  import logging
12
5
  import threading
13
- from typing import Any, Optional, Sequence
6
+ from typing import Any, Optional, Sequence, Union
14
7
 
15
8
  import parsl.app.app as app
16
9
 
@@ -77,13 +70,34 @@ class AppFuture(Future):
77
70
  self._outputs = []
78
71
  self.task_record = task_record
79
72
 
73
+ self._stdout_future: Optional[DataFuture] = None
74
+ self._stderr_future: Optional[DataFuture] = None
75
+
80
76
  @property
81
- def stdout(self) -> Optional[str]:
82
- return self.task_record['kwargs'].get('stdout')
77
+ def stdout(self) -> Union[None, str, DataFuture]:
78
+ """Return app stdout. If stdout was specified as a string, then this
79
+ property will return that string. If stdout was specified as a File,
80
+ then this property will return a DataFuture representing that file
81
+ stageout.
82
+ TODO: this can be a tuple too I think?"""
83
+ if self._stdout_future:
84
+ return self._stdout_future
85
+ else:
86
+ # this covers the str and None cases
87
+ return self.task_record['kwargs'].get('stdout')
83
88
 
84
89
  @property
85
- def stderr(self) -> Optional[str]:
86
- return self.task_record['kwargs'].get('stderr')
90
+ def stderr(self) -> Union[None, str, DataFuture]:
91
+ """Return app stderr. If stdout was specified as a string, then this
92
+ property will return that string. If stdout was specified as a File,
93
+ then this property will return a DataFuture representing that file
94
+ stageout.
95
+ TODO: this can be a tuple too I think?"""
96
+ if self._stderr_future:
97
+ return self._stderr_future
98
+ else:
99
+ # this covers the str and None cases
100
+ return self.task_record['kwargs'].get('stderr')
87
101
 
88
102
  @property
89
103
  def tid(self) -> int:
@@ -1,9 +1,10 @@
1
+ import os
1
2
  from abc import ABCMeta, abstractmethod
2
3
  from concurrent.futures import Future
3
- from typing import Any, Callable, Dict, Optional, List
4
+ from typing import Any, Callable, Dict, Optional
4
5
  from typing_extensions import Literal, Self
5
6
 
6
- from parsl.jobs.states import JobStatus
7
+ from parsl.monitoring.radios import MonitoringRadio
7
8
 
8
9
 
9
10
  class ParslExecutor(metaclass=ABCMeta):
@@ -45,6 +46,21 @@ class ParslExecutor(metaclass=ABCMeta):
45
46
  label: str = "undefined"
46
47
  radio_mode: str = "udp"
47
48
 
49
+ def __init__(
50
+ self,
51
+ *,
52
+ hub_address: Optional[str] = None,
53
+ hub_port: Optional[int] = None,
54
+ monitoring_radio: Optional[MonitoringRadio] = None,
55
+ run_dir: str = ".",
56
+ run_id: Optional[str] = None,
57
+ ):
58
+ self.hub_address = hub_address
59
+ self.hub_port = hub_port
60
+ self.monitoring_radio = monitoring_radio
61
+ self.run_dir = os.path.abspath(run_dir)
62
+ self.run_id = run_id
63
+
48
64
  def __enter__(self) -> Self:
49
65
  return self
50
66
 
@@ -79,13 +95,6 @@ class ParslExecutor(metaclass=ABCMeta):
79
95
  """
80
96
  pass
81
97
 
82
- def create_monitoring_info(self, status: Dict[str, JobStatus]) -> List[object]:
83
- """Create a monitoring message for each block based on the poll status.
84
-
85
- :return: a list of dictionaries mapping to the info of each block
86
- """
87
- return []
88
-
89
98
  def monitor_resources(self) -> bool:
90
99
  """Should resource monitoring happen for tasks on running on this executor?
91
100
 
@@ -135,3 +144,13 @@ class ParslExecutor(metaclass=ABCMeta):
135
144
  @hub_port.setter
136
145
  def hub_port(self, value: Optional[int]) -> None:
137
146
  self._hub_port = value
147
+
148
+ @property
149
+ def monitoring_radio(self) -> Optional[MonitoringRadio]:
150
+ """Local radio for sending monitoring messages
151
+ """
152
+ return self._monitoring_radio
153
+
154
+ @monitoring_radio.setter
155
+ def monitoring_radio(self, value: Optional[MonitoringRadio]) -> None:
156
+ self._monitoring_radio = value
@@ -5,7 +5,6 @@ import typeguard
5
5
  import logging
6
6
  import threading
7
7
  import queue
8
- import datetime
9
8
  import pickle
10
9
  from dataclasses import dataclass
11
10
  from multiprocessing import Process, Queue
@@ -18,7 +17,7 @@ import parsl.launchers
18
17
  from parsl.serialize import pack_res_spec_apply_message, deserialize
19
18
  from parsl.serialize.errors import SerializationError, DeserializationError
20
19
  from parsl.app.errors import RemoteExceptionWrapper
21
- from parsl.jobs.states import JobStatus, JobState
20
+ from parsl.jobs.states import JobStatus, JobState, TERMINAL_STATES
22
21
  from parsl.executors.high_throughput import zmq_pipes
23
22
  from parsl.executors.high_throughput import interchange
24
23
  from parsl.executors.errors import (
@@ -677,22 +676,6 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin):
677
676
  # Return the future
678
677
  return fut
679
678
 
680
- def create_monitoring_info(self, status):
681
- """ Create a msg for monitoring based on the poll status
682
-
683
- """
684
- msg = []
685
- for bid, s in status.items():
686
- d = {}
687
- d['run_id'] = self.run_id
688
- d['status'] = s.status_name
689
- d['timestamp'] = datetime.datetime.now()
690
- d['executor_label'] = self.label
691
- d['job_id'] = self.blocks_to_job_id.get(bid, None)
692
- d['block_id'] = bid
693
- msg.append(d)
694
- return msg
695
-
696
679
  @property
697
680
  def workers_per_node(self) -> Union[int, float]:
698
681
  return self._workers_per_node
@@ -730,8 +713,20 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin):
730
713
  tasks: int # sum of tasks in this block
731
714
  idle: float # shortest idle time of any manager in this block
732
715
 
716
+ # block_info will be populated from two sources:
717
+ # the Job Status Poller mutable block list, and the list of blocks
718
+ # which have connected to the interchange.
719
+
720
+ def new_block_info():
721
+ return BlockInfo(tasks=0, idle=float('inf'))
722
+
723
+ block_info: Dict[str, BlockInfo] = defaultdict(new_block_info)
724
+
725
+ for block_id, job_status in self._status.items():
726
+ if job_status.state not in TERMINAL_STATES:
727
+ block_info[block_id] = new_block_info()
728
+
733
729
  managers = self.connected_managers()
734
- block_info: Dict[str, BlockInfo] = defaultdict(lambda: BlockInfo(tasks=0, idle=float('inf')))
735
730
  for manager in managers:
736
731
  if not manager['active']:
737
732
  continue
@@ -361,7 +361,9 @@ class Manager:
361
361
  kill_event.set()
362
362
  else:
363
363
  task_recv_counter += len(tasks)
364
- logger.debug("Got executor tasks: {}, cumulative count of tasks: {}".format([t['task_id'] for t in tasks], task_recv_counter))
364
+ logger.debug("Got executor tasks: {}, cumulative count of tasks: {}".format(
365
+ [t['task_id'] for t in tasks], task_recv_counter
366
+ ))
365
367
 
366
368
  for task in tasks:
367
369
  self.task_scheduler.put_task(task)