panda-server-source 1.0.2__tar.gz → 1.0.4__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 (431) hide show
  1. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/Dockerfile.base +1 -1
  2. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/PKG-INFO +2 -2
  3. panda_server_source-1.0.4/PandaPkgInfo.py +1 -0
  4. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedibrokerage/AtlasAnalJobBroker.py +62 -38
  5. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedibrokerage/AtlasBrokerUtils.py +86 -103
  6. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedibrokerage/AtlasProdJobBroker.py +24 -13
  7. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedibrokerage/AtlasProdTaskBroker.py +3 -7
  8. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedicore/Interaction.py +6 -0
  9. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedicore/JediTaskBuffer.py +3 -1
  10. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedicore/ThreadUtils.py +1 -1
  11. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jediddm/AtlasDDMClient.py +31 -0
  12. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedidog/AsyncRequestWatchDog.py +2 -1
  13. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedidog/AtlasProdWatchDog.py +6 -6
  14. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedimsgprocessor/processing_msg_processor.py +13 -9
  15. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedimsgprocessor/tape_carousel_msg_processor.py +13 -9
  16. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jediorder/ContentsFeeder.py +7 -1
  17. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jediorder/JediMaster.py +1 -1
  18. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jediorder/JobGenerator.py +6 -2
  19. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jediorder/JobSplitter.py +1 -1
  20. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jediorder/TaskBroker.py +2 -2
  21. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jediorder/TaskCommando.py +10 -3
  22. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jediorder/TaskRefiner.py +29 -1
  23. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedirefine/AtlasProdTaskRefiner.py +1 -1
  24. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedisetup/AtlasTaskSetupper.py +16 -1
  25. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/addIDDSStageInRequest.py +1 -1
  26. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/async_process_api.py +118 -58
  27. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/common.py +65 -0
  28. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/credential_management_api.py +4 -0
  29. panda_server_source-1.0.4/pandaserver/api/v1/data_carousel_api.py +353 -0
  30. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/job_api.py +5 -3
  31. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/pilot_api.py +31 -2
  32. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/statistics_api.py +84 -2
  33. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/tests/async_process_api_tests.py +157 -9
  34. panda_server_source-1.0.4/pandaserver/api/v1/tests/data_carousel_api_tests.py +324 -0
  35. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/tests/pilot_api_tests.py +13 -31
  36. panda_server_source-1.0.4/pandaserver/asyncprocess/data_carousel_handlers.py +143 -0
  37. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/asyncprocess/processor.py +98 -7
  38. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/configurator/Configurator.py +19 -8
  39. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/daemons/scripts/async_request_daemon.py +2 -1
  40. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/daemons/scripts/evpPD2P.py +1 -1
  41. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/daemons/scripts/process_workflow_files_daemon.py +1 -1
  42. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/daemons/scripts/recover_lost_files_daemon.py +1 -1
  43. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/dataservice/DataServiceUtils.py +9 -0
  44. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/dataservice/adder_atlas_plugin.py +25 -37
  45. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/dataservice/adder_gen.py +35 -4
  46. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/dataservice/adder_simple_plugin.py +7 -26
  47. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/dataservice/ddm.py +175 -95
  48. panda_server_source-1.0.4/pandaserver/srvcore/exceptions.py +20 -0
  49. panda_server_source-1.0.4/pandaserver/srvcore/hardware_matching.py +128 -0
  50. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/srvcore/oidc_utils.py +19 -7
  51. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/srvcore/panda_request.py +11 -2
  52. {panda_server_source-1.0.2/pandaserver/taskbuffer → panda_server_source-1.0.4/pandaserver/srvcore/tests}/__init__.py +0 -0
  53. panda_server_source-1.0.4/pandaserver/srvcore/tests/hardware_matching_tests.py +144 -0
  54. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/DataCarousel.py +23 -13
  55. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/JediTaskSpec.py +16 -3
  56. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/SiteSpec.py +2 -2
  57. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/TaskBuffer.py +24 -112
  58. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/WorkQueue.py +6 -6
  59. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/WorkerSpec.py +1 -1
  60. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/WrappedCursor.py +1 -1
  61. {panda_server_source-1.0.2/pandaserver/test → panda_server_source-1.0.4/pandaserver/taskbuffer}/__init__.py +0 -0
  62. panda_server_source-1.0.2/pandaserver/api/v1/data_carousel_api.py → panda_server_source-1.0.4/pandaserver/taskbuffer/data_carousel_ops.py +121 -112
  63. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/db_proxy_mods/async_request_module.py +46 -0
  64. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/db_proxy_mods/entity_module.py +10 -4
  65. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/db_proxy_mods/job_complex_module.py +155 -34
  66. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/db_proxy_mods/misc_standalone_module.py +30 -24
  67. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/db_proxy_mods/task_complex_module.py +33 -11
  68. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/db_proxy_mods/task_event_module.py +6 -5
  69. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/db_proxy_mods/task_standalone_module.py +6 -4
  70. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/db_proxy_mods/task_utils_module.py +1 -1
  71. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/db_proxy_mods/worker_module.py +50 -5
  72. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/db_proxy_mods/workflow_module.py +101 -2
  73. panda_server_source-1.0.4/pandaserver/taskbuffer/offline_run_script.py +402 -0
  74. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/task_split_rules.py +1 -1
  75. panda_server_source-1.0.4/pandaserver/workflow/__init__.py +0 -0
  76. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/workflow/data_handler_plugins/base_data_handler.py +17 -0
  77. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/workflow/data_handler_plugins/ddm_collection_data_handler.py +38 -0
  78. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/workflow/data_handler_plugins/panda_task_data_handler.py +60 -14
  79. panda_server_source-1.0.4/pandaserver/workflow/examples/nested_workflow_inline_sig_bg_comb_wfd.yaml +91 -0
  80. panda_server_source-1.0.4/pandaserver/workflow/examples/nested_workflow_sig_bg_comb_wfd.yaml +33 -0
  81. panda_server_source-1.0.4/pandaserver/workflow/examples/scatter_sig_bg_comb_wfd.yaml +38 -0
  82. panda_server_source-1.0.4/pandaserver/workflow/examples/signal_background_combine_wfd.yaml +72 -0
  83. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/workflow/workflow_base.py +5 -0
  84. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/workflow/workflow_core.py +754 -61
  85. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/workflow/workflow_native_utils.py +215 -29
  86. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/workflow/workflow_parser.py +98 -2
  87. panda_server_source-1.0.2/PandaPkgInfo.py +0 -1
  88. panda_server_source-1.0.2/pandaserver/api/v1/tests/data_carousel_api_tests.py +0 -82
  89. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/.gitignore +0 -0
  90. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/.pre-commit-config.yaml +0 -0
  91. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/Dockerfile +0 -0
  92. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/LICENSE.txt +0 -0
  93. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/README.md +0 -0
  94. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/package/hatch_build.py +0 -0
  95. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/__init__.py +0 -0
  96. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedibrokerage/GenJobBroker.py +0 -0
  97. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedibrokerage/JobBrokerBase.py +0 -0
  98. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedibrokerage/TaskBrokerBase.py +0 -0
  99. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedibrokerage/__init__.py +0 -0
  100. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jediconfig/__init__.py +0 -0
  101. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jediconfig/jedi_config.py +0 -0
  102. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedicore/FactoryBase.py +0 -0
  103. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedicore/JediDBProxy.py +0 -0
  104. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedicore/JediDBProxyPool.py +0 -0
  105. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedicore/JediDBSchemaInfo.py +0 -0
  106. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedicore/JediException.py +0 -0
  107. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedicore/JediTaskBufferInterface.py +0 -0
  108. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedicore/MsgWrapper.py +0 -0
  109. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedicore/ProcessUtils.py +0 -0
  110. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedicore/SiteCandidate.py +0 -0
  111. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedicore/__init__.py +0 -0
  112. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jediddm/DDMClientBase.py +0 -0
  113. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jediddm/DDMInterface.py +0 -0
  114. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jediddm/GenDDMClient.py +0 -0
  115. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jediddm/__init__.py +0 -0
  116. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedidog/AtlasAnalWatchDog.py +0 -0
  117. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedidog/AtlasDataCarouselWatchDog.py +0 -0
  118. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedidog/AtlasDataLocalityUpdaterWatchDog.py +0 -0
  119. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedidog/AtlasQueueFillerWatchDog.py +0 -0
  120. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedidog/AtlasTaskWithholderWatchDog.py +0 -0
  121. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedidog/AtlasWorkflowManagerWatchDog.py +0 -0
  122. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedidog/GenWatchDog.py +0 -0
  123. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedidog/JumboWatchDog.py +0 -0
  124. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedidog/TypicalWatchDogBase.py +0 -0
  125. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedidog/WatchDogBase.py +0 -0
  126. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedidog/__init__.py +0 -0
  127. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jediexec/reniceJEDI.py +0 -0
  128. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedigen/AtlasTaskGenerator.py +0 -0
  129. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedigen/TaskGeneratorBase.py +0 -0
  130. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedigen/__init__.py +0 -0
  131. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedimsgprocessor/__init__.py +0 -0
  132. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedimsgprocessor/ai_parameter_adjuster_msg_processor +0 -0
  133. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedimsgprocessor/atlas_idds_msg_processor.py +0 -0
  134. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedimsgprocessor/base_msg_processor.py +0 -0
  135. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedimsgprocessor/forwarding_msg_processor.py +0 -0
  136. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedimsgprocessor/hpo_msg_processor.py +0 -0
  137. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedimsgprocessor/jedi_contents_feeder_msg_processor.py +0 -0
  138. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedimsgprocessor/jedi_job_generator_msg_processor.py +0 -0
  139. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedimsgprocessor/jedi_post_processor_msg_processor.py +0 -0
  140. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedimsgprocessor/kafka_msg_processor.py +0 -0
  141. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedimsgprocessor/panda_callback_msg_processor.py +0 -0
  142. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedimsgprocessor/panda_to_jedi_msg_processor.py +0 -0
  143. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedimsgprocessor/status_report_msg_processor.py +0 -0
  144. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedimsgprocessor/workflow_manager_msg_processor.py +0 -0
  145. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jediorder/JediDaemon.py +0 -0
  146. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jediorder/JediKnight.py +0 -0
  147. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jediorder/JediMsgProcessor.py +0 -0
  148. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jediorder/JobBroker.py +0 -0
  149. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jediorder/JobThrottler.py +0 -0
  150. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jediorder/PostProcessor.py +0 -0
  151. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jediorder/TaskGenerator.py +0 -0
  152. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jediorder/TaskSetupper.py +0 -0
  153. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jediorder/WatchDog.py +0 -0
  154. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jediorder/__init__.py +0 -0
  155. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedipprocess/AtlasAnalPostProcessor.py +0 -0
  156. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedipprocess/AtlasPostProcessorUtils.py +0 -0
  157. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedipprocess/AtlasProdPostProcessor.py +0 -0
  158. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedipprocess/GenPostProcessor.py +0 -0
  159. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedipprocess/MailTemplates.py +0 -0
  160. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedipprocess/PostProcessorBase.py +0 -0
  161. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedipprocess/__init__.py +0 -0
  162. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedirefine/AtlasAnalTaskRefiner.py +0 -0
  163. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedirefine/GenTaskRefiner.py +0 -0
  164. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedirefine/RefinerUtils.py +0 -0
  165. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedirefine/TaskRefinerBase.py +0 -0
  166. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedirefine/__init__.py +0 -0
  167. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedisetup/GenTaskSetupper.py +0 -0
  168. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedisetup/SimpleTaskSetupper.py +0 -0
  169. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedisetup/TaskSetupperBase.py +0 -0
  170. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedisetup/__init__.py +0 -0
  171. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/SchemaChecker.py +0 -0
  172. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/addContWoSoTask.py +0 -0
  173. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/addDataCarouselRequest.py +0 -0
  174. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/addEventServiceTask.py +0 -0
  175. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/addHpoTask.py +0 -0
  176. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/addNonAtlasTask.py +0 -0
  177. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/addNonAtlasTaskEnc.py +0 -0
  178. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/addTestTask.py +0 -0
  179. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/addTestTaskParamToDEFT.py +0 -0
  180. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/addTestTaskWithMerger.py +0 -0
  181. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/brokerTest.py +0 -0
  182. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/cancelDataCarouselRequest.py +0 -0
  183. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/contentsFeederTest.py +0 -0
  184. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/contentsFeederTestWithTask.py +0 -0
  185. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/ddmTest.py +0 -0
  186. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/jobGenForOneTask.py +0 -0
  187. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/jobGeneratorTest.py +0 -0
  188. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/jobSplitterTest.py +0 -0
  189. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/jobThrottlerTest.py +0 -0
  190. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/msgProcessorTest.py +0 -0
  191. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/postProcessorTest.py +0 -0
  192. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/resubmitDataCarouselRequest.py +0 -0
  193. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/resubmitTaskParam.py +0 -0
  194. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/taskBrokerTest.py +0 -0
  195. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/taskBrokerTestWithTask.py +0 -0
  196. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/taskBufferTest.py +0 -0
  197. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/taskCommandoTest.py +0 -0
  198. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/taskRefinerTest.py +0 -0
  199. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/testOneTaskToRefine.py +0 -0
  200. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/testOneTaskToTaskBroker.py +0 -0
  201. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/testPandaDDMMap.py +0 -0
  202. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/updateDataCarouselRequestParams.py +0 -0
  203. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/watchDogTest.py +0 -0
  204. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jeditest/workQueueTest.py +0 -0
  205. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedithrottle/AtlasAnalJobThrottler.py +0 -0
  206. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedithrottle/AtlasProdJobThrottler.py +0 -0
  207. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedithrottle/GenJobThrottler.py +0 -0
  208. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedithrottle/JobThrottlerBase.py +0 -0
  209. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandajedi/jedithrottle/__init__.py +0 -0
  210. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/__init__.py +0 -0
  211. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/__init__.py +0 -0
  212. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/__init__.py +0 -0
  213. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/event_api.py +0 -0
  214. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/file_server_api.py +0 -0
  215. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/harvester_api.py +0 -0
  216. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/http_client.py +0 -0
  217. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/idds_api.py +0 -0
  218. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/metaconfig_api.py +0 -0
  219. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/system_api.py +0 -0
  220. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/task_api.py +0 -0
  221. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/tests/__init__.py +0 -0
  222. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/tests/credential_management_api_tests.py +0 -0
  223. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/tests/harvester_api_tests.py +0 -0
  224. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/tests/idds_api_tests.py +0 -0
  225. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/tests/job_api_tests.py +0 -0
  226. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/tests/statistics_api_tests.py +0 -0
  227. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/tests/system_api_tests.py +0 -0
  228. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/tests/task_api_tests.py +0 -0
  229. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/version.py +0 -0
  230. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/api/v1/workflow_api.py +0 -0
  231. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/asyncprocess/__init__.py +0 -0
  232. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/brokerage/SiteMapper.py +0 -0
  233. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/brokerage/__init__.py +0 -0
  234. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/brokerage/broker.py +0 -0
  235. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/config/__init__.py +0 -0
  236. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/config/config_utils.py +0 -0
  237. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/config/daemon_config.py +0 -0
  238. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/config/mcp_config.py +0 -0
  239. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/config/panda_config.py +0 -0
  240. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/configurator/Carbon.py +0 -0
  241. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/configurator/__init__.py +0 -0
  242. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/configurator/aux.py +0 -0
  243. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/daemons/__init__.py +0 -0
  244. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/daemons/master.py +0 -0
  245. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/daemons/master_systemd.py +0 -0
  246. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/daemons/scripts/__init__.py +0 -0
  247. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/daemons/scripts/add_main.py +0 -0
  248. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/daemons/scripts/add_sub.py +0 -0
  249. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/daemons/scripts/cache_pilots.py +0 -0
  250. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/daemons/scripts/cache_schedconfig.py +0 -0
  251. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/daemons/scripts/carbon.py +0 -0
  252. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/daemons/scripts/configurator.py +0 -0
  253. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/daemons/scripts/copyArchive.py +0 -0
  254. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/daemons/scripts/datasetManager.py +0 -0
  255. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/daemons/scripts/dummy_test.py +0 -0
  256. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/daemons/scripts/hs_scrapers.py +0 -0
  257. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/daemons/scripts/metric_collector.py +0 -0
  258. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/daemons/scripts/panda_activeusers_query.py +0 -0
  259. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/daemons/scripts/pilotStreaming.py +0 -0
  260. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/daemons/scripts/task_evaluator.py +0 -0
  261. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/daemons/scripts/tmpwatch.py +0 -0
  262. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/daemons/scripts/worker_synchronization.py +0 -0
  263. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/daemons/utils.py +0 -0
  264. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/dataservice/ErrorCode.py +0 -0
  265. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/dataservice/RecoverLostFilesCore.py +0 -0
  266. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/dataservice/__init__.py +0 -0
  267. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/dataservice/activator.py +0 -0
  268. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/dataservice/adder_dummy_plugin.py +0 -0
  269. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/dataservice/adder_plugin_base.py +0 -0
  270. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/dataservice/adder_result.py +0 -0
  271. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/dataservice/closer.py +0 -0
  272. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/dataservice/closer_atlas_plugin.py +0 -0
  273. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/dataservice/ddm_handler.py +0 -0
  274. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/dataservice/dyn_data_distributer.py +0 -0
  275. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/dataservice/event_lookup_client_ei.py +0 -0
  276. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/dataservice/event_picker.py +0 -0
  277. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/dataservice/finisher.py +0 -0
  278. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/dataservice/setupper.py +0 -0
  279. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/dataservice/setupper_atlas_plugin.py +0 -0
  280. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/dataservice/setupper_dummy_plugin.py +0 -0
  281. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/dataservice/setupper_plugin_base.py +0 -0
  282. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/jobdispatcher/DispatcherUtils.py +0 -0
  283. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/jobdispatcher/ErrorCode.py +0 -0
  284. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/jobdispatcher/Protocol.py +0 -0
  285. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/jobdispatcher/Watcher.py +0 -0
  286. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/jobdispatcher/__init__.py +0 -0
  287. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/pandamcp/__init__.py +0 -0
  288. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/pandamcp/client_utils/get_panda_token.py +0 -0
  289. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/pandamcp/client_utils/get_panda_token.sh +0 -0
  290. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/pandamcp/client_utils/panda_mcp_proxy.py +0 -0
  291. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/pandamcp/client_utils/panda_mcp_wrapper.sh +0 -0
  292. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/pandamcp/mcp_main.py +0 -0
  293. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/pandamcp/mcp_test_client.py +0 -0
  294. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/pandamcp/mcp_utils.py +0 -0
  295. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/pandamcp/panda_mcp_endpoints.json +0 -0
  296. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/proxycache/__init__.py +0 -0
  297. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/proxycache/panda_proxy_cache.py +0 -0
  298. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/proxycache/token_cache.py +0 -0
  299. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/server/.gacl +0 -0
  300. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/server/panda.py +0 -0
  301. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/srvcore/CoreUtils.py +0 -0
  302. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/srvcore/MailUtils.py +0 -0
  303. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/srvcore/__init__.py +0 -0
  304. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/srvcore/allowed_methods.py +0 -0
  305. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/srvcore/srv_msg_utils.py +0 -0
  306. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/ConBridge.py +0 -0
  307. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/DBProxyPool.py +0 -0
  308. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/DatasetSpec.py +0 -0
  309. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/DdmSpec.py +0 -0
  310. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/ErrorCode.py +0 -0
  311. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/EventServiceUtils.py +0 -0
  312. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/FileSpec.py +0 -0
  313. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/GlobalShares.py +0 -0
  314. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/HarvesterMetricsSpec.py +0 -0
  315. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/Initializer.py +0 -0
  316. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/InputChunk.py +0 -0
  317. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/JediCacheSpec.py +0 -0
  318. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/JediDatasetSpec.py +0 -0
  319. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/JediFileSpec.py +0 -0
  320. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/JobSpec.py +0 -0
  321. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/JobUtils.py +0 -0
  322. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/NucleusSpec.py +0 -0
  323. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/OraDBProxy.py +0 -0
  324. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/PanDAMsgProcessor.py +0 -0
  325. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/PandaDBSchemaInfo.py +0 -0
  326. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/ParseJobXML.py +0 -0
  327. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/PickleFileSpec.py +0 -0
  328. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/PickleJobSpec.py +0 -0
  329. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/PrioUtil.py +0 -0
  330. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/ProcessGroups.py +0 -0
  331. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/ResourceSpec.py +0 -0
  332. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/SQLDumper.py +0 -0
  333. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/SQLManager.py +0 -0
  334. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/SupErrors.py +0 -0
  335. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/TaskBufferInterface.py +0 -0
  336. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/WorkQueueMapper.py +0 -0
  337. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/WrappedPostgresConn.py +0 -0
  338. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/db_proxy_mods/OraDBProxy_structure.png +0 -0
  339. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/db_proxy_mods/__init__.py +0 -0
  340. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/db_proxy_mods/base_module.py +0 -0
  341. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/db_proxy_mods/data_carousel_module.py +0 -0
  342. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/db_proxy_mods/job_standalone_module.py +0 -0
  343. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/db_proxy_mods/metrics_module.py +0 -0
  344. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/retryModule.py +0 -0
  345. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/workflow_processor.py +0 -0
  346. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/taskbuffer/wrapped_oracle_conn.py +0 -0
  347. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/SchemaChecker.py +0 -0
  348. {panda_server_source-1.0.2/pandaserver/userinterface → panda_server_source-1.0.4/pandaserver/test}/__init__.py +0 -0
  349. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/banUser.py +0 -0
  350. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/boostPrio.py +0 -0
  351. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/boostUser.py +0 -0
  352. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/callbackDDM.py +0 -0
  353. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/daod_on_demand.py +0 -0
  354. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/finishJob.py +0 -0
  355. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/finishTaskJEDI.py +0 -0
  356. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/getJobs.py +0 -0
  357. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/killJob.py +0 -0
  358. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/killJobLowPrio.py +0 -0
  359. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/killJobsInTask.py +0 -0
  360. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/killTask.py +0 -0
  361. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/killTaskJEDI.py +0 -0
  362. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/killUser.py +0 -0
  363. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/lsst/README.txt +0 -0
  364. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/lsst/lsstSubmit.py +0 -0
  365. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/lsst/lsstSubmitMERGEtest.py +0 -0
  366. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/lsst/lsstSubmitPhosim332.py +0 -0
  367. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/lsst/prepare-client-tarball-from-bigpanda-server.sh +0 -0
  368. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/reassignJobs.py +0 -0
  369. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/reassignSite.py +0 -0
  370. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/reassignTask.py +0 -0
  371. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/reassignWaiting.py +0 -0
  372. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/recoverLostFiles.py +0 -0
  373. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/reloadInputDS.py +0 -0
  374. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/sendCommandToJob.py +0 -0
  375. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/setDebugMode.py +0 -0
  376. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/setPriority.py +0 -0
  377. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/testEvgen.py +0 -0
  378. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/testEvgen17.py +0 -0
  379. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/testG4sim.py +0 -0
  380. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/testG4sim17.py +0 -0
  381. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/testGlobalShares.py +0 -0
  382. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/testReco.py +0 -0
  383. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/testSimulReco14.py +0 -0
  384. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/testSiteMap.py +0 -0
  385. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/test/testUpdateWorkerPilotStatus.py +0 -0
  386. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/userinterface/Client.py +0 -0
  387. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/userinterface/UserIF.py +0 -0
  388. {panda_server_source-1.0.2/pandaserver/workflow → panda_server_source-1.0.4/pandaserver/userinterface}/__init__.py +0 -0
  389. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/workflow/examples/multistep_merge_wfd.yaml +0 -0
  390. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/workflow/pcwl_test.py +0 -0
  391. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/workflow/pcwl_utils.py +0 -0
  392. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/workflow/psnakemake_container.json +0 -0
  393. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/workflow/psnakemake_task.json +0 -0
  394. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/workflow/psnakemake_test.py +0 -0
  395. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/workflow/snakeparser/__init__.py +0 -0
  396. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/workflow/snakeparser/extensions.py +0 -0
  397. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/workflow/snakeparser/log.py +0 -0
  398. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/workflow/snakeparser/names.py +0 -0
  399. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/workflow/snakeparser/parser.py +0 -0
  400. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/workflow/snakeparser/utils.py +0 -0
  401. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/workflow/step_handler_plugins/base_step_handler.py +0 -0
  402. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/workflow/step_handler_plugins/panda_task_step_handler.py +0 -0
  403. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/workflow/workflow_core_smoketest.py +0 -0
  404. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pandaserver/workflow/workflow_utils.py +0 -0
  405. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pyproject-source.toml +0 -0
  406. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/pyproject.toml +0 -0
  407. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/templates/bin/panda_jedi-reniceJEDI.exe.template +0 -0
  408. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/templates/bin/panda_server-makeSlsXml.exe.template +0 -0
  409. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/templates/bin/panda_server-vomsrenew.exe.template +0 -0
  410. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/templates/init.d/panda_daemon.exe.template +0 -0
  411. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/templates/init.d/panda_httpd.exe.template +0 -0
  412. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/templates/init.d/panda_jedi.exe.template +0 -0
  413. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/templates/init.d/panda_mcp.exe.template +0 -0
  414. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/templates/init.d/panda_server.exe.template +0 -0
  415. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/templates/logrotate.d/panda_jedi.template +0 -0
  416. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/templates/logrotate.d/panda_server.logrotate.template +0 -0
  417. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/templates/panda_jedi.cfg.rpmnew.template +0 -0
  418. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/templates/panda_jedi.cron.template +0 -0
  419. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/templates/panda_server-httpd.conf.rpmnew.template +0 -0
  420. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/templates/panda_server.cfg.rpmnew.template +0 -0
  421. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/templates/sysconfig/panda_jedi.sysconfig_for_systemd.template +0 -0
  422. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/templates/sysconfig/panda_jedi.template +0 -0
  423. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/templates/sysconfig/panda_jedi_env.template +0 -0
  424. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/templates/sysconfig/panda_server.sysconfig.rpmnew.template +0 -0
  425. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/templates/sysconfig/panda_server.sysconfig_for_systemd.template +0 -0
  426. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/templates/sysconfig/panda_server_env.systemd.rpmnew.template +0 -0
  427. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/templates/systemd/panda.service.template +0 -0
  428. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/templates/systemd/panda_daemon.service.template +0 -0
  429. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/templates/systemd/panda_httpd.service.template +0 -0
  430. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/templates/systemd/panda_jedi.service.template +0 -0
  431. {panda_server_source-1.0.2 → panda_server_source-1.0.4}/templates/systemd/panda_mcp.service.template +0 -0
@@ -1,6 +1,6 @@
1
1
  # Base Platform Image for PanDA services
2
2
  #
3
- # NOTE: Modify the image tag in ./github/workflows/base-platform-docker-image.yml when OS or Python version is changed
3
+ # NOTE: Modify the image tag in .github/workflows/base-platform-docker-publish.yml when OS or Python version is changed
4
4
 
5
5
  ARG PYTHON_VERSION=3.11.6
6
6
 
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: panda-server-source
3
- Version: 1.0.2
3
+ Version: 1.0.4
4
4
  Summary: Unified PanDA Server and JEDI Package - Source Only
5
5
  Project-URL: Homepage, https://panda-wms.readthedocs.io/en/latest/
6
6
  Author-email: PanDA Team <panda-support@cern.ch>
@@ -0,0 +1 @@
1
+ release_version = "1.0.4"
@@ -23,6 +23,7 @@ logger = PandaLogger().getLogger(__name__.split(".")[-1])
23
23
 
24
24
  APP = "jedi"
25
25
  COMPONENT = "jobbroker"
26
+ ANALYSIS_COMPONENT = "anal_jobbroker"
26
27
  VO = "atlas"
27
28
 
28
29
 
@@ -66,6 +67,9 @@ class AtlasAnalJobBroker(JobBrokerBase):
66
67
  # return for failure
67
68
  retFatal = self.SC_FATAL, inputChunk
68
69
  retTmpError = self.SC_FAILED, inputChunk
70
+ # return when the task is only waiting for something it cannot control, so that
71
+ # it is not penalized with the pending timeout while it waits
72
+ retWaiting = self.SC_WAITING, inputChunk
69
73
  # new maxwdir
70
74
  newMaxwdir = {}
71
75
  # get primary site candidates
@@ -150,12 +154,12 @@ class AtlasAnalJobBroker(JobBrokerBase):
150
154
  # not use MCORE
151
155
  useMP = "unuse"
152
156
  # get statistics of failures
153
- timeWindowForFC = self.taskBufferIF.getConfigValue("anal_jobbroker", "TW_DONE_JOB_STAT", "jedi", taskSpec.vo)
157
+ timeWindowForFC = self.taskBufferIF.getConfigValue(ANALYSIS_COMPONENT, "TW_DONE_JOB_STAT", "jedi", taskSpec.vo)
154
158
  if timeWindowForFC is None:
155
159
  timeWindowForFC = 6
156
160
 
157
161
  # get minimum bad jobs to skip PQ
158
- minBadJobsToSkipPQ = self.taskBufferIF.getConfigValue("anal_jobbroker", "MIN_BAD_JOBS_TO_SKIP_PQ", "jedi", taskSpec.vo)
162
+ minBadJobsToSkipPQ = self.taskBufferIF.getConfigValue(ANALYSIS_COMPONENT, "MIN_BAD_JOBS_TO_SKIP_PQ", "jedi", taskSpec.vo)
159
163
  if minBadJobsToSkipPQ is None:
160
164
  minBadJobsToSkipPQ = 5
161
165
 
@@ -183,20 +187,20 @@ class AtlasAnalJobBroker(JobBrokerBase):
183
187
  if totalJobStat["nRunJobs"] > maxNumRunJobs:
184
188
  tmpLog.error(f"throttle to generate jobs due to too many running jobs {totalJobStat['nRunJobs']} > {gdp_token_jobs}")
185
189
  taskSpec.setErrDiag(tmpLog.uploadLog(taskSpec.jediTaskID))
186
- return retTmpError
190
+ return retWaiting
187
191
  elif totalJobStat["nQueuedJobs"] > maxFactor * maxNumRunJobs:
188
192
  tmpLog.error(f"throttle to generate jobs due to too many queued jobs {totalJobStat['nQueuedJobs']} > {maxFactor}x{gdp_token_jobs}")
189
193
  taskSpec.setErrDiag(tmpLog.uploadLog(taskSpec.jediTaskID))
190
- return retTmpError
194
+ return retWaiting
191
195
  if maxNumRunCores:
192
196
  if totalJobStat["nRunCores"] > maxNumRunCores:
193
197
  tmpLog.error(f"throttle to generate jobs due to too many running cores {totalJobStat['nRunCores']} > {gdp_token_cores}")
194
198
  taskSpec.setErrDiag(tmpLog.uploadLog(taskSpec.jediTaskID))
195
- return retTmpError
199
+ return retWaiting
196
200
  elif totalJobStat["nQueuedCores"] > maxFactor * maxNumRunCores:
197
201
  tmpLog.error(f"throttle to generate jobs due to too many queued cores {totalJobStat['nQueuedCores']} > {maxFactor}x{gdp_token_cores}")
198
202
  taskSpec.setErrDiag(tmpLog.uploadLog(taskSpec.jediTaskID))
199
- return retTmpError
203
+ return retWaiting
200
204
 
201
205
  # get gshare usage
202
206
  ret_val, gshare_usage_dict = AtlasBrokerUtils.getGShareUsage(tbIF=self.taskBufferIF, gshare=taskSpec.gshare)
@@ -250,38 +254,40 @@ class AtlasAnalJobBroker(JobBrokerBase):
250
254
  user_analyis_throttle_intensity_A = 1.0
251
255
 
252
256
  # parameters about Analysis Stabilizer
253
- base_queue_length_per_pq = self.taskBufferIF.getConfigValue("anal_jobbroker", "BASE_QUEUE_LENGTH_PER_PQ", "jedi", taskSpec.vo)
257
+ base_queue_length_per_pq = self.taskBufferIF.getConfigValue(ANALYSIS_COMPONENT, "BASE_QUEUE_LENGTH_PER_PQ", "jedi", taskSpec.vo)
254
258
  if base_queue_length_per_pq is None:
255
259
  base_queue_length_per_pq = 100
256
- base_expected_wait_hour_on_pq = self.taskBufferIF.getConfigValue("anal_jobbroker", "BASE_EXPECTED_WAIT_HOUR_ON_PQ", "jedi", taskSpec.vo)
260
+ base_expected_wait_hour_on_pq = self.taskBufferIF.getConfigValue(ANALYSIS_COMPONENT, "BASE_EXPECTED_WAIT_HOUR_ON_PQ", "jedi", taskSpec.vo)
257
261
  if base_expected_wait_hour_on_pq is None:
258
262
  base_expected_wait_hour_on_pq = 8
259
- base_default_queue_length_per_pq_user = self.taskBufferIF.getConfigValue("anal_jobbroker", "BASE_DEFAULT_QUEUE_LENGTH_PER_PQ_USER", "jedi", taskSpec.vo)
263
+ base_default_queue_length_per_pq_user = self.taskBufferIF.getConfigValue(
264
+ ANALYSIS_COMPONENT, "BASE_DEFAULT_QUEUE_LENGTH_PER_PQ_USER", "jedi", taskSpec.vo
265
+ )
260
266
  if base_default_queue_length_per_pq_user is None:
261
267
  base_default_queue_length_per_pq_user = 5
262
- base_queue_ratio_on_pq = self.taskBufferIF.getConfigValue("anal_jobbroker", "BASE_QUEUE_RATIO_ON_PQ", "jedi", taskSpec.vo)
268
+ base_queue_ratio_on_pq = self.taskBufferIF.getConfigValue(ANALYSIS_COMPONENT, "BASE_QUEUE_RATIO_ON_PQ", "jedi", taskSpec.vo)
263
269
  if base_queue_ratio_on_pq is None:
264
270
  base_queue_ratio_on_pq = 0.05
265
- static_max_queue_running_ratio = self.taskBufferIF.getConfigValue("anal_jobbroker", "STATIC_MAX_QUEUE_RUNNING_RATIO", "jedi", taskSpec.vo)
271
+ static_max_queue_running_ratio = self.taskBufferIF.getConfigValue(ANALYSIS_COMPONENT, "STATIC_MAX_QUEUE_RUNNING_RATIO", "jedi", taskSpec.vo)
266
272
  if static_max_queue_running_ratio is None:
267
273
  static_max_queue_running_ratio = 2.0
268
- max_expected_wait_hour = self.taskBufferIF.getConfigValue("anal_jobbroker", "MAX_EXPECTED_WAIT_HOUR", "jedi", taskSpec.vo)
274
+ max_expected_wait_hour = self.taskBufferIF.getConfigValue(ANALYSIS_COMPONENT, "MAX_EXPECTED_WAIT_HOUR", "jedi", taskSpec.vo)
269
275
  if max_expected_wait_hour is None:
270
276
  max_expected_wait_hour = 12.0
271
277
 
272
- max_missing_input_files = self.taskBufferIF.getConfigValue("jobbroker", "MAX_MISSING_INPUT_FILES", "jedi", taskSpec.vo)
278
+ max_missing_input_files = self.taskBufferIF.getConfigValue(ANALYSIS_COMPONENT, "MAX_MISSING_INPUT_FILES", "jedi", taskSpec.vo)
273
279
  if max_missing_input_files is None:
274
280
  max_missing_input_files = 10
275
- min_input_completeness = self.taskBufferIF.getConfigValue("jobbroker", "MIN_INPUT_COMPLETENESS", "jedi", taskSpec.vo)
281
+ min_input_completeness = self.taskBufferIF.getConfigValue(ANALYSIS_COMPONENT, "MIN_INPUT_COMPLETENESS", "jedi", taskSpec.vo)
276
282
  if min_input_completeness is None:
277
283
  min_input_completeness = 90
278
284
 
279
285
  # minimum brokerage weight
280
286
  min_weight_param = f"MIN_WEIGHT_{taskSpec.prodSourceLabel}_{taskSpec.gshare}"
281
- min_weight = self.taskBufferIF.getConfigValue("jobbroker", min_weight_param, "jedi", taskSpec.vo)
287
+ min_weight = self.taskBufferIF.getConfigValue(COMPONENT, min_weight_param, "jedi", taskSpec.vo)
282
288
  if min_weight is None:
283
289
  min_weight_param = f"MIN_WEIGHT_{taskSpec.prodSourceLabel}"
284
- min_weight = self.taskBufferIF.getConfigValue("jobbroker", min_weight_param, "jedi", taskSpec.vo)
290
+ min_weight = self.taskBufferIF.getConfigValue(COMPONENT, min_weight_param, "jedi", taskSpec.vo)
285
291
  if min_weight is None:
286
292
  min_weight = 0
287
293
 
@@ -304,7 +310,7 @@ class AtlasAnalJobBroker(JobBrokerBase):
304
310
  )
305
311
  )
306
312
  taskSpec.setErrDiag(tmpLog.uploadLog(taskSpec.jediTaskID))
307
- return retTmpError
313
+ return retWaiting
308
314
  elif task_class_value == 0 and usage_percent > user_analyis_to_throttle_threshold_perc_B:
309
315
  # B-tasks to throttle
310
316
  tmpLog.error(
@@ -313,7 +319,7 @@ class AtlasAnalJobBroker(JobBrokerBase):
313
319
  )
314
320
  )
315
321
  taskSpec.setErrDiag(tmpLog.uploadLog(taskSpec.jediTaskID))
316
- return retTmpError
322
+ return retWaiting
317
323
  elif (
318
324
  task_class_value == 1 and usage_percent * usage_slot_ratio_A * user_analyis_throttle_intensity_A > user_analyis_to_throttle_threshold_perc_A
319
325
  ):
@@ -324,7 +330,7 @@ class AtlasAnalJobBroker(JobBrokerBase):
324
330
  )
325
331
  )
326
332
  taskSpec.setErrDiag(tmpLog.uploadLog(taskSpec.jediTaskID))
327
- return retTmpError
333
+ return retWaiting
328
334
  except Exception as e:
329
335
  tmpLog.error(f"got error when checking low-ranked tasks to throttle; skipped : {e}")
330
336
 
@@ -362,11 +368,11 @@ class AtlasAnalJobBroker(JobBrokerBase):
362
368
 
363
369
  # IO intensity cutoff in kB/sec to allow input transfers
364
370
  io_intensity_key = "IO_INTENSITY_CUTOFF_USER"
365
- io_intensity_cutoff = self.taskBufferIF.getConfigValue("anal_jobbroker", io_intensity_key, "jedi", taskSpec.vo)
371
+ io_intensity_cutoff = self.taskBufferIF.getConfigValue(ANALYSIS_COMPONENT, io_intensity_key, "jedi", taskSpec.vo)
366
372
 
367
373
  # timelimit for data locality check
368
374
  loc_check_timeout_key = "DATA_CHECK_TIMEOUT_USER"
369
- loc_check_timeout_val = self.taskBufferIF.getConfigValue("anal_jobbroker", loc_check_timeout_key, "jedi", taskSpec.vo)
375
+ loc_check_timeout_val = self.taskBufferIF.getConfigValue(ANALYSIS_COMPONENT, loc_check_timeout_key, "jedi", taskSpec.vo)
370
376
 
371
377
  # check input datasets
372
378
  element_map = dict()
@@ -1175,8 +1181,17 @@ class AtlasAnalJobBroker(JobBrokerBase):
1175
1181
  newScanSiteList = []
1176
1182
  oldScanSiteList = copy.copy(scanSiteList)
1177
1183
  msg_map = {}
1184
+ # free space
1185
+ diskThreshold_in = self.taskBufferIF.getConfigValue(COMPONENT, "STORAGE_MIN_FREE_SIZE", "jedi", taskSpec.vo)
1186
+ if not diskThreshold_in:
1187
+ # default to 200GB if not set in config
1188
+ diskThreshold_in = 200
1189
+ diskThreshold_out = self.taskBufferIF.getConfigValue(ANALYSIS_COMPONENT, "STORAGE_MIN_FREE_SIZE_OUTPUT", "jedi", taskSpec.vo)
1190
+ if not diskThreshold_out:
1191
+ # default to 200GB if not set in config
1192
+ diskThreshold_out = 200
1178
1193
  for tmpSiteName in self.get_unified_sites(scanSiteList):
1179
- # check endpoint
1194
+ # check output endpoint
1180
1195
  tmpSiteSpec = self.siteMapper.getSite(tmpSiteName)
1181
1196
  scope_input, scope_output = select_scope(tmpSiteSpec, JobUtils.ANALY_PS, JobUtils.ANALY_PS)
1182
1197
  if scope_output not in tmpSiteSpec.ddm_endpoints_output:
@@ -1184,18 +1199,27 @@ class AtlasAnalJobBroker(JobBrokerBase):
1184
1199
  continue
1185
1200
  tmp_output_endpoint = tmpSiteSpec.ddm_endpoints_output[scope_output].getEndPoint(tmpSiteSpec.ddm_output[scope_output])
1186
1201
  if tmp_output_endpoint is not None:
1187
- # free space must be >= 200GB
1188
- diskThreshold = 200
1189
- tmpSpaceSize = 0
1190
- if tmp_output_endpoint["space_expired"] is not None:
1191
- tmpSpaceSize += tmp_output_endpoint["space_expired"]
1192
- if tmp_output_endpoint["space_free"] is not None:
1193
- tmpSpaceSize += tmp_output_endpoint["space_free"]
1194
- if (
1195
- tmpSpaceSize < diskThreshold and "skip_RSE_check" not in tmpSiteSpec.catchall
1196
- ): # skip_RSE_check: exceptional bypass of RSEs without storage reporting
1197
- msg_map[tmpSiteName] = f" skip site={tmpSiteName} due to disk shortage in SE {tmpSpaceSize} < {diskThreshold}GB criteria=-disk"
1202
+ tmp_space_size = tmp_output_endpoint["space_usable"]
1203
+ if tmp_space_size < diskThreshold_out:
1204
+ msg_map[tmpSiteName] = (
1205
+ f" skip site={tmpSiteName} due to output disk shortage in SE {tmp_space_size} < {diskThreshold_out}GB criteria=-disk"
1206
+ )
1198
1207
  continue
1208
+ # check input endpoint to transfer input when data locality is not required
1209
+ if not checkDataLocality:
1210
+ if scope_input not in tmpSiteSpec.ddm_endpoints_input:
1211
+ msg_map[tmpSiteName] = f" skip site={tmpSiteName} since {scope_input} input endpoint undefined criteria=-disk"
1212
+ continue
1213
+ # check only when input and output endpoints are different
1214
+ if tmpSiteSpec.ddm_output[scope_output] != tmpSiteSpec.ddm_input[scope_input]:
1215
+ tmp_input_endpoint = tmpSiteSpec.ddm_endpoints_input[scope_input].getEndPoint(tmpSiteSpec.ddm_input[scope_input])
1216
+ if tmp_input_endpoint is not None:
1217
+ tmp_space_size = tmp_input_endpoint["space_usable"]
1218
+ if tmp_space_size < diskThreshold_in:
1219
+ msg_map[tmpSiteName] = (
1220
+ f" skip site={tmpSiteName} due to input disk shortage in SE {tmp_space_size} < {diskThreshold_in}GB criteria=-disk"
1221
+ )
1222
+ continue
1199
1223
  # check if blacklisted
1200
1224
  tmp_msg = AtlasBrokerUtils.check_endpoints_with_blacklist(tmpSiteSpec, scope_input, scope_output, sites_in_nucleus, remote_source_available)
1201
1225
  if tmp_msg is not None:
@@ -1332,7 +1356,7 @@ class AtlasAnalJobBroker(JobBrokerBase):
1332
1356
  if siteMaxTime != 0 and siteMaxTime < minTimeForZeroWalltime:
1333
1357
  tmpMsg = f" skip site={tmpSiteName} due to site walltime {tmpSiteStr} (site upper limit) insufficient "
1334
1358
  if inputChunk.useScout():
1335
- tmpMsg += f"for scout jobs (requireing {str_minTimeForZeroWalltime} at least) "
1359
+ tmpMsg += f"for scout jobs (requiring {str_minTimeForZeroWalltime} at least) "
1336
1360
  tmpMsg += "criteria=-scout_walltime"
1337
1361
  else:
1338
1362
  tmpMsg += f"for merge or walltime-undefined jobs (requiring {str_minTimeForZeroWalltime} at least) "
@@ -1525,10 +1549,10 @@ class AtlasAnalJobBroker(JobBrokerBase):
1525
1549
  msg_map = {}
1526
1550
  msgList = []
1527
1551
  msgListVP = []
1528
- minQueue = self.taskBufferIF.getConfigValue("anal_jobbroker", "OVERLOAD_MIN_QUEUE", "jedi", taskSpec.vo)
1552
+ minQueue = self.taskBufferIF.getConfigValue(ANALYSIS_COMPONENT, "OVERLOAD_MIN_QUEUE", "jedi", taskSpec.vo)
1529
1553
  if minQueue is None:
1530
1554
  minQueue = 20
1531
- ratioOffset = self.taskBufferIF.getConfigValue("anal_jobbroker", "OVERLOAD_RATIO_OFFSET", "jedi", taskSpec.vo)
1555
+ ratioOffset = self.taskBufferIF.getConfigValue(ANALYSIS_COMPONENT, "OVERLOAD_RATIO_OFFSET", "jedi", taskSpec.vo)
1532
1556
  if ratioOffset is None:
1533
1557
  ratioOffset = 1.2
1534
1558
  grandRatio = AtlasBrokerUtils.get_total_nq_nr_ratio(jobStatPrioMap, taskSpec.gshare)
@@ -1617,7 +1641,7 @@ class AtlasAnalJobBroker(JobBrokerBase):
1617
1641
  continue
1618
1642
  allowed_queue_length_from_wait_time = base_expected_wait_hour_on_pq * to_running_rate
1619
1643
  if nQueue_pq_in_gshare < allowed_queue_length_from_wait_time:
1620
- # not statisfy since overall waiting time of the site is not long enough
1644
+ # not satisfy since overall waiting time of the site is not long enough
1621
1645
  tmpLog.debug(
1622
1646
  "not throttle on {0} since nQ({1}) < {2:.3f} = toRunningRate({3:.3f} /hr) * base wait time ({4} hr)".format(
1623
1647
  tmpSiteName, nQueue_pq_in_gshare, allowed_queue_length_from_wait_time, to_running_rate, base_expected_wait_hour_on_pq
@@ -2055,7 +2079,7 @@ class AtlasAnalJobBroker(JobBrokerBase):
2055
2079
  nbw_main = n_jobs_to_submit
2056
2080
  if taskSpec.gshare in ["User Analysis", "Express Analysis"]:
2057
2081
  nbw_main = main_weight_site_class_dict[bw_map["class"]]
2058
- # secondary weight proportional to remaing queue length
2082
+ # secondary weight proportional to remaining queue length
2059
2083
  nbw_sec = 1
2060
2084
  if taskSpec.gshare in ["User Analysis", "Express Analysis"]:
2061
2085
  _nbw_numer = max(bw_map["rem_q_len"] - nbw_main / site_class_n_site_dict[bw_map["class"]], nbw_main * 0.001)
@@ -8,7 +8,6 @@ import time
8
8
  import traceback
9
9
  from typing import Any
10
10
 
11
- from packaging import version
12
11
  from pandacommon.pandautils.PandaUtils import naive_utcnow
13
12
 
14
13
  from pandajedi.jedicore import Interaction
@@ -16,6 +15,10 @@ from pandajedi.jediddm.DDMInterface import DDMInterface
16
15
  from pandaserver.brokerage.SiteMapper import SiteMapper
17
16
  from pandaserver.dataservice import DataServiceUtils
18
17
  from pandaserver.dataservice.DataServiceUtils import select_scope
18
+ from pandaserver.srvcore.hardware_matching import (
19
+ compare_version_string,
20
+ match_gpu_spec,
21
+ )
19
22
  from pandaserver.taskbuffer import JobUtils, ProcessGroups, SiteSpec
20
23
  from pandaserver.taskbuffer.DdmSpec import DOWNTIME_STATUSES
21
24
 
@@ -916,49 +919,6 @@ def getAnalySitesClass(tbIF, fresher_than_minutes_ago=60):
916
919
  return ret_val, ret_map
917
920
 
918
921
 
919
- def compare_version_string(version_string, comparison_string):
920
- """
921
- Compares a version string with another string composed of a comparison operator and a version string.
922
-
923
- Args:
924
- version_string (str): The version string to compare.
925
- comparison_string (str): The string containing the comparison operator and version string (e.g., ">=2.0").
926
-
927
- Returns:
928
- bool or None: True if the version string satisfies the comparison, False if it doesn't,
929
- or None if the comparison string is invalid.
930
- """
931
- match = re.match(r"([=><]+)(.+)", comparison_string)
932
- if not match:
933
- return None
934
-
935
- operator = match.group(1).strip()
936
- if operator == "=":
937
- operator = "=="
938
- version_to_compare = match.group(2).strip()
939
-
940
- try:
941
- version1 = version.parse(version_string)
942
- version2 = version.parse(version_to_compare)
943
- except version.InvalidVersion:
944
- return None
945
-
946
- if operator == "==":
947
- return version1 == version2
948
- elif operator == "!=":
949
- return version1 != version2
950
- elif operator == ">=":
951
- return version1 >= version2
952
- elif operator == "<=":
953
- return version1 <= version2
954
- elif operator == ">":
955
- return version1 > version2
956
- elif operator == "<":
957
- return version1 < version2
958
- else:
959
- return None
960
-
961
-
962
922
  # check SW with json
963
923
  class JsonSoftwareCheck:
964
924
  # constructor
@@ -1090,54 +1050,12 @@ class JsonSoftwareCheck:
1090
1050
  continue
1091
1051
 
1092
1052
  # All attribute checks use WN GPU monitoring (MV_WORKER_NODE_GPU_SUMMARY)
1093
- # which has richer per-host data (vram, architecture, driver version)
1094
- wn_gpus = self.wn_gpu_map.get(tmp_site_name, [])
1095
-
1096
- # check vendor
1097
- if host_gpu_spec["vendor"] != "*":
1098
- if not wn_gpus or not any(g.get("vendor") and re.match(host_gpu_spec["vendor"], g["vendor"], re.IGNORECASE) for g in wn_gpus):
1099
- continue
1100
-
1101
- # check model (include or exclude pattern)
1102
- if host_gpu_spec["model"] != "*":
1103
- if isinstance(host_gpu_spec["model"], dict):
1104
- model_pattern = host_gpu_spec["model"]["pattern"]
1105
- model_excl = host_gpu_spec["model"].get("excl", False)
1106
- else:
1107
- model_pattern = host_gpu_spec["model"]
1108
- model_excl = False
1109
- if not wn_gpus:
1110
- continue
1111
- matches = any(g.get("model") and re.match(model_pattern, g["model"], re.IGNORECASE) for g in wn_gpus)
1112
- if matches == model_excl:
1113
- continue
1114
-
1115
- # check VRAM (in MB); supports operators: ==, >=, <=, >, <, != (e.g. ">=40960")
1116
- if "vram" in host_gpu_spec:
1117
- if not wn_gpus or not any(g.get("vram") and compare_version_string(str(g["vram"]), host_gpu_spec["vram"]) for g in wn_gpus):
1118
- continue
1119
-
1120
- # check GPU microarchitecture generation (e.g. Ampere, Hopper, Ada Lovelace)
1121
- if "microarchitecture" in host_gpu_spec:
1122
- req_arch = host_gpu_spec["microarchitecture"]
1123
- if isinstance(req_arch, str):
1124
- req_arch = [req_arch]
1125
- if not wn_gpus or not any(g.get("architecture") in req_arch for g in wn_gpus):
1126
- continue
1127
-
1128
- # check minimum CUDA version
1129
- if "version" in host_gpu_spec:
1130
- if not wn_gpus or not any(
1131
- g.get("framework_version") and compare_version_string(g["framework_version"], host_gpu_spec["version"]) for g in wn_gpus
1132
- ):
1133
- continue
1134
-
1135
- # check minimum GPU driver version (kernel driver, e.g. 575.57.08)
1136
- if "driver_version" in host_gpu_spec:
1137
- if not wn_gpus or not any(
1138
- g.get("driver_version") and compare_version_string(g["driver_version"], host_gpu_spec["driver_version"]) for g in wn_gpus
1139
- ):
1140
- continue
1053
+ # which has richer per-host data (vram, architecture, driver version).
1054
+ # The minimum-requirement attributes are checked against all GPU entries of
1055
+ # the queue, to prevent brokering to mixed sites where some nodes fall below
1056
+ # the requirement
1057
+ if not match_gpu_spec(host_gpu_spec, self.wn_gpu_map.get(tmp_site_name, [])):
1058
+ continue
1141
1059
  go_ahead = True
1142
1060
  except Exception as e:
1143
1061
  if log_stream:
@@ -1209,6 +1127,52 @@ class JsonSoftwareCheck:
1209
1127
  return ok_sites, no_auto_sites, preference_weight_map
1210
1128
 
1211
1129
 
1130
+ # pattern to extract the architecture alternation of a cmt_config, e.g. (x86_64|aarch64)-el9-gcc15-opt
1131
+ ARCH_ALTERNATION_IN_CMT_CONFIG = re.compile(r"^\(([A-Za-z0-9_.+-]+(?:\|[A-Za-z0-9_.+-]+)*)\)([A-Za-z0-9_.+-]+)$")
1132
+
1133
+
1134
+ # get CPU architectures of a queue
1135
+ def get_queue_cpu_architectures(queue_name: str, sw_map: dict) -> list:
1136
+ """
1137
+ get CPU architectures of a queue
1138
+ :param queue_name: queue name
1139
+ :param sw_map: software map
1140
+ :return: list of CPU architectures. empty if unavailable
1141
+ """
1142
+ arch_list = []
1143
+ for arch_spec in sw_map.get(queue_name, {}).get("architectures", []):
1144
+ if arch_spec.get("type") == "cpu":
1145
+ arch_list += arch_spec.get("arch", [])
1146
+ return arch_list
1147
+
1148
+
1149
+ # resolve the architecture of cmt_config
1150
+ def resolve_arch_in_cmt_config(queue_name: str, cmt_config: str, sw_map: dict) -> str | None:
1151
+ """
1152
+ resolve the architecture alternation of a cmt_config with the queue's CPU architectures,
1153
+ e.g. (x86_64|aarch64)-el9-gcc15-opt to x86_64-el9-gcc15-opt at an x86_64 queue.
1154
+ Only a leading alternation followed by a literal remainder is supported
1155
+ :param queue_name: queue name
1156
+ :param cmt_config: cmt config to resolve
1157
+ :param sw_map: software map
1158
+ :return: resolved cmt config or None if unresolvable
1159
+ """
1160
+ match = ARCH_ALTERNATION_IN_CMT_CONFIG.search(cmt_config)
1161
+ if not match:
1162
+ return None
1163
+ # return None if the queue doesn't describe CPU architectures
1164
+ queue_arch_list = get_queue_cpu_architectures(queue_name, sw_map)
1165
+ if not queue_arch_list:
1166
+ return None
1167
+ # use the first architecture supported by the queue
1168
+ remainder = match.group(2)
1169
+ for arch in match.group(1).split("|"):
1170
+ if "any" in queue_arch_list or arch in queue_arch_list:
1171
+ return arch + remainder
1172
+ # return None if no architecture is supported by the queue
1173
+ return None
1174
+
1175
+
1212
1176
  # resolve cmt_config
1213
1177
  def resolve_cmt_config(queue_name: str, cmt_config: str, base_platform, sw_map: dict) -> str | None:
1214
1178
  """
@@ -1222,22 +1186,35 @@ def resolve_cmt_config(queue_name: str, cmt_config: str, base_platform, sw_map:
1222
1186
  # return None if queue_name is unavailable
1223
1187
  if queue_name not in sw_map:
1224
1188
  return None
1189
+ cmt_config_list = sw_map[queue_name].get("cmtconfigs", [])
1225
1190
  # return None if cmt_config is valid
1226
- if cmt_config in sw_map[queue_name]["cmtconfigs"]:
1191
+ if cmt_config in cmt_config_list:
1227
1192
  return None
1193
+ resolved_cmt_config = None
1228
1194
  # check if cmt_config matches with any of the queue's cmt_configs
1229
- for tmp_cmt_config in sw_map[queue_name]["cmtconfigs"]:
1230
- if re.search("^" + cmt_config + "$", tmp_cmt_config):
1231
- if base_platform:
1232
- # add base_platform if necessary
1233
- tmp_cmt_config = tmp_cmt_config + "@" + base_platform
1234
- return tmp_cmt_config
1195
+ try:
1196
+ for tmp_cmt_config in cmt_config_list:
1197
+ if re.search("^" + cmt_config + "$", tmp_cmt_config):
1198
+ resolved_cmt_config = tmp_cmt_config
1199
+ break
1200
+ except re.error:
1201
+ # ignore malformed cmt_config
1202
+ return None
1203
+ # resolve the architecture if the queue has no matching cmt_config
1204
+ if resolved_cmt_config is None:
1205
+ resolved_cmt_config = resolve_arch_in_cmt_config(queue_name, cmt_config, sw_map)
1235
1206
  # return None if cmt_config is unavailable
1236
- return None
1207
+ if resolved_cmt_config is None:
1208
+ return None
1209
+ if base_platform:
1210
+ # add base_platform if necessary
1211
+ resolved_cmt_config = resolved_cmt_config + "@" + base_platform
1212
+ return resolved_cmt_config
1237
1213
 
1238
1214
 
1239
1215
  def check_endpoints_with_blacklist(
1240
- site_spec: SiteSpec.SiteSpec, scope_input: str, scope_output: str, sites_in_nucleus: list, remote_source_available: bool
1216
+ site_spec: SiteSpec.SiteSpec, scope_input: str, scope_output: str, sites_in_nucleus: list, remote_source_available: bool,
1217
+ storage_type: str = None, complete_replica_locations: set = None
1241
1218
  ) -> str | None:
1242
1219
  """
1243
1220
  Check if site's endpoints are in the blacklist
@@ -1247,6 +1224,8 @@ def check_endpoints_with_blacklist(
1247
1224
  :param scope_output: output scope
1248
1225
  :param sites_in_nucleus: list of sites in nucleus
1249
1226
  :param remote_source_available: if remote source is available
1227
+ :param storage_type: type of storage
1228
+ :param complete_replica_locations: set of locations with complete replicas for all datasets
1250
1229
 
1251
1230
  :return: description of blacklisted reason or None
1252
1231
  """
@@ -1258,22 +1237,26 @@ def check_endpoints_with_blacklist(
1258
1237
  tmp_site_name = site_spec.sitename
1259
1238
  if scope_input in site_spec.ddm_endpoints_input:
1260
1239
  for tmp_input_endpoint in site_spec.ddm_endpoints_input[scope_input].all.values():
1240
+ if storage_type and tmp_input_endpoint["type"] != storage_type:
1241
+ continue
1261
1242
  tmp_read_input_over_lan = tmp_input_endpoint["detailed_status"].get("read_lan")
1262
1243
  tmp_receive_input_over_wan = tmp_input_endpoint["detailed_status"].get("write_wan")
1263
1244
  # can read input from local
1264
1245
  if tmp_read_input_over_lan not in DOWNTIME_STATUSES:
1265
1246
  read_input_over_lan = True
1266
1247
  # can receive input from remote to local
1267
- if tmp_site_name not in sites_in_nucleus:
1248
+ if tmp_site_name not in sites_in_nucleus or (complete_replica_locations and tmp_input_endpoint["ddm_endpoint_name"] not in complete_replica_locations):
1268
1249
  # satellite sites
1269
1250
  if tmp_receive_input_over_wan not in DOWNTIME_STATUSES:
1270
1251
  receive_input_over_wan = True
1271
1252
  else:
1272
- # NA for nucleus sites
1253
+ # NA for nucleus sites when input datasets are already available
1273
1254
  receive_input_over_wan = True
1274
1255
  remote_source_available = True
1275
1256
  if scope_output in site_spec.ddm_endpoints_output:
1276
1257
  for tmp_output_endpoint in site_spec.ddm_endpoints_output[scope_output].all.values():
1258
+ if storage_type and tmp_output_endpoint["type"] != storage_type:
1259
+ continue
1277
1260
  tmp_write_output_over_lan = tmp_output_endpoint["detailed_status"].get("write_lan")
1278
1261
  tmp_send_output_over_wan = tmp_output_endpoint["detailed_status"].get("read_wan")
1279
1262
  # can write output to local
@@ -316,7 +316,8 @@ class AtlasProdJobBroker(JobBrokerBase):
316
316
  ######################################
317
317
  # check dataset completeness
318
318
  remote_source_available = True
319
- if inputChunk.getDatasets() and not taskSpec.inputPreStaging():
319
+ complete_replica_locations = None
320
+ if inputChunk.getDatasets():
320
321
  for datasetSpec in inputChunk.getDatasets():
321
322
  datasetName = datasetSpec.datasetName
322
323
  # skip distributed datasets
@@ -347,6 +348,14 @@ class AtlasProdJobBroker(JobBrokerBase):
347
348
  tmpLog.error(f"failed to get available storage endpoints with {datasetName}")
348
349
  taskSpec.setErrDiag(tmpLog.uploadLog(taskSpec.jediTaskID))
349
350
  return retTmpError
351
+ # get the list of locations with complete replicas for all datasets
352
+ if complete_replica_locations is None:
353
+ complete_replica_locations = set(tmp_list_of_complete_replica_locations)
354
+ else:
355
+ complete_replica_locations = complete_replica_locations.intersection(set(tmp_list_of_complete_replica_locations))
356
+ if taskSpec.inputPreStaging():
357
+ tmpLog.debug(f"completeness check disabled for {datasetName} since it is being pre-staged")
358
+ continue
350
359
  # pending if the dataset is incomplete or missing at online endpoints
351
360
  if not tmp_complete_disk_ok and not tmp_complete_tape_ok:
352
361
  err_msg = f"{datasetName} is "
@@ -984,6 +993,10 @@ class AtlasProdJobBroker(JobBrokerBase):
984
993
  msg_map = {}
985
994
  tmpLog.set_message_slot()
986
995
  newSkippedTmp = dict()
996
+ diskThreshold = self.taskBufferIF.getConfigValue(COMPONENT, "STORAGE_MIN_FREE_SIZE", "jedi", taskSpec.vo)
997
+ if not diskThreshold:
998
+ # set default threshold to 200GB if not configured
999
+ diskThreshold = 200
987
1000
  for tmpSiteName in self.get_unified_sites(scanSiteList):
988
1001
  tmpSiteSpec = self.siteMapper.getSite(tmpSiteName)
989
1002
  scope_input, scope_output = select_scope(tmpSiteSpec, JobUtils.PROD_PS, JobUtils.PROD_PS)
@@ -992,22 +1005,17 @@ class AtlasProdJobBroker(JobBrokerBase):
992
1005
  tmp_msg = None
993
1006
  # check free size on output endpoint
994
1007
  if tmp_default_output_endpoint is not None:
995
- tmpSpaceSize = 0
996
- if tmp_default_output_endpoint["space_free"] is not None:
997
- tmpSpaceSize += tmp_default_output_endpoint["space_free"]
998
- if tmp_default_output_endpoint["space_expired"] is not None:
999
- tmpSpaceSize += tmp_default_output_endpoint["space_expired"]
1000
- diskThreshold = 200
1001
-
1002
- # skip_RSE_check: exceptional bypass of RSEs without storage reporting
1003
- if tmpSpaceSize < diskThreshold and "skip_RSE_check" not in tmpSiteSpec.catchall:
1008
+ tmpSpaceSize = tmp_default_output_endpoint["space_usable"]
1009
+ if tmpSpaceSize < diskThreshold:
1004
1010
  tmp_msg = (
1005
1011
  f" skip site={tmpSiteName} due to disk shortage at "
1006
1012
  f"{tmpSiteSpec.ddm_output[scope_output]} {tmpSpaceSize}GB < {diskThreshold}GB criteria=-disk"
1007
1013
  )
1008
1014
  # check if blacklisted
1009
1015
  if not tmp_msg:
1010
- tmp_msg = AtlasBrokerUtils.check_endpoints_with_blacklist(tmpSiteSpec, scope_input, scope_output, sites_in_nucleus, remote_source_available)
1016
+ tmp_msg = AtlasBrokerUtils.check_endpoints_with_blacklist(
1017
+ tmpSiteSpec, scope_input, scope_output, sites_in_nucleus, remote_source_available, "DATADISK", complete_replica_locations
1018
+ )
1011
1019
  if tmp_msg is not None:
1012
1020
  newSkippedTmp[tmpSiteName] = tmp_msg
1013
1021
  msg_map[tmpSiteName] = tmp_msg
@@ -1134,7 +1142,7 @@ class AtlasProdJobBroker(JobBrokerBase):
1134
1142
  if siteMaxTime != 0 and siteMaxTime < minTimeForZeroWalltime:
1135
1143
  tmp_msg = f" skip site={tmpSiteName} due to site walltime {tmpSiteStr} (site upper limit) insufficient "
1136
1144
  if inputChunk.useScout():
1137
- tmp_msg += f"for scout jobs (requireing {str_minTimeForZeroWalltime} at least) "
1145
+ tmp_msg += f"for scout jobs (requiring {str_minTimeForZeroWalltime} at least) "
1138
1146
  tmp_msg += "criteria=-scout_walltime"
1139
1147
  else:
1140
1148
  tmp_msg += f"for walltime-undefined jobs (requiring {str_minTimeForZeroWalltime} at least) "
@@ -1789,8 +1797,11 @@ class AtlasProdJobBroker(JobBrokerBase):
1789
1797
  tmpLog.debug(f"using nStarting+nRunning at {tmpPseudoSiteName} to set nRunning={nRunning} due to numSlot={numStandby}")
1790
1798
  else:
1791
1799
  # the number of standby jobs is defined
1800
+ old_nRunning = nRunning
1792
1801
  nRunning = max(int(numStandby / tmpSiteSpec.coreCount), nRunning)
1793
- tmpLog.debug(f"using numSlots={numStandby}/coreCount at {tmpPseudoSiteName} to set nRunning={nRunning}")
1802
+ tmpLog.debug(
1803
+ f"using max(int(numStandby={numStandby}/coreCount={tmpSiteSpec.coreCount}), nRunning={old_nRunning}) at {tmpPseudoSiteName} to set nRunning={nRunning}"
1804
+ )
1794
1805
  manyAssigned = float(nAssigned + 1) / float(nActivated + 1)
1795
1806
  manyAssigned = min(2.0, manyAssigned)
1796
1807
  manyAssigned = max(1.0, manyAssigned)
@@ -94,7 +94,7 @@ class AtlasProdTaskBroker(TaskBrokerBase):
94
94
  class AtlasProdTaskBrokerThread(WorkerThread):
95
95
  # constructor
96
96
  def __init__(self, inputList, threadPool, taskbufferIF, ddmIF, fullRW, prioRW, workQueue):
97
- # initialize woker with no semaphore
97
+ # initialize worker with no semaphore
98
98
  WorkerThread.__init__(self, None, threadPool, logger)
99
99
  # attributres
100
100
  self.inputList = inputList
@@ -360,18 +360,14 @@ class AtlasProdTaskBrokerThread(WorkerThread):
360
360
  to_skip = True
361
361
  break
362
362
  # check space
363
- tmpSpaceSize = 0
364
- if tmpEP["space_free"]:
365
- tmpSpaceSize += tmpEP["space_free"]
366
- if tmpEP["space_expired"]:
367
- tmpSpaceSize += tmpEP["space_expired"]
363
+ tmpSpaceSize = tmpEP["space_usable"]
368
364
  tmpSpaceToUse = 0
369
365
  if tmpNucleus in self.fullRW:
370
366
  # 0.25GB per cpuTime/corePower/day
371
367
  tmpSpaceToUse = int(self.fullRW[tmpNucleus] / 10 / 24 / 3600 * 0.25)
372
368
  if tmpSpaceSize - tmpSpaceToUse < diskThreshold:
373
369
  tmpLog.info(
374
- " skip nucleus={0} since disk shortage (free {1} TB - reserved {2} TB < thr {3} TB) at endpoint {4} criteria=-space".format(
370
+ " skip nucleus={0} since disk shortage (usable {1} TB - projected demand {2} TB < thr {3} TB) at endpoint {4} criteria=-space".format(
375
371
  tmpNucleus, tmpSpaceSize // 1024, tmpSpaceToUse // 1024, diskThreshold // 1024, tmpEP["ddm_endpoint_name"]
376
372
  )
377
373
  )