parsl 2024.3.18__py3-none-any.whl → 2025.1.13__py3-none-any.whl

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 (369) hide show
  1. parsl/__init__.py +9 -10
  2. parsl/addresses.py +26 -6
  3. parsl/app/app.py +7 -8
  4. parsl/app/bash.py +15 -8
  5. parsl/app/errors.py +10 -13
  6. parsl/app/futures.py +8 -10
  7. parsl/app/python.py +2 -1
  8. parsl/benchmark/perf.py +2 -1
  9. parsl/concurrent/__init__.py +2 -2
  10. parsl/config.py +53 -10
  11. parsl/configs/ASPIRE1.py +6 -5
  12. parsl/configs/Azure.py +9 -8
  13. parsl/configs/bridges.py +6 -4
  14. parsl/configs/cc_in2p3.py +3 -3
  15. parsl/configs/ec2.py +3 -1
  16. parsl/configs/expanse.py +4 -3
  17. parsl/configs/frontera.py +3 -4
  18. parsl/configs/htex_local.py +3 -4
  19. parsl/configs/illinoiscluster.py +3 -1
  20. parsl/configs/improv.py +34 -0
  21. parsl/configs/kubernetes.py +4 -3
  22. parsl/configs/local_threads.py +5 -1
  23. parsl/configs/midway.py +5 -3
  24. parsl/configs/osg.py +4 -2
  25. parsl/configs/polaris.py +4 -2
  26. parsl/configs/stampede2.py +6 -5
  27. parsl/configs/summit.py +3 -3
  28. parsl/configs/toss3_llnl.py +4 -3
  29. parsl/configs/vineex_local.py +6 -4
  30. parsl/configs/wqex_local.py +5 -3
  31. parsl/curvezmq.py +4 -0
  32. parsl/data_provider/data_manager.py +4 -3
  33. parsl/data_provider/file_noop.py +1 -2
  34. parsl/data_provider/files.py +3 -3
  35. parsl/data_provider/ftp.py +1 -3
  36. parsl/data_provider/globus.py +7 -6
  37. parsl/data_provider/http.py +2 -2
  38. parsl/data_provider/rsync.py +1 -1
  39. parsl/data_provider/staging.py +2 -2
  40. parsl/data_provider/zip.py +135 -0
  41. parsl/dataflow/dependency_resolvers.py +115 -0
  42. parsl/dataflow/dflow.py +259 -223
  43. parsl/dataflow/errors.py +3 -5
  44. parsl/dataflow/futures.py +27 -14
  45. parsl/dataflow/memoization.py +5 -5
  46. parsl/dataflow/rundirs.py +5 -6
  47. parsl/dataflow/taskrecord.py +4 -5
  48. parsl/executors/__init__.py +4 -2
  49. parsl/executors/base.py +45 -15
  50. parsl/executors/errors.py +13 -0
  51. parsl/executors/execute_task.py +37 -0
  52. parsl/executors/flux/execute_parsl_task.py +3 -3
  53. parsl/executors/flux/executor.py +18 -19
  54. parsl/executors/flux/flux_instance_manager.py +26 -27
  55. parsl/executors/high_throughput/errors.py +43 -3
  56. parsl/executors/high_throughput/executor.py +307 -285
  57. parsl/executors/high_throughput/interchange.py +137 -168
  58. parsl/executors/high_throughput/manager_record.py +4 -0
  59. parsl/executors/high_throughput/manager_selector.py +55 -0
  60. parsl/executors/high_throughput/monitoring_info.py +2 -1
  61. parsl/executors/high_throughput/mpi_executor.py +113 -0
  62. parsl/executors/high_throughput/mpi_prefix_composer.py +10 -11
  63. parsl/executors/high_throughput/mpi_resource_management.py +6 -17
  64. parsl/executors/high_throughput/probe.py +9 -7
  65. parsl/executors/high_throughput/process_worker_pool.py +77 -75
  66. parsl/executors/high_throughput/zmq_pipes.py +81 -23
  67. parsl/executors/radical/executor.py +130 -79
  68. parsl/executors/radical/rpex_resources.py +17 -15
  69. parsl/executors/radical/rpex_worker.py +4 -3
  70. parsl/executors/status_handling.py +157 -51
  71. parsl/executors/taskvine/__init__.py +1 -1
  72. parsl/executors/taskvine/errors.py +1 -1
  73. parsl/executors/taskvine/exec_parsl_function.py +2 -2
  74. parsl/executors/taskvine/executor.py +38 -55
  75. parsl/executors/taskvine/factory.py +1 -1
  76. parsl/executors/taskvine/factory_config.py +1 -1
  77. parsl/executors/taskvine/manager.py +17 -13
  78. parsl/executors/taskvine/manager_config.py +7 -2
  79. parsl/executors/threads.py +6 -6
  80. parsl/executors/workqueue/errors.py +1 -1
  81. parsl/executors/workqueue/exec_parsl_function.py +6 -5
  82. parsl/executors/workqueue/executor.py +64 -63
  83. parsl/executors/workqueue/parsl_coprocess.py +1 -1
  84. parsl/jobs/error_handlers.py +2 -2
  85. parsl/jobs/job_status_poller.py +28 -112
  86. parsl/jobs/states.py +7 -2
  87. parsl/jobs/strategy.py +43 -31
  88. parsl/launchers/__init__.py +12 -3
  89. parsl/launchers/errors.py +1 -1
  90. parsl/launchers/launchers.py +0 -6
  91. parsl/log_utils.py +1 -2
  92. parsl/monitoring/db_manager.py +55 -93
  93. parsl/monitoring/errors.py +6 -0
  94. parsl/monitoring/monitoring.py +85 -311
  95. parsl/monitoring/queries/pandas.py +1 -2
  96. parsl/monitoring/radios/base.py +13 -0
  97. parsl/monitoring/radios/filesystem.py +52 -0
  98. parsl/monitoring/radios/htex.py +57 -0
  99. parsl/monitoring/radios/multiprocessing.py +17 -0
  100. parsl/monitoring/radios/udp.py +56 -0
  101. parsl/monitoring/radios/zmq.py +17 -0
  102. parsl/monitoring/remote.py +33 -37
  103. parsl/monitoring/router.py +212 -0
  104. parsl/monitoring/types.py +5 -6
  105. parsl/monitoring/visualization/app.py +4 -2
  106. parsl/monitoring/visualization/models.py +0 -1
  107. parsl/monitoring/visualization/plots/default/workflow_plots.py +8 -4
  108. parsl/monitoring/visualization/plots/default/workflow_resource_plots.py +1 -0
  109. parsl/monitoring/visualization/utils.py +0 -1
  110. parsl/monitoring/visualization/views.py +16 -9
  111. parsl/multiprocessing.py +0 -1
  112. parsl/process_loggers.py +1 -2
  113. parsl/providers/__init__.py +8 -17
  114. parsl/providers/aws/aws.py +2 -3
  115. parsl/providers/azure/azure.py +4 -5
  116. parsl/providers/base.py +2 -18
  117. parsl/providers/cluster_provider.py +3 -9
  118. parsl/providers/condor/condor.py +7 -17
  119. parsl/providers/errors.py +2 -2
  120. parsl/providers/googlecloud/googlecloud.py +2 -1
  121. parsl/providers/grid_engine/grid_engine.py +5 -14
  122. parsl/providers/kubernetes/kube.py +80 -40
  123. parsl/providers/local/local.py +13 -26
  124. parsl/providers/lsf/lsf.py +5 -23
  125. parsl/providers/pbspro/pbspro.py +5 -17
  126. parsl/providers/slurm/slurm.py +81 -39
  127. parsl/providers/torque/torque.py +3 -14
  128. parsl/serialize/__init__.py +8 -3
  129. parsl/serialize/base.py +1 -2
  130. parsl/serialize/concretes.py +5 -4
  131. parsl/serialize/facade.py +3 -3
  132. parsl/serialize/proxystore.py +3 -2
  133. parsl/tests/__init__.py +1 -1
  134. parsl/tests/configs/azure_single_node.py +4 -5
  135. parsl/tests/configs/bridges.py +3 -2
  136. parsl/tests/configs/cc_in2p3.py +1 -3
  137. parsl/tests/configs/comet.py +2 -1
  138. parsl/tests/configs/ec2_single_node.py +1 -2
  139. parsl/tests/configs/ec2_spot.py +1 -2
  140. parsl/tests/configs/flux_local.py +11 -0
  141. parsl/tests/configs/frontera.py +2 -3
  142. parsl/tests/configs/htex_local.py +3 -5
  143. parsl/tests/configs/htex_local_alternate.py +11 -15
  144. parsl/tests/configs/htex_local_intask_staging.py +5 -9
  145. parsl/tests/configs/htex_local_rsync_staging.py +4 -8
  146. parsl/tests/configs/local_radical.py +1 -3
  147. parsl/tests/configs/local_radical_mpi.py +2 -2
  148. parsl/tests/configs/local_threads_checkpoint_periodic.py +8 -10
  149. parsl/tests/configs/local_threads_monitoring.py +0 -1
  150. parsl/tests/configs/midway.py +2 -2
  151. parsl/tests/configs/nscc_singapore.py +3 -3
  152. parsl/tests/configs/osg_htex.py +1 -1
  153. parsl/tests/configs/petrelkube.py +3 -2
  154. parsl/tests/configs/slurm_local.py +24 -0
  155. parsl/tests/configs/summit.py +1 -0
  156. parsl/tests/configs/taskvine_ex.py +4 -7
  157. parsl/tests/configs/user_opts.py +0 -7
  158. parsl/tests/configs/workqueue_ex.py +4 -6
  159. parsl/tests/conftest.py +27 -13
  160. parsl/tests/integration/test_stress/test_python_simple.py +3 -4
  161. parsl/tests/integration/test_stress/test_python_threads.py +3 -5
  162. parsl/tests/manual_tests/htex_local.py +4 -6
  163. parsl/tests/manual_tests/test_basic.py +1 -0
  164. parsl/tests/manual_tests/test_log_filter.py +3 -1
  165. parsl/tests/manual_tests/test_memory_limits.py +6 -8
  166. parsl/tests/manual_tests/test_regression_220.py +2 -1
  167. parsl/tests/manual_tests/test_udp_simple.py +4 -4
  168. parsl/tests/manual_tests/test_worker_count.py +3 -2
  169. parsl/tests/scaling_tests/htex_local.py +2 -4
  170. parsl/tests/scaling_tests/test_scale.py +0 -9
  171. parsl/tests/scaling_tests/vineex_condor.py +1 -2
  172. parsl/tests/scaling_tests/vineex_local.py +1 -2
  173. parsl/tests/site_tests/site_config_selector.py +1 -6
  174. parsl/tests/site_tests/test_provider.py +4 -2
  175. parsl/tests/site_tests/test_site.py +2 -0
  176. parsl/tests/sites/test_affinity.py +7 -7
  177. parsl/tests/sites/test_dynamic_executor.py +3 -4
  178. parsl/tests/sites/test_ec2.py +3 -2
  179. parsl/tests/sites/test_worker_info.py +4 -5
  180. parsl/tests/test_aalst_patterns.py +0 -1
  181. parsl/tests/test_bash_apps/test_apptimeout.py +2 -2
  182. parsl/tests/test_bash_apps/test_basic.py +10 -4
  183. parsl/tests/test_bash_apps/test_error_codes.py +5 -7
  184. parsl/tests/test_bash_apps/test_inputs_default.py +25 -0
  185. parsl/tests/test_bash_apps/test_kwarg_storage.py +1 -1
  186. parsl/tests/test_bash_apps/test_memoize.py +2 -8
  187. parsl/tests/test_bash_apps/test_memoize_ignore_args.py +9 -14
  188. parsl/tests/test_bash_apps/test_memoize_ignore_args_regr.py +9 -14
  189. parsl/tests/test_bash_apps/test_multiline.py +1 -1
  190. parsl/tests/test_bash_apps/test_pipeline.py +1 -1
  191. parsl/tests/test_bash_apps/test_std_uri.py +123 -0
  192. parsl/tests/test_bash_apps/test_stdout.py +33 -8
  193. parsl/tests/test_callables.py +2 -2
  194. parsl/tests/test_checkpointing/test_periodic.py +21 -39
  195. parsl/tests/test_checkpointing/test_python_checkpoint_1.py +1 -0
  196. parsl/tests/test_checkpointing/test_python_checkpoint_2.py +2 -2
  197. parsl/tests/test_checkpointing/test_python_checkpoint_3.py +0 -1
  198. parsl/tests/test_checkpointing/test_regression_239.py +1 -1
  199. parsl/tests/test_checkpointing/test_task_exit.py +2 -3
  200. parsl/tests/test_docs/test_from_slides.py +5 -2
  201. parsl/tests/test_docs/test_kwargs.py +4 -1
  202. parsl/tests/test_docs/test_tutorial_1.py +1 -2
  203. parsl/tests/test_docs/test_workflow1.py +2 -2
  204. parsl/tests/test_docs/test_workflow2.py +0 -1
  205. parsl/tests/test_error_handling/test_rand_fail.py +2 -2
  206. parsl/tests/test_error_handling/test_resource_spec.py +10 -12
  207. parsl/tests/test_error_handling/test_retries.py +6 -16
  208. parsl/tests/test_error_handling/test_retry_handler.py +1 -0
  209. parsl/tests/test_error_handling/test_retry_handler_failure.py +2 -1
  210. parsl/tests/test_error_handling/test_serialization_fail.py +1 -1
  211. parsl/tests/test_error_handling/test_wrap_with_logs.py +1 -0
  212. parsl/tests/test_execute_task.py +29 -0
  213. parsl/tests/test_flux.py +1 -1
  214. parsl/tests/test_htex/test_basic.py +2 -3
  215. parsl/tests/test_htex/test_block_manager_selector_unit.py +20 -0
  216. parsl/tests/test_htex/test_command_client_timeout.py +66 -0
  217. parsl/tests/test_htex/test_connected_blocks.py +3 -2
  218. parsl/tests/test_htex/test_cpu_affinity_explicit.py +6 -10
  219. parsl/tests/test_htex/test_disconnected_blocks.py +6 -5
  220. parsl/tests/test_htex/test_disconnected_blocks_failing_provider.py +71 -0
  221. parsl/tests/test_htex/test_drain.py +11 -10
  222. parsl/tests/test_htex/test_htex.py +51 -25
  223. parsl/tests/test_htex/test_manager_failure.py +0 -1
  224. parsl/tests/test_htex/test_manager_selector_by_block.py +51 -0
  225. parsl/tests/test_htex/test_managers_command.py +36 -0
  226. parsl/tests/test_htex/test_missing_worker.py +2 -12
  227. parsl/tests/test_htex/test_multiple_disconnected_blocks.py +9 -9
  228. parsl/tests/test_htex/test_resource_spec_validation.py +45 -0
  229. parsl/tests/test_htex/test_zmq_binding.py +29 -8
  230. parsl/tests/test_monitoring/test_app_names.py +5 -5
  231. parsl/tests/test_monitoring/test_basic.py +73 -25
  232. parsl/tests/test_monitoring/test_db_locks.py +6 -4
  233. parsl/tests/test_monitoring/test_fuzz_zmq.py +19 -8
  234. parsl/tests/test_monitoring/test_htex_init_blocks_vs_monitoring.py +80 -0
  235. parsl/tests/test_monitoring/test_incomplete_futures.py +5 -4
  236. parsl/tests/test_monitoring/test_memoization_representation.py +4 -2
  237. parsl/tests/test_monitoring/test_stdouterr.py +134 -0
  238. parsl/tests/test_monitoring/test_viz_colouring.py +1 -0
  239. parsl/tests/test_mpi_apps/test_bad_mpi_config.py +33 -26
  240. parsl/tests/test_mpi_apps/test_mpi_mode_enabled.py +28 -11
  241. parsl/tests/test_mpi_apps/test_mpi_prefix.py +4 -4
  242. parsl/tests/test_mpi_apps/test_mpi_scheduler.py +7 -2
  243. parsl/tests/test_mpi_apps/test_mpiex.py +64 -0
  244. parsl/tests/test_mpi_apps/test_resource_spec.py +42 -49
  245. parsl/tests/test_providers/test_kubernetes_provider.py +102 -0
  246. parsl/tests/test_providers/test_local_provider.py +3 -132
  247. parsl/tests/test_providers/test_pbspro_template.py +2 -3
  248. parsl/tests/test_providers/test_slurm_template.py +2 -3
  249. parsl/tests/test_providers/test_submiterror_deprecation.py +2 -1
  250. parsl/tests/test_python_apps/test_context_manager.py +128 -0
  251. parsl/tests/test_python_apps/test_dep_standard_futures.py +2 -1
  252. parsl/tests/test_python_apps/test_dependencies_deep.py +59 -0
  253. parsl/tests/test_python_apps/test_fail.py +0 -25
  254. parsl/tests/test_python_apps/test_futures.py +2 -1
  255. parsl/tests/test_python_apps/test_inputs_default.py +22 -0
  256. parsl/tests/test_python_apps/test_join.py +0 -1
  257. parsl/tests/test_python_apps/test_lifted.py +11 -7
  258. parsl/tests/test_python_apps/test_memoize_bad_id_for_memo.py +1 -0
  259. parsl/tests/test_python_apps/test_outputs.py +1 -1
  260. parsl/tests/test_python_apps/test_pluggable_future_resolution.py +161 -0
  261. parsl/tests/test_radical/test_mpi_funcs.py +1 -2
  262. parsl/tests/test_regression/test_1480.py +2 -1
  263. parsl/tests/test_regression/test_1653.py +2 -1
  264. parsl/tests/test_regression/test_226.py +1 -0
  265. parsl/tests/test_regression/test_2652.py +1 -0
  266. parsl/tests/test_regression/test_69a.py +0 -1
  267. parsl/tests/test_regression/test_854.py +4 -2
  268. parsl/tests/test_regression/test_97_parallelism_0.py +1 -2
  269. parsl/tests/test_regression/test_98.py +0 -1
  270. parsl/tests/test_scaling/test_block_error_handler.py +9 -4
  271. parsl/tests/test_scaling/test_regression_1621.py +11 -15
  272. parsl/tests/test_scaling/test_regression_3568_scaledown_vs_MISSING.py +84 -0
  273. parsl/tests/test_scaling/test_regression_3696_oscillation.py +103 -0
  274. parsl/tests/test_scaling/test_scale_down.py +2 -5
  275. parsl/tests/test_scaling/test_scale_down_htex_auto_scale.py +5 -8
  276. parsl/tests/test_scaling/test_scale_down_htex_unregistered.py +71 -0
  277. parsl/tests/test_scaling/test_shutdown_scalein.py +73 -0
  278. parsl/tests/test_scaling/test_worker_interchange_bad_messages_3262.py +90 -0
  279. parsl/tests/test_serialization/test_2555_caching_deserializer.py +1 -1
  280. parsl/tests/test_serialization/test_3495_deserialize_managerlost.py +47 -0
  281. parsl/tests/test_serialization/test_basic.py +2 -1
  282. parsl/tests/test_serialization/test_htex_code_cache.py +3 -4
  283. parsl/tests/test_serialization/test_pack_resource_spec.py +2 -1
  284. parsl/tests/test_serialization/test_proxystore_configured.py +10 -6
  285. parsl/tests/test_serialization/test_proxystore_impl.py +5 -3
  286. parsl/tests/test_shutdown/test_kill_monitoring.py +64 -0
  287. parsl/tests/test_staging/staging_provider.py +2 -2
  288. parsl/tests/test_staging/test_1316.py +3 -4
  289. parsl/tests/test_staging/test_docs_1.py +2 -1
  290. parsl/tests/test_staging/test_docs_2.py +2 -1
  291. parsl/tests/test_staging/test_elaborate_noop_file.py +2 -3
  292. parsl/tests/{test_data → test_staging}/test_file.py +6 -6
  293. parsl/tests/{test_data → test_staging}/test_output_chain_filenames.py +3 -0
  294. parsl/tests/test_staging/test_staging_ftp.py +1 -0
  295. parsl/tests/test_staging/test_staging_https.py +5 -2
  296. parsl/tests/test_staging/test_staging_stdout.py +64 -0
  297. parsl/tests/test_staging/test_zip_in.py +39 -0
  298. parsl/tests/test_staging/test_zip_out.py +110 -0
  299. parsl/tests/test_staging/test_zip_to_zip.py +41 -0
  300. parsl/tests/test_summary.py +2 -2
  301. parsl/tests/test_thread_parallelism.py +0 -1
  302. parsl/tests/test_threads/test_configs.py +1 -2
  303. parsl/tests/test_threads/test_lazy_errors.py +2 -2
  304. parsl/tests/test_utils/test_execute_wait.py +35 -0
  305. parsl/tests/test_utils/test_sanitize_dns.py +76 -0
  306. parsl/tests/unit/test_address.py +20 -0
  307. parsl/tests/unit/test_file.py +99 -0
  308. parsl/tests/unit/test_usage_tracking.py +66 -0
  309. parsl/usage_tracking/api.py +65 -0
  310. parsl/usage_tracking/levels.py +6 -0
  311. parsl/usage_tracking/usage.py +104 -62
  312. parsl/utils.py +137 -4
  313. parsl/version.py +1 -1
  314. {parsl-2024.3.18.data → parsl-2025.1.13.data}/scripts/exec_parsl_function.py +6 -5
  315. parsl-2025.1.13.data/scripts/interchange.py +649 -0
  316. {parsl-2024.3.18.data → parsl-2025.1.13.data}/scripts/process_worker_pool.py +77 -75
  317. parsl-2025.1.13.dist-info/METADATA +96 -0
  318. parsl-2025.1.13.dist-info/RECORD +462 -0
  319. {parsl-2024.3.18.dist-info → parsl-2025.1.13.dist-info}/WHEEL +1 -1
  320. parsl/channels/__init__.py +0 -7
  321. parsl/channels/base.py +0 -141
  322. parsl/channels/errors.py +0 -113
  323. parsl/channels/local/local.py +0 -164
  324. parsl/channels/oauth_ssh/oauth_ssh.py +0 -110
  325. parsl/channels/ssh/ssh.py +0 -276
  326. parsl/channels/ssh_il/__init__.py +0 -0
  327. parsl/channels/ssh_il/ssh_il.py +0 -74
  328. parsl/configs/ad_hoc.py +0 -35
  329. parsl/executors/radical/rpex_master.py +0 -42
  330. parsl/monitoring/radios.py +0 -175
  331. parsl/providers/ad_hoc/__init__.py +0 -0
  332. parsl/providers/ad_hoc/ad_hoc.py +0 -248
  333. parsl/providers/cobalt/__init__.py +0 -0
  334. parsl/providers/cobalt/cobalt.py +0 -236
  335. parsl/providers/cobalt/template.py +0 -17
  336. parsl/tests/configs/ad_hoc_cluster_htex.py +0 -35
  337. parsl/tests/configs/cooley_htex.py +0 -37
  338. parsl/tests/configs/htex_ad_hoc_cluster.py +0 -28
  339. parsl/tests/configs/local_adhoc.py +0 -18
  340. parsl/tests/configs/swan_htex.py +0 -43
  341. parsl/tests/configs/theta.py +0 -37
  342. parsl/tests/integration/test_channels/__init__.py +0 -0
  343. parsl/tests/integration/test_channels/test_channels.py +0 -17
  344. parsl/tests/integration/test_channels/test_local_channel.py +0 -42
  345. parsl/tests/integration/test_channels/test_scp_1.py +0 -45
  346. parsl/tests/integration/test_channels/test_ssh_1.py +0 -40
  347. parsl/tests/integration/test_channels/test_ssh_errors.py +0 -46
  348. parsl/tests/integration/test_channels/test_ssh_file_transport.py +0 -41
  349. parsl/tests/integration/test_channels/test_ssh_interactive.py +0 -24
  350. parsl/tests/manual_tests/test_ad_hoc_htex.py +0 -48
  351. parsl/tests/manual_tests/test_fan_in_out_htex_remote.py +0 -88
  352. parsl/tests/manual_tests/test_oauth_ssh.py +0 -13
  353. parsl/tests/sites/test_local_adhoc.py +0 -61
  354. parsl/tests/test_channels/__init__.py +0 -0
  355. parsl/tests/test_channels/test_large_output.py +0 -22
  356. parsl/tests/test_data/__init__.py +0 -0
  357. parsl/tests/test_mpi_apps/test_mpi_mode_disabled.py +0 -51
  358. parsl/tests/test_providers/test_cobalt_deprecation_warning.py +0 -16
  359. parsl-2024.3.18.dist-info/METADATA +0 -98
  360. parsl-2024.3.18.dist-info/RECORD +0 -449
  361. parsl/{channels/local → monitoring/radios}/__init__.py +0 -0
  362. parsl/{channels/oauth_ssh → tests/test_shutdown}/__init__.py +0 -0
  363. parsl/tests/{test_data → test_staging}/test_file_apps.py +0 -0
  364. parsl/tests/{test_data → test_staging}/test_file_staging.py +0 -0
  365. parsl/{channels/ssh → tests/unit}/__init__.py +0 -0
  366. {parsl-2024.3.18.data → parsl-2025.1.13.data}/scripts/parsl_coprocess.py +1 -1
  367. {parsl-2024.3.18.dist-info → parsl-2025.1.13.dist-info}/LICENSE +0 -0
  368. {parsl-2024.3.18.dist-info → parsl-2025.1.13.dist-info}/entry_points.txt +0 -0
  369. {parsl-2024.3.18.dist-info → parsl-2025.1.13.dist-info}/top_level.txt +0 -0
@@ -61,7 +61,6 @@ class SingleNodeLauncher(Launcher):
61
61
  """
62
62
  Args:
63
63
  - command (string): The command string to be launched
64
- - task_block (string) : bash evaluated string.
65
64
  - fail_on_any: If True, return a nonzero exit code if any worker failed, otherwise zero;
66
65
  if False, return a nonzero exit code if all workers failed, otherwise zero.
67
66
 
@@ -131,7 +130,6 @@ class GnuParallelLauncher(Launcher):
131
130
  """
132
131
  Args:
133
132
  - command (string): The command string to be launched
134
- - task_block (string) : bash evaluated string.
135
133
 
136
134
  """
137
135
  task_blocks = tasks_per_node * nodes_per_block
@@ -208,7 +206,6 @@ class MpiExecLauncher(Launcher):
208
206
  """
209
207
  Args:
210
208
  - command (string): The command string to be launched
211
- - task_block (string) : bash evaluated string.
212
209
 
213
210
  """
214
211
  task_blocks = tasks_per_node * nodes_per_block
@@ -263,7 +260,6 @@ class MpiRunLauncher(Launcher):
263
260
  """
264
261
  Args:
265
262
  - command (string): The command string to be launched
266
- - task_block (string) : bash evaluated string.
267
263
 
268
264
  """
269
265
  task_blocks = tasks_per_node * nodes_per_block
@@ -311,7 +307,6 @@ class SrunLauncher(Launcher):
311
307
  """
312
308
  Args:
313
309
  - command (string): The command string to be launched
314
- - task_block (string) : bash evaluated string.
315
310
 
316
311
  """
317
312
  task_blocks = tasks_per_node * nodes_per_block
@@ -363,7 +358,6 @@ class SrunMPILauncher(Launcher):
363
358
  """
364
359
  Args:
365
360
  - command (string): The command string to be launched
366
- - task_block (string) : bash evaluated string.
367
361
 
368
362
  """
369
363
  task_blocks = tasks_per_node * nodes_per_block
parsl/log_utils.py CHANGED
@@ -12,10 +12,9 @@ provided for logging:
12
12
  """
13
13
  import io
14
14
  import logging
15
- import typeguard
16
-
17
15
  from typing import Optional
18
16
 
17
+ import typeguard
19
18
 
20
19
  DEFAULT_FORMAT = (
21
20
  "%(created)f %(asctime)s %(processName)s-%(process)d "
@@ -1,15 +1,17 @@
1
+ import datetime
1
2
  import logging
2
- import threading
3
- import queue
3
+ import multiprocessing.queues as mpq
4
4
  import os
5
+ import queue
6
+ import threading
5
7
  import time
6
- import datetime
7
-
8
8
  from typing import Any, Dict, List, Optional, Set, Tuple, TypeVar, cast
9
9
 
10
- from parsl.log_utils import set_file_logger
10
+ import typeguard
11
+
11
12
  from parsl.dataflow.states import States
12
13
  from parsl.errors import OptionalModuleMissing
14
+ from parsl.log_utils import set_file_logger
13
15
  from parsl.monitoring.message_type import MessageType
14
16
  from parsl.monitoring.types import MonitoringMessage, TaggedMonitoringMessage
15
17
  from parsl.process_loggers import wrap_with_logs
@@ -21,11 +23,18 @@ X = TypeVar('X')
21
23
 
22
24
  try:
23
25
  import sqlalchemy as sa
24
- from sqlalchemy import Column, Text, Float, Boolean, BigInteger, Integer, DateTime, PrimaryKeyConstraint, Table
25
- from sqlalchemy.orm import Mapper
26
- from sqlalchemy.orm import mapperlib
27
- from sqlalchemy.orm import sessionmaker
28
- from sqlalchemy.orm import declarative_base
26
+ from sqlalchemy import (
27
+ BigInteger,
28
+ Boolean,
29
+ Column,
30
+ DateTime,
31
+ Float,
32
+ Integer,
33
+ PrimaryKeyConstraint,
34
+ Table,
35
+ Text,
36
+ )
37
+ from sqlalchemy.orm import Mapper, declarative_base, mapperlib, sessionmaker
29
38
  except ImportError:
30
39
  _sqlalchemy_enabled = False
31
40
  else:
@@ -69,7 +78,7 @@ class Database:
69
78
 
70
79
  def _get_mapper(self, table_obj: Table) -> Mapper:
71
80
  all_mappers: Set[Mapper] = set()
72
- for mapper_registry in mapperlib._all_registries(): # type: ignore[attr-defined]
81
+ for mapper_registry in mapperlib._all_registries():
73
82
  all_mappers.update(mapper_registry.mappers)
74
83
  mapper_gen = (
75
84
  mapper for mapper in all_mappers
@@ -270,20 +279,20 @@ class Database:
270
279
  class DatabaseManager:
271
280
  def __init__(self,
272
281
  db_url: str = 'sqlite:///runinfo/monitoring.db',
273
- logdir: str = '.',
282
+ run_dir: str = '.',
274
283
  logging_level: int = logging.INFO,
275
284
  batching_interval: float = 1,
276
285
  batching_threshold: float = 99999,
277
286
  ):
278
287
 
279
288
  self.workflow_end = False
280
- self.workflow_start_message = None # type: Optional[MonitoringMessage]
281
- self.logdir = logdir
282
- os.makedirs(self.logdir, exist_ok=True)
289
+ self.workflow_start_message: Optional[MonitoringMessage] = None
290
+ self.run_dir = run_dir
291
+ os.makedirs(self.run_dir, exist_ok=True)
283
292
 
284
293
  logger.propagate = False
285
294
 
286
- set_file_logger("{}/database_manager.log".format(self.logdir), level=logging_level,
295
+ set_file_logger(f"{self.run_dir}/database_manager.log", level=logging_level,
287
296
  format_string="%(asctime)s.%(msecs)03d %(name)s:%(lineno)d [%(levelname)s] [%(threadName)s %(thread)d] %(message)s",
288
297
  name="database_manager")
289
298
 
@@ -293,45 +302,19 @@ class DatabaseManager:
293
302
  self.batching_interval = batching_interval
294
303
  self.batching_threshold = batching_threshold
295
304
 
296
- self.pending_priority_queue = queue.Queue() # type: queue.Queue[TaggedMonitoringMessage]
297
- self.pending_node_queue = queue.Queue() # type: queue.Queue[MonitoringMessage]
298
- self.pending_block_queue = queue.Queue() # type: queue.Queue[MonitoringMessage]
299
- self.pending_resource_queue = queue.Queue() # type: queue.Queue[MonitoringMessage]
305
+ self.pending_priority_queue: queue.Queue[TaggedMonitoringMessage] = queue.Queue()
306
+ self.pending_node_queue: queue.Queue[MonitoringMessage] = queue.Queue()
307
+ self.pending_block_queue: queue.Queue[MonitoringMessage] = queue.Queue()
308
+ self.pending_resource_queue: queue.Queue[MonitoringMessage] = queue.Queue()
300
309
 
301
310
  def start(self,
302
- priority_queue: "queue.Queue[TaggedMonitoringMessage]",
303
- node_queue: "queue.Queue[MonitoringMessage]",
304
- block_queue: "queue.Queue[MonitoringMessage]",
305
- resource_queue: "queue.Queue[MonitoringMessage]") -> None:
311
+ resource_queue: mpq.Queue) -> None:
306
312
 
307
313
  self._kill_event = threading.Event()
308
- self._priority_queue_pull_thread = threading.Thread(target=self._migrate_logs_to_internal,
309
- args=(
310
- priority_queue, 'priority', self._kill_event,),
311
- name="Monitoring-migrate-priority",
312
- daemon=True,
313
- )
314
- self._priority_queue_pull_thread.start()
315
-
316
- self._node_queue_pull_thread = threading.Thread(target=self._migrate_logs_to_internal,
317
- args=(
318
- node_queue, 'node', self._kill_event,),
319
- name="Monitoring-migrate-node",
320
- daemon=True,
321
- )
322
- self._node_queue_pull_thread.start()
323
-
324
- self._block_queue_pull_thread = threading.Thread(target=self._migrate_logs_to_internal,
325
- args=(
326
- block_queue, 'block', self._kill_event,),
327
- name="Monitoring-migrate-block",
328
- daemon=True,
329
- )
330
- self._block_queue_pull_thread.start()
331
314
 
332
315
  self._resource_queue_pull_thread = threading.Thread(target=self._migrate_logs_to_internal,
333
316
  args=(
334
- resource_queue, 'resource', self._kill_event,),
317
+ resource_queue, self._kill_event,),
335
318
  name="Monitoring-migrate-resource",
336
319
  daemon=True,
337
320
  )
@@ -345,38 +328,36 @@ class DatabaseManager:
345
328
  If that happens, the message will be added to deferred_resource_messages and processed later.
346
329
 
347
330
  """
348
- inserted_tasks = set() # type: Set[object]
331
+ inserted_tasks: Set[object] = set()
349
332
 
350
333
  """
351
334
  like inserted_tasks but for task,try tuples
352
335
  """
353
- inserted_tries = set() # type: Set[Any]
336
+ inserted_tries: Set[Any] = set()
354
337
 
355
338
  # for any task ID, we can defer exactly one message, which is the
356
339
  # assumed-to-be-unique first message (with first message flag set).
357
340
  # The code prior to this patch will discard previous message in
358
341
  # the case of multiple messages to defer.
359
- deferred_resource_messages = {} # type: MonitoringMessage
342
+ deferred_resource_messages: MonitoringMessage = {}
360
343
 
361
344
  exception_happened = False
362
345
 
363
346
  while (not self._kill_event.is_set() or
364
347
  self.pending_priority_queue.qsize() != 0 or self.pending_resource_queue.qsize() != 0 or
365
348
  self.pending_node_queue.qsize() != 0 or self.pending_block_queue.qsize() != 0 or
366
- priority_queue.qsize() != 0 or resource_queue.qsize() != 0 or
367
- node_queue.qsize() != 0 or block_queue.qsize() != 0):
349
+ resource_queue.qsize() != 0):
368
350
 
369
351
  """
370
352
  WORKFLOW_INFO and TASK_INFO messages (i.e. priority messages)
371
353
 
372
354
  """
373
355
  try:
374
- logger.debug("""Checking STOP conditions: {}, {}, {}, {}, {}, {}, {}, {}, {}""".format(
356
+ logger.debug("""Checking STOP conditions: {}, {}, {}, {}, {}, {}""".format(
375
357
  self._kill_event.is_set(),
376
358
  self.pending_priority_queue.qsize() != 0, self.pending_resource_queue.qsize() != 0,
377
359
  self.pending_node_queue.qsize() != 0, self.pending_block_queue.qsize() != 0,
378
- priority_queue.qsize() != 0, resource_queue.qsize() != 0,
379
- node_queue.qsize() != 0, block_queue.qsize() != 0))
360
+ resource_queue.qsize() != 0))
380
361
 
381
362
  # This is the list of resource messages which can be reprocessed as if they
382
363
  # had just arrived because the corresponding first task message has been
@@ -499,7 +480,7 @@ class DatabaseManager:
499
480
  "Got {} messages from block queue".format(len(block_info_messages)))
500
481
  # block_info_messages is possibly a nested list of dict (at different polling times)
501
482
  # Each dict refers to the info of a job/block at one polling time
502
- block_messages_to_insert = [] # type: List[Any]
483
+ block_messages_to_insert: List[Any] = []
503
484
  for block_msg in block_info_messages:
504
485
  block_messages_to_insert.extend(block_msg)
505
486
  self._insert(table=BLOCK, messages=block_messages_to_insert)
@@ -568,43 +549,26 @@ class DatabaseManager:
568
549
  raise RuntimeError("An exception happened sometime during database processing and should have been logged in database_manager.log")
569
550
 
570
551
  @wrap_with_logs(target="database_manager")
571
- def _migrate_logs_to_internal(self, logs_queue: queue.Queue, queue_tag: str, kill_event: threading.Event) -> None:
572
- logger.info("Starting processing for queue {}".format(queue_tag))
552
+ def _migrate_logs_to_internal(self, logs_queue: queue.Queue, kill_event: threading.Event) -> None:
553
+ logger.info("Starting _migrate_logs_to_internal")
573
554
 
574
555
  while not kill_event.is_set() or logs_queue.qsize() != 0:
575
- logger.debug("""Checking STOP conditions for {} threads: {}, {}"""
576
- .format(queue_tag, kill_event.is_set(), logs_queue.qsize() != 0))
556
+ logger.debug("Checking STOP conditions: kill event: %s, queue has entries: %s",
557
+ kill_event.is_set(), logs_queue.qsize() != 0)
577
558
  try:
578
- x, addr = logs_queue.get(timeout=0.1)
559
+ x = logs_queue.get(timeout=0.1)
579
560
  except queue.Empty:
580
561
  continue
581
562
  else:
582
- if queue_tag == 'priority' and x == 'STOP':
563
+ if x == 'STOP':
583
564
  self.close()
584
- elif queue_tag == 'priority': # implicitly not 'STOP'
585
- assert isinstance(x, tuple)
586
- assert len(x) == 2
587
- assert x[0] in [MessageType.WORKFLOW_INFO, MessageType.TASK_INFO], \
588
- "_migrate_logs_to_internal can only migrate WORKFLOW_,TASK_INFO message from priority queue, got x[0] == {}".format(x[0])
589
- self._dispatch_to_internal(x)
590
- elif queue_tag == 'resource':
591
- assert isinstance(x, tuple), "_migrate_logs_to_internal was expecting a tuple, got {}".format(x)
592
- assert x[0] == MessageType.RESOURCE_INFO, (
593
- "_migrate_logs_to_internal can only migrate RESOURCE_INFO message from resource queue, "
594
- "got tag {}, message {}".format(x[0], x)
595
- )
596
- self._dispatch_to_internal(x)
597
- elif queue_tag == 'node':
598
- assert len(x) == 2, "expected message tuple to have exactly two elements"
599
- assert x[0] == MessageType.NODE_INFO, "_migrate_logs_to_internal can only migrate NODE_INFO messages from node queue"
600
-
601
- self._dispatch_to_internal(x)
602
- elif queue_tag == "block":
603
- self._dispatch_to_internal(x)
604
565
  else:
605
- logger.error(f"Discarding because unknown queue tag '{queue_tag}', message: {x}")
566
+ self._dispatch_to_internal(x)
606
567
 
607
568
  def _dispatch_to_internal(self, x: Tuple) -> None:
569
+ assert isinstance(x, tuple)
570
+ assert len(x) == 2, "expected message tuple to have exactly two elements"
571
+
608
572
  if x[0] in [MessageType.WORKFLOW_INFO, MessageType.TASK_INFO]:
609
573
  self.pending_priority_queue.put(cast(Any, x))
610
574
  elif x[0] == MessageType.RESOURCE_INFO:
@@ -680,7 +644,7 @@ class DatabaseManager:
680
644
  logger.exception("Rollback failed")
681
645
 
682
646
  def _get_messages_in_batch(self, msg_queue: "queue.Queue[X]") -> List[X]:
683
- messages = [] # type: List[X]
647
+ messages: List[X] = []
684
648
  start = time.time()
685
649
  while True:
686
650
  if time.time() - start >= self.batching_interval or len(messages) >= self.batching_threshold:
@@ -713,13 +677,11 @@ class DatabaseManager:
713
677
 
714
678
 
715
679
  @wrap_with_logs(target="database_manager")
716
- def dbm_starter(exception_q: "queue.Queue[Tuple[str, str]]",
717
- priority_msgs: "queue.Queue[TaggedMonitoringMessage]",
718
- node_msgs: "queue.Queue[MonitoringMessage]",
719
- block_msgs: "queue.Queue[MonitoringMessage]",
720
- resource_msgs: "queue.Queue[MonitoringMessage]",
680
+ @typeguard.typechecked
681
+ def dbm_starter(exception_q: mpq.Queue,
682
+ resource_msgs: mpq.Queue,
721
683
  db_url: str,
722
- logdir: str,
684
+ run_dir: str,
723
685
  logging_level: int) -> None:
724
686
  """Start the database manager process
725
687
 
@@ -730,10 +692,10 @@ def dbm_starter(exception_q: "queue.Queue[Tuple[str, str]]",
730
692
 
731
693
  try:
732
694
  dbm = DatabaseManager(db_url=db_url,
733
- logdir=logdir,
695
+ run_dir=run_dir,
734
696
  logging_level=logging_level)
735
697
  logger.info("Starting dbm in dbm starter")
736
- dbm.start(priority_msgs, node_msgs, block_msgs, resource_msgs)
698
+ dbm.start(resource_msgs)
737
699
  except KeyboardInterrupt:
738
700
  logger.exception("KeyboardInterrupt signal caught")
739
701
  dbm.close()
@@ -0,0 +1,6 @@
1
+ from parsl.errors import ParslError
2
+
3
+
4
+ class MonitoringHubStartError(ParslError):
5
+ def __str__(self) -> str:
6
+ return "Hub failed to start"