panda-server-source 0.8.0__tar.gz → 0.8.1__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 (408) hide show
  1. panda_server_source-0.8.1/.gitignore +41 -0
  2. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/Dockerfile +2 -0
  3. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/PKG-INFO +1 -1
  4. panda_server_source-0.8.1/PandaPkgInfo.py +1 -0
  5. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedibrokerage/AtlasAnalJobBroker.py +25 -1
  6. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedibrokerage/AtlasProdJobBroker.py +48 -16
  7. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedibrokerage/AtlasProdTaskBroker.py +1 -1
  8. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedibrokerage/GenJobBroker.py +8 -0
  9. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedicore/JediTaskBuffer.py +11 -2
  10. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedidog/AtlasAnalWatchDog.py +105 -5
  11. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jediorder/JobGenerator.py +3 -0
  12. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedirefine/AtlasAnalTaskRefiner.py +3 -3
  13. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/data_carousel_api.py +62 -2
  14. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/task_api.py +1 -52
  15. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/tests/task_api_tests.py +0 -20
  16. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/brokerage/SiteMapper.py +2 -6
  17. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/config/panda_config.py +6 -1
  18. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/daemons/scripts/hs_scrapers.py +3 -3
  19. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/DataCarousel.py +127 -8
  20. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/JediTaskSpec.py +26 -23
  21. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/JobSpec.py +45 -1
  22. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/SiteSpec.py +38 -4
  23. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/TaskBuffer.py +7 -2
  24. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/db_proxy_mods/entity_module.py +6 -3
  25. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/db_proxy_mods/job_standalone_module.py +48 -0
  26. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/db_proxy_mods/misc_standalone_module.py +10 -9
  27. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/db_proxy_mods/task_standalone_module.py +161 -14
  28. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/db_proxy_mods/worker_module.py +1 -1
  29. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/task_split_rules.py +35 -1
  30. panda_server_source-0.8.0/PandaPkgInfo.py +0 -1
  31. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/.pre-commit-config.yaml +0 -0
  32. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/Dockerfile.base +0 -0
  33. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/LICENSE.txt +0 -0
  34. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/README.md +0 -0
  35. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/package/hatch_build.py +0 -0
  36. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/__init__.py +0 -0
  37. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedibrokerage/AtlasBrokerUtils.py +0 -0
  38. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedibrokerage/JobBrokerBase.py +0 -0
  39. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedibrokerage/TaskBrokerBase.py +0 -0
  40. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedibrokerage/__init__.py +0 -0
  41. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jediconfig/__init__.py +0 -0
  42. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jediconfig/jedi_config.py +0 -0
  43. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedicore/FactoryBase.py +0 -0
  44. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedicore/Interaction.py +0 -0
  45. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedicore/JediDBProxy.py +0 -0
  46. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedicore/JediDBProxyPool.py +0 -0
  47. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedicore/JediDBSchemaInfo.py +0 -0
  48. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedicore/JediException.py +0 -0
  49. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedicore/JediTaskBufferInterface.py +0 -0
  50. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedicore/MsgWrapper.py +0 -0
  51. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedicore/ProcessUtils.py +0 -0
  52. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedicore/SiteCandidate.py +0 -0
  53. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedicore/ThreadUtils.py +0 -0
  54. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedicore/__init__.py +0 -0
  55. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jediddm/AtlasDDMClient.py +0 -0
  56. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jediddm/DDMClientBase.py +0 -0
  57. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jediddm/DDMInterface.py +0 -0
  58. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jediddm/GenDDMClient.py +0 -0
  59. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jediddm/__init__.py +0 -0
  60. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedidog/AtlasDataCarouselWatchDog.py +0 -0
  61. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedidog/AtlasDataLocalityUpdaterWatchDog.py +0 -0
  62. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedidog/AtlasProdWatchDog.py +0 -0
  63. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedidog/AtlasQueueFillerWatchDog.py +0 -0
  64. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedidog/AtlasTaskWithholderWatchDog.py +0 -0
  65. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedidog/AtlasWorkflowManagerWatchDog.py +0 -0
  66. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedidog/GenWatchDog.py +0 -0
  67. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedidog/JumboWatchDog.py +0 -0
  68. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedidog/TypicalWatchDogBase.py +0 -0
  69. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedidog/WatchDogBase.py +0 -0
  70. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedidog/__init__.py +0 -0
  71. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jediexec/reniceJEDI.py +0 -0
  72. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedigen/AtlasTaskGenerator.py +0 -0
  73. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedigen/TaskGeneratorBase.py +0 -0
  74. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedigen/__init__.py +0 -0
  75. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedimsgprocessor/__init__.py +0 -0
  76. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedimsgprocessor/ai_parameter_adjuster_msg_processor +0 -0
  77. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedimsgprocessor/atlas_idds_msg_processor.py +0 -0
  78. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedimsgprocessor/base_msg_processor.py +0 -0
  79. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedimsgprocessor/forwarding_msg_processor.py +0 -0
  80. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedimsgprocessor/hpo_msg_processor.py +0 -0
  81. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedimsgprocessor/jedi_contents_feeder_msg_processor.py +0 -0
  82. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedimsgprocessor/jedi_job_generator_msg_processor.py +0 -0
  83. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedimsgprocessor/jedi_post_processor_msg_processor.py +0 -0
  84. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedimsgprocessor/kafka_msg_processor.py +0 -0
  85. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedimsgprocessor/panda_callback_msg_processor.py +0 -0
  86. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedimsgprocessor/panda_to_jedi_msg_processor.py +0 -0
  87. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedimsgprocessor/processing_msg_processor.py +0 -0
  88. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedimsgprocessor/status_report_msg_processor.py +0 -0
  89. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedimsgprocessor/tape_carousel_msg_processor.py +0 -0
  90. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedimsgprocessor/workflow_manager_msg_processor.py +0 -0
  91. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jediorder/ContentsFeeder.py +0 -0
  92. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jediorder/JediDaemon.py +0 -0
  93. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jediorder/JediKnight.py +0 -0
  94. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jediorder/JediMaster.py +0 -0
  95. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jediorder/JediMsgProcessor.py +0 -0
  96. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jediorder/JobBroker.py +0 -0
  97. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jediorder/JobSplitter.py +0 -0
  98. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jediorder/JobThrottler.py +0 -0
  99. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jediorder/PostProcessor.py +0 -0
  100. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jediorder/TaskBroker.py +0 -0
  101. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jediorder/TaskCommando.py +0 -0
  102. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jediorder/TaskGenerator.py +0 -0
  103. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jediorder/TaskRefiner.py +0 -0
  104. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jediorder/TaskSetupper.py +0 -0
  105. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jediorder/WatchDog.py +0 -0
  106. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jediorder/__init__.py +0 -0
  107. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedipprocess/AtlasAnalPostProcessor.py +0 -0
  108. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedipprocess/AtlasPostProcessorUtils.py +0 -0
  109. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedipprocess/AtlasProdPostProcessor.py +0 -0
  110. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedipprocess/GenPostProcessor.py +0 -0
  111. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedipprocess/MailTemplates.py +0 -0
  112. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedipprocess/PostProcessorBase.py +0 -0
  113. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedipprocess/__init__.py +0 -0
  114. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedirefine/AtlasProdTaskRefiner.py +0 -0
  115. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedirefine/GenTaskRefiner.py +0 -0
  116. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedirefine/RefinerUtils.py +0 -0
  117. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedirefine/TaskRefinerBase.py +0 -0
  118. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedirefine/__init__.py +0 -0
  119. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedisetup/AtlasTaskSetupper.py +0 -0
  120. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedisetup/GenTaskSetupper.py +0 -0
  121. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedisetup/SimpleTaskSetupper.py +0 -0
  122. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedisetup/TaskSetupperBase.py +0 -0
  123. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedisetup/__init__.py +0 -0
  124. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/SchemaChecker.py +0 -0
  125. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/addContWoSoTask.py +0 -0
  126. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/addDataCarouselRequest.py +0 -0
  127. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/addEventServiceTask.py +0 -0
  128. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/addHpoTask.py +0 -0
  129. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/addIDDSStageInRequest.py +0 -0
  130. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/addNonAtlasTask.py +0 -0
  131. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/addNonAtlasTaskEnc.py +0 -0
  132. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/addTestTask.py +0 -0
  133. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/addTestTaskParamToDEFT.py +0 -0
  134. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/addTestTaskWithMerger.py +0 -0
  135. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/brokerTest.py +0 -0
  136. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/cancelDataCarouselRequest.py +0 -0
  137. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/contentsFeederTest.py +0 -0
  138. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/contentsFeederTestWithTask.py +0 -0
  139. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/ddmTest.py +0 -0
  140. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/jobGenForOneTask.py +0 -0
  141. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/jobGeneratorTest.py +0 -0
  142. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/jobSplitterTest.py +0 -0
  143. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/jobThrottlerTest.py +0 -0
  144. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/msgProcessorTest.py +0 -0
  145. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/postProcessorTest.py +0 -0
  146. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/resubmitDataCarouselRequest.py +0 -0
  147. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/resubmitTaskParam.py +0 -0
  148. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/taskBrokerTest.py +0 -0
  149. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/taskBrokerTestWithTask.py +0 -0
  150. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/taskBufferTest.py +0 -0
  151. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/taskCommandoTest.py +0 -0
  152. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/taskRefinerTest.py +0 -0
  153. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/testOneTaskToRefine.py +0 -0
  154. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/testOneTaskToTaskBroker.py +0 -0
  155. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/testPandaDDMMap.py +0 -0
  156. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/updateDataCarouselRequestParams.py +0 -0
  157. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/watchDogTest.py +0 -0
  158. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jeditest/workQueueTest.py +0 -0
  159. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedithrottle/AtlasAnalJobThrottler.py +0 -0
  160. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedithrottle/AtlasProdJobThrottler.py +0 -0
  161. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedithrottle/GenJobThrottler.py +0 -0
  162. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedithrottle/JobThrottlerBase.py +0 -0
  163. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandajedi/jedithrottle/__init__.py +0 -0
  164. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/__init__.py +0 -0
  165. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/__init__.py +0 -0
  166. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/__init__.py +0 -0
  167. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/common.py +0 -0
  168. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/credential_management_api.py +0 -0
  169. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/event_api.py +0 -0
  170. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/file_server_api.py +0 -0
  171. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/harvester_api.py +0 -0
  172. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/http_client.py +0 -0
  173. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/idds_api.py +0 -0
  174. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/job_api.py +0 -0
  175. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/metaconfig_api.py +0 -0
  176. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/pilot_api.py +0 -0
  177. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/statistics_api.py +0 -0
  178. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/system_api.py +0 -0
  179. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/tests/__init__.py +0 -0
  180. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/tests/credential_management_api_tests.py +0 -0
  181. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/tests/data_carousel_api_tests.py +0 -0
  182. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/tests/harvester_api_tests.py +0 -0
  183. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/tests/idds_api_tests.py +0 -0
  184. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/tests/job_api_tests.py +0 -0
  185. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/tests/pilot_api_tests.py +0 -0
  186. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/tests/statistics_api_tests.py +0 -0
  187. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/tests/system_api_tests.py +0 -0
  188. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/version.py +0 -0
  189. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/api/v1/workflow_api.py +0 -0
  190. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/brokerage/__init__.py +0 -0
  191. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/brokerage/broker.py +0 -0
  192. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/config/__init__.py +0 -0
  193. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/config/config_utils.py +0 -0
  194. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/config/daemon_config.py +0 -0
  195. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/config/mcp_config.py +0 -0
  196. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/configurator/Carbon.py +0 -0
  197. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/configurator/Configurator.py +0 -0
  198. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/configurator/__init__.py +0 -0
  199. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/configurator/aux.py +0 -0
  200. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/daemons/__init__.py +0 -0
  201. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/daemons/master.py +0 -0
  202. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/daemons/master_systemd.py +0 -0
  203. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/daemons/scripts/__init__.py +0 -0
  204. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/daemons/scripts/add_main.py +0 -0
  205. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/daemons/scripts/add_sub.py +0 -0
  206. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/daemons/scripts/cache_pilots.py +0 -0
  207. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/daemons/scripts/cache_schedconfig.py +0 -0
  208. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/daemons/scripts/carbon.py +0 -0
  209. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/daemons/scripts/configurator.py +0 -0
  210. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/daemons/scripts/copyArchive.py +0 -0
  211. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/daemons/scripts/datasetManager.py +0 -0
  212. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/daemons/scripts/dummy_test.py +0 -0
  213. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/daemons/scripts/evpPD2P.py +0 -0
  214. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/daemons/scripts/metric_collector.py +0 -0
  215. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/daemons/scripts/panda_activeusers_query.py +0 -0
  216. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/daemons/scripts/pilotStreaming.py +0 -0
  217. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/daemons/scripts/process_workflow_files_daemon.py +0 -0
  218. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/daemons/scripts/recover_lost_files_daemon.py +0 -0
  219. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/daemons/scripts/task_evaluator.py +0 -0
  220. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/daemons/scripts/tmpwatch.py +0 -0
  221. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/daemons/scripts/worker_synchronization.py +0 -0
  222. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/daemons/utils.py +0 -0
  223. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/dataservice/DataServiceUtils.py +0 -0
  224. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/dataservice/ErrorCode.py +0 -0
  225. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/dataservice/RecoverLostFilesCore.py +0 -0
  226. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/dataservice/__init__.py +0 -0
  227. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/dataservice/activator.py +0 -0
  228. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/dataservice/adder_atlas_plugin.py +0 -0
  229. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/dataservice/adder_dummy_plugin.py +0 -0
  230. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/dataservice/adder_gen.py +0 -0
  231. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/dataservice/adder_plugin_base.py +0 -0
  232. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/dataservice/adder_result.py +0 -0
  233. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/dataservice/adder_simple_plugin.py +0 -0
  234. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/dataservice/closer.py +0 -0
  235. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/dataservice/closer_atlas_plugin.py +0 -0
  236. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/dataservice/ddm.py +0 -0
  237. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/dataservice/ddm_handler.py +0 -0
  238. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/dataservice/dyn_data_distributer.py +0 -0
  239. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/dataservice/event_lookup_client_ei.py +0 -0
  240. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/dataservice/event_picker.py +0 -0
  241. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/dataservice/finisher.py +0 -0
  242. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/dataservice/setupper.py +0 -0
  243. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/dataservice/setupper_atlas_plugin.py +0 -0
  244. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/dataservice/setupper_dummy_plugin.py +0 -0
  245. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/dataservice/setupper_plugin_base.py +0 -0
  246. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/jobdispatcher/DispatcherUtils.py +0 -0
  247. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/jobdispatcher/ErrorCode.py +0 -0
  248. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/jobdispatcher/JobDispatcher.py +0 -0
  249. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/jobdispatcher/Protocol.py +0 -0
  250. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/jobdispatcher/Watcher.py +0 -0
  251. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/jobdispatcher/__init__.py +0 -0
  252. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/pandamcp/__init__.py +0 -0
  253. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/pandamcp/mcp_main.py +0 -0
  254. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/pandamcp/mcp_test_client.py +0 -0
  255. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/pandamcp/mcp_utils.py +0 -0
  256. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/proxycache/__init__.py +0 -0
  257. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/proxycache/panda_proxy_cache.py +0 -0
  258. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/proxycache/token_cache.py +0 -0
  259. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/server/.gacl +0 -0
  260. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/server/panda.py +0 -0
  261. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/srvcore/CoreUtils.py +0 -0
  262. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/srvcore/MailUtils.py +0 -0
  263. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/srvcore/__init__.py +0 -0
  264. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/srvcore/allowed_methods.py +0 -0
  265. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/srvcore/oidc_utils.py +0 -0
  266. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/srvcore/panda_request.py +0 -0
  267. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/srvcore/srv_msg_utils.py +0 -0
  268. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/ConBridge.py +0 -0
  269. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/DBProxyPool.py +0 -0
  270. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/DatasetSpec.py +0 -0
  271. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/DdmSpec.py +0 -0
  272. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/ErrorCode.py +0 -0
  273. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/EventServiceUtils.py +0 -0
  274. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/FileSpec.py +0 -0
  275. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/GlobalShares.py +0 -0
  276. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/HarvesterMetricsSpec.py +0 -0
  277. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/Initializer.py +0 -0
  278. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/InputChunk.py +0 -0
  279. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/JediCacheSpec.py +0 -0
  280. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/JediDatasetSpec.py +0 -0
  281. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/JediFileSpec.py +0 -0
  282. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/JobUtils.py +0 -0
  283. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/NucleusSpec.py +0 -0
  284. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/OraDBProxy.py +0 -0
  285. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/PanDAMsgProcessor.py +0 -0
  286. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/PandaDBSchemaInfo.py +0 -0
  287. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/ParseJobXML.py +0 -0
  288. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/PickleFileSpec.py +0 -0
  289. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/PickleJobSpec.py +0 -0
  290. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/PrioUtil.py +0 -0
  291. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/ProcessGroups.py +0 -0
  292. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/ResourceSpec.py +0 -0
  293. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/SQLDumper.py +0 -0
  294. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/SQLManager.py +0 -0
  295. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/SupErrors.py +0 -0
  296. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/TaskBufferInterface.py +0 -0
  297. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/Utils.py +0 -0
  298. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/WorkQueue.py +0 -0
  299. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/WorkQueueMapper.py +0 -0
  300. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/WorkerSpec.py +0 -0
  301. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/WrappedCursor.py +0 -0
  302. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/WrappedPickle.py +0 -0
  303. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/WrappedPostgresConn.py +0 -0
  304. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/__init__.py +0 -0
  305. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/db_proxy_mods/OraDBProxy_structure.png +0 -0
  306. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/db_proxy_mods/__init__.py +0 -0
  307. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/db_proxy_mods/base_module.py +0 -0
  308. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/db_proxy_mods/data_carousel_module.py +0 -0
  309. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/db_proxy_mods/job_complex_module.py +0 -0
  310. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/db_proxy_mods/metrics_module.py +0 -0
  311. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/db_proxy_mods/task_complex_module.py +0 -0
  312. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/db_proxy_mods/task_event_module.py +0 -0
  313. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/db_proxy_mods/task_utils_module.py +0 -0
  314. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/db_proxy_mods/workflow_module.py +0 -0
  315. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/retryModule.py +0 -0
  316. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/workflow_processor.py +0 -0
  317. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/taskbuffer/wrapped_oracle_conn.py +0 -0
  318. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/SchemaChecker.py +0 -0
  319. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/__init__.py +0 -0
  320. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/banUser.py +0 -0
  321. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/boostPrio.py +0 -0
  322. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/boostUser.py +0 -0
  323. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/callbackDDM.py +0 -0
  324. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/daod_on_demand.py +0 -0
  325. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/finishJob.py +0 -0
  326. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/finishTaskJEDI.py +0 -0
  327. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/getJobs.py +0 -0
  328. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/killJob.py +0 -0
  329. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/killJobLowPrio.py +0 -0
  330. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/killJobsInTask.py +0 -0
  331. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/killTask.py +0 -0
  332. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/killTaskJEDI.py +0 -0
  333. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/killUser.py +0 -0
  334. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/lsst/README.txt +0 -0
  335. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/lsst/lsstSubmit.py +0 -0
  336. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/lsst/lsstSubmitMERGEtest.py +0 -0
  337. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/lsst/lsstSubmitPhosim332.py +0 -0
  338. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/lsst/prepare-client-tarball-from-bigpanda-server.sh +0 -0
  339. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/reassignJobs.py +0 -0
  340. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/reassignSite.py +0 -0
  341. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/reassignTask.py +0 -0
  342. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/reassignWaiting.py +0 -0
  343. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/recoverLostFiles.py +0 -0
  344. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/reloadInputDS.py +0 -0
  345. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/sendCommandToJob.py +0 -0
  346. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/setDebugMode.py +0 -0
  347. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/setPriority.py +0 -0
  348. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/testEvgen.py +0 -0
  349. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/testEvgen17.py +0 -0
  350. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/testG4sim.py +0 -0
  351. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/testG4sim17.py +0 -0
  352. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/testGlobalShares.py +0 -0
  353. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/testReco.py +0 -0
  354. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/testSimulReco14.py +0 -0
  355. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/testSiteMap.py +0 -0
  356. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/test/testUpdateWorkerPilotStatus.py +0 -0
  357. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/userinterface/Client.py +0 -0
  358. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/userinterface/UserIF.py +0 -0
  359. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/userinterface/__init__.py +0 -0
  360. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/workflow/__init__.py +0 -0
  361. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/workflow/data_handler_plugins/base_data_handler.py +0 -0
  362. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/workflow/data_handler_plugins/ddm_collection_data_handler.py +0 -0
  363. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/workflow/data_handler_plugins/panda_task_data_handler.py +0 -0
  364. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/workflow/pcwl_test.py +0 -0
  365. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/workflow/pcwl_utils.py +0 -0
  366. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/workflow/psnakemake_container.json +0 -0
  367. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/workflow/psnakemake_task.json +0 -0
  368. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/workflow/psnakemake_test.py +0 -0
  369. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/workflow/snakeparser/__init__.py +0 -0
  370. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/workflow/snakeparser/extensions.py +0 -0
  371. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/workflow/snakeparser/log.py +0 -0
  372. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/workflow/snakeparser/names.py +0 -0
  373. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/workflow/snakeparser/parser.py +0 -0
  374. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/workflow/snakeparser/utils.py +0 -0
  375. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/workflow/step_handler_plugins/base_step_handler.py +0 -0
  376. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/workflow/step_handler_plugins/panda_task_step_handler.py +0 -0
  377. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/workflow/workflow_base.py +0 -0
  378. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/workflow/workflow_core.py +0 -0
  379. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/workflow/workflow_core_smoketest.py +0 -0
  380. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/workflow/workflow_parser.py +0 -0
  381. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pandaserver/workflow/workflow_utils.py +0 -0
  382. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pyproject-source.toml +0 -0
  383. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/pyproject.toml +0 -0
  384. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/templates/bin/panda_jedi-reniceJEDI.exe.template +0 -0
  385. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/templates/bin/panda_server-makeSlsXml.exe.template +0 -0
  386. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/templates/bin/panda_server-vomsrenew.exe.template +0 -0
  387. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/templates/init.d/panda_daemon.exe.template +0 -0
  388. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/templates/init.d/panda_httpd.exe.template +0 -0
  389. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/templates/init.d/panda_jedi.exe.template +0 -0
  390. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/templates/init.d/panda_mcp.exe.template +0 -0
  391. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/templates/init.d/panda_server.exe.template +0 -0
  392. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/templates/logrotate.d/panda_jedi.template +0 -0
  393. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/templates/logrotate.d/panda_server.logrotate.template +0 -0
  394. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/templates/panda_jedi.cfg.rpmnew.template +0 -0
  395. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/templates/panda_jedi.cron.template +0 -0
  396. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/templates/panda_server-httpd.conf.rpmnew.template +0 -0
  397. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/templates/panda_server.cfg.rpmnew.template +0 -0
  398. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/templates/sysconfig/panda_jedi.sysconfig_for_systemd.template +0 -0
  399. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/templates/sysconfig/panda_jedi.template +0 -0
  400. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/templates/sysconfig/panda_jedi_env.template +0 -0
  401. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/templates/sysconfig/panda_server.sysconfig.rpmnew.template +0 -0
  402. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/templates/sysconfig/panda_server.sysconfig_for_systemd.template +0 -0
  403. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/templates/sysconfig/panda_server_env.systemd.rpmnew.template +0 -0
  404. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/templates/systemd/panda.service.template +0 -0
  405. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/templates/systemd/panda_daemon.service.template +0 -0
  406. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/templates/systemd/panda_httpd.service.template +0 -0
  407. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/templates/systemd/panda_jedi.service.template +0 -0
  408. {panda_server_source-0.8.0 → panda_server_source-0.8.1}/templates/systemd/panda_mcp.service.template +0 -0
@@ -0,0 +1,41 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.pyo
5
+ *.pyd
6
+ *.so
7
+ *.egg
8
+ *.egg-info/
9
+ dist/
10
+ build/
11
+ .eggs/
12
+
13
+ # Virtual environments
14
+ .venv/
15
+ venv/
16
+ env/
17
+
18
+ # Distribution / packaging
19
+ *.whl
20
+ *.tar.gz
21
+
22
+ # Testing
23
+ .tox/
24
+ .coverage
25
+ .coverage.*
26
+ htmlcov/
27
+ .pytest_cache/
28
+ *.log
29
+
30
+ # IDEs
31
+ .idea/
32
+ .vscode/
33
+ *.swp
34
+ *~
35
+
36
+ # OS
37
+ .DS_Store
38
+ Thumbs.db
39
+
40
+ # Claude
41
+ .claude/
@@ -11,6 +11,8 @@ RUN /opt/panda/bin/pip install --no-cache-dir .[postgres,oracle,mcp]
11
11
  RUN /opt/panda/bin/pip install --no-cache-dir rucio-clients
12
12
  RUN /opt/panda/bin/pip install --no-cache-dir "git+https://github.com/PanDAWMS/panda-cacheschedconfig.git"
13
13
  RUN ln -s /opt/panda/lib/python*/site-packages/mod_wsgi/server/mod_wsgi*.so /etc/httpd/modules/mod_wsgi.so
14
+ # Remove the default OS ssl.conf which references a non-existent localhost.crt and conflicts with panda's SSL config
15
+ RUN rm -f /etc/httpd/conf.d/ssl.conf
14
16
 
15
17
  WORKDIR /
16
18
  RUN rm -rf /tmp/src
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: panda-server-source
3
- Version: 0.8.0
3
+ Version: 0.8.1
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 = "0.8.1"
@@ -161,7 +161,7 @@ class AtlasAnalJobBroker(JobBrokerBase):
161
161
  totalJobStat = self.taskBufferIF.countJobsPerTarget_JEDI(taskSpec.origUserName, True)
162
162
  self.set_task_common("totalJobStat", totalJobStat)
163
163
  # check total to cap
164
- if totalJobStat:
164
+ if totalJobStat and not inputChunk.isMerging:
165
165
  if taskSpec.workingGroup:
166
166
  gdp_token_jobs = "CAP_RUNNING_GROUP_JOBS"
167
167
  gdp_token_cores = "CAP_RUNNING_GROUP_CORES"
@@ -756,6 +756,30 @@ class AtlasAnalJobBroker(JobBrokerBase):
756
756
  retVal = retTmpError
757
757
  continue
758
758
 
759
+ ######################################
760
+ # selection with IO intensity
761
+ if taskSpec.ioIntensity and not inputChunk.isMerging:
762
+ newScanSiteList = []
763
+ oldScanSiteList = copy.copy(scanSiteList)
764
+ msg_map = {}
765
+ for tmpSiteName in scanSiteList:
766
+ tmpSiteSpec = self.siteMapper.getSite(tmpSiteName)
767
+ max_io_intensity = tmpSiteSpec.get_max_io_intensity()
768
+ if max_io_intensity is None or taskSpec.ioIntensity <= max_io_intensity:
769
+ newScanSiteList.append(tmpSiteName)
770
+ else:
771
+ msg_map[tmpSiteSpec.get_unified_name()] = (
772
+ f" skip site={tmpSiteSpec.get_unified_name()} since ioIntensity={taskSpec.ioIntensity} "
773
+ f"is larger than site max_io_intensity={max_io_intensity} criteria=-max_io_intensity"
774
+ )
775
+ scanSiteList = newScanSiteList
776
+ self.add_summary_message(oldScanSiteList, scanSiteList, "max IO intensity check", tmpLog, msg_map)
777
+ if not scanSiteList:
778
+ self.dump_summary(tmpLog)
779
+ tmpLog.error("no candidates")
780
+ retVal = retTmpError
781
+ continue
782
+
759
783
  ######################################
760
784
  # selection for VP
761
785
  if taskSpec.avoid_vp() or avoidVP or not checkDataLocality:
@@ -1406,6 +1406,30 @@ class AtlasProdJobBroker(JobBrokerBase):
1406
1406
  taskSpec.setErrDiag(tmpLog.uploadLog(taskSpec.jediTaskID))
1407
1407
  return retTmpError
1408
1408
 
1409
+ ######################################
1410
+ # selection with IO intensity
1411
+ if taskSpec.ioIntensity and not inputChunk.isMerging:
1412
+ newScanSiteList = []
1413
+ oldScanSiteList = copy.copy(scanSiteList)
1414
+ msg_map = {}
1415
+ for tmpSiteName in scanSiteList:
1416
+ tmpSiteSpec = self.siteMapper.getSite(tmpSiteName)
1417
+ max_io_intensity = tmpSiteSpec.get_max_io_intensity()
1418
+ if max_io_intensity is None or taskSpec.ioIntensity <= max_io_intensity:
1419
+ newScanSiteList.append(tmpSiteName)
1420
+ else:
1421
+ msg_map[tmpSiteSpec.get_unified_name()] = (
1422
+ f" skip site={tmpSiteSpec.get_unified_name()} since ioIntensity={taskSpec.ioIntensity} "
1423
+ f"is larger than site max_io_intensity={max_io_intensity} criteria=-max_io_intensity"
1424
+ )
1425
+ scanSiteList = newScanSiteList
1426
+ self.add_summary_message(oldScanSiteList, scanSiteList, "max IO intensity check", tmpLog, msg_map)
1427
+ if not scanSiteList:
1428
+ self.dump_summary(tmpLog)
1429
+ tmpLog.error("no candidates")
1430
+ taskSpec.setErrDiag(tmpLog.uploadLog(taskSpec.jediTaskID))
1431
+ return retTmpError
1432
+
1409
1433
  ######################################
1410
1434
  # selection for full chain
1411
1435
  if nucleusSpec:
@@ -1679,6 +1703,8 @@ class AtlasProdJobBroker(JobBrokerBase):
1679
1703
  tmpLog.error("failed to get job statistics with priority")
1680
1704
  taskSpec.setErrDiag(tmpLog.uploadLog(taskSpec.jediTaskID))
1681
1705
  return retTmpError
1706
+ # get resource types per site
1707
+ site_resource_type_map = self.taskBufferIF.get_distinct_resource_types_per_site(taskSpec.jediTaskID)
1682
1708
  workerStat = self.taskBufferIF.ups_load_worker_stats()
1683
1709
  upsQueues = set(self.taskBufferIF.ups_get_queues())
1684
1710
  tmpLog.info(f"calculate weight and check cap for {len(scanSiteList)} candidates")
@@ -1767,31 +1793,37 @@ class AtlasProdJobBroker(JobBrokerBase):
1767
1793
  useAssigned = True
1768
1794
  # stat with resource type
1769
1795
  RT_Cap = 2
1770
- if tmpSiteName in tmpStatMapRT and taskSpec.resource_type in tmpStatMapRT[tmpSiteName]:
1771
- useCapRT = True
1772
- tmpRTrunning = tmpStatMapRT[tmpSiteName][taskSpec.resource_type].get("running", 0)
1773
- tmpRTrunning = max(tmpRTrunning, nRunning)
1774
- tmpRTqueue = tmpStatMapRT[tmpSiteName][taskSpec.resource_type].get("defined", 0)
1775
- if useAssigned:
1776
- tmpRTqueue += tmpStatMapRT[tmpSiteName][taskSpec.resource_type].get("assigned", 0)
1777
- tmpRTqueue += tmpStatMapRT[tmpSiteName][taskSpec.resource_type].get("activated", 0)
1778
- tmpRTqueue += tmpStatMapRT[tmpSiteName][taskSpec.resource_type].get("starting", 0)
1779
- else:
1780
- useCapRT = False
1781
- tmpRTqueue = 0
1782
- tmpRTrunning = 0
1796
+ useCapRT = False
1797
+ tmpRTqueue = 0
1798
+ tmpRTrunning = 0
1799
+ resource_type_str = taskSpec.resource_type
1800
+ if tmpSiteName in tmpStatMapRT:
1801
+ # loop over all resource types for the site since task and job may have different resource types
1802
+ tmp_resource_types = site_resource_type_map.get(tmpSiteName, [taskSpec.resource_type])
1803
+ resource_type_str = ",".join(tmp_resource_types)
1804
+ for tmp_resource_type in tmp_resource_types:
1805
+ if tmp_resource_type in tmpStatMapRT[tmpSiteName]:
1806
+ useCapRT = True
1807
+ tmpRTrunning += tmpStatMapRT[tmpSiteName][tmp_resource_type].get("running", 0)
1808
+ tmpRTqueue += tmpStatMapRT[tmpSiteName][tmp_resource_type].get("defined", 0)
1809
+ if useAssigned:
1810
+ tmpRTqueue += tmpStatMapRT[tmpSiteName][tmp_resource_type].get("assigned", 0)
1811
+ tmpRTqueue += tmpStatMapRT[tmpSiteName][tmp_resource_type].get("activated", 0)
1812
+ tmpRTqueue += tmpStatMapRT[tmpSiteName][tmp_resource_type].get("starting", 0)
1813
+ if useCapRT:
1814
+ tmpRTrunning = max(tmpRTrunning, nRunning)
1783
1815
  if totalSize == 0 or totalSize - siteSizeMap[tmpSiteName] <= 0:
1784
1816
  weight = float(nRunning + 1) / float(nActivated + nStarting + nDefined + 10)
1785
1817
  weightStr = (
1786
1818
  f"nRun={nRunning} nAct={nActivated} nStart={nStarting} nDef={nDefined} nPilot={nPilot}{corrNumPilotStr} "
1787
- f"totalSizeMB={int(totalSize / 1024 / 1024)} totalNumFiles={maxNumFiles} nRun_rt={tmpRTrunning} nQueued_rt={tmpRTqueue} "
1819
+ f"totalSizeMB={int(totalSize / 1024 / 1024)} totalNumFiles={maxNumFiles} nRun_rt={tmpRTrunning} nQueued_rt={tmpRTqueue} resource_type={resource_type_str} "
1788
1820
  )
1789
1821
  else:
1790
1822
  weight = float(nRunning + 1) / float(nActivated + nAssigned + nStarting + nDefined + 10) / manyAssigned
1791
1823
  weightStr = (
1792
1824
  f"nRun={nRunning} nAct={nActivated} nAss={nAssigned} nStart={nStarting} nDef={nDefined} manyAss={manyAssigned} "
1793
1825
  f"nPilot={nPilot}{corrNumPilotStr} totalSizeMB={int(totalSize / 1024 / 1024)} "
1794
- f"totalNumFiles={maxNumFiles} nRun_rt={tmpRTrunning} nQueued_rt={tmpRTqueue} "
1826
+ f"totalNumFiles={maxNumFiles} nRun_rt={tmpRTrunning} nQueued_rt={tmpRTqueue} resource_type={resource_type_str} "
1795
1827
  )
1796
1828
 
1797
1829
  # reduce weights by taking data availability into account
@@ -1954,7 +1986,7 @@ class AtlasProdJobBroker(JobBrokerBase):
1954
1986
  ngMsg += f"nDefined_rt+nActivated_rt+nAssigned_rt+nStarting_rt={tmpRTqueue} "
1955
1987
  else:
1956
1988
  ngMsg += f"nDefined_rt+nActivated_rt+nStarting_rt={tmpRTqueue} (nAssigned_rt ignored due to data locally available) "
1957
- ngMsg += "with gshare+resource_type is greater than max({cutOffValue},{RT_Cap}*nRun_rt={RT_Cap}*{tmpRTrunning}) criteria=-cap_rt"
1989
+ ngMsg += f"with gshare+resource_type({resource_type_str}) is greater than max({cutOffValue},{RT_Cap}*nRun_rt={RT_Cap}*{tmpRTrunning}) criteria=-cap_rt"
1958
1990
  elif (
1959
1991
  nRunning + nActivated + nAssigned + nStarting + nDefined == 0
1960
1992
  and taskSpec.currentPriority <= self.max_prio_for_bootstrap
@@ -354,7 +354,7 @@ class AtlasProdTaskBrokerThread(WorkerThread):
354
354
  write_wan_status = tmpEP["detailed_status"].get("write_wan")
355
355
  if write_wan_status in ["OFF", "TEST"]:
356
356
  tmpLog.info(
357
- f" skip nucleus={tmpNucleus} since {tmp_ddm_endpoint_name} has write_wan={read_wan_status} criteria=-destination_blacklist"
357
+ f" skip nucleus={tmpNucleus} since {tmp_ddm_endpoint_name} has write_wan={write_wan_status} criteria=-destination_blacklist"
358
358
  )
359
359
  to_skip = True
360
360
  break
@@ -7,6 +7,7 @@ from pandajedi.jedicore import Interaction
7
7
  from pandajedi.jedicore.MsgWrapper import MsgWrapper
8
8
  from pandajedi.jedicore.SiteCandidate import SiteCandidate
9
9
  from pandajedi.jedirefine import RefinerUtils
10
+ from pandaserver.config import panda_config
10
11
  from pandaserver.srvcore import CoreUtils
11
12
 
12
13
  from . import AtlasBrokerUtils
@@ -277,6 +278,7 @@ class GenJobBroker(JobBrokerBase):
277
278
  ######################################
278
279
  # get list of available files
279
280
  availableFileMap = {}
281
+ total_num_files = 0
280
282
  for datasetSpec in inputChunk.getDatasets():
281
283
  try:
282
284
  # get list of site to be scanned
@@ -312,6 +314,7 @@ class GenJobBroker(JobBrokerBase):
312
314
  if tmpAvFileMap is None:
313
315
  raise Interaction.JEDITemporaryError("ddmIF.getAvailableFiles failed")
314
316
  availableFileMap[datasetSpec.datasetName] = tmpAvFileMap
317
+ total_num_files += len(datasetSpec.Files)
315
318
  except Exception as e:
316
319
  tmpLog.error(f"failed to get available files with {e}")
317
320
  taskSpec.setErrDiag(tmpLog.uploadLog(taskSpec.jediTaskID))
@@ -369,6 +372,11 @@ class GenJobBroker(JobBrokerBase):
369
372
  for siteCandidateSpec in candidateSpecList:
370
373
  # append
371
374
  inputChunk.addSiteCandidate(siteCandidateSpec)
375
+ if panda_config.disable_file_dispatch and len(siteCandidateSpec.localDiskFiles) < total_num_files:
376
+ tmpLog.debug(
377
+ f" skip {siteCandidateSpec.siteName} due to input file dispatch is disabled and not all files are available at the site ({len(siteCandidateSpec.localDiskFiles)} < {total_num_files})"
378
+ )
379
+ continue
372
380
  newScanSiteList.append(siteCandidateSpec.siteName)
373
381
  tmpLog.debug(f" use {siteCandidateSpec.siteName} with weight={siteCandidateSpec.weight} nFiles={len(siteCandidateSpec.localDiskFiles)}")
374
382
  scanSiteList = newScanSiteList
@@ -677,6 +677,11 @@ class JediTaskBuffer(TaskBuffer.TaskBuffer, CommandReceiveInterface):
677
677
  with self.proxyPool.get() as proxy:
678
678
  return proxy.throttleTask_JEDI(jediTaskID, waitTime, errorDialog)
679
679
 
680
+ # throttle tasks of a user or working group and get the list of throttled tasks
681
+ def throttle_tasks_with_uid(self, vo: str, prod_source_label: str, wait_time: int, dialog: str, uid: str, is_user: bool = True):
682
+ with self.proxyPool.get() as proxy:
683
+ return proxy.throttle_tasks_with_uid(vo, prod_source_label, wait_time, dialog, uid, is_user)
684
+
680
685
  # release throttled tasks
681
686
  def releaseThrottledTasks_JEDI(self, vo, prodSourceLabel):
682
687
  with self.proxyPool.get() as proxy:
@@ -757,12 +762,16 @@ class JediTaskBuffer(TaskBuffer.TaskBuffer, CommandReceiveInterface):
757
762
  with self.proxyPool.get() as proxy:
758
763
  return proxy.getFailureCountsForTask_JEDI(jediTaskID, timeWindow)
759
764
 
760
- # count the number of queued jobs per user or working group
761
-
765
+ # count the number of queued jobs per user or working group
762
766
  def countJobsPerTarget_JEDI(self, target, is_user):
763
767
  with self.proxyPool.get() as proxy:
764
768
  return proxy.countJobsPerTarget_JEDI(target, is_user)
765
769
 
770
+ # count the number of jobs and cores per user or working group in VO and production source label
771
+ def count_jobs_per_uid_JEDI(self, vo, prod_source_label):
772
+ with self.proxyPool.get() as proxy:
773
+ return proxy.count_jobs_per_uid_JEDI(vo, prod_source_label)
774
+
766
775
  # get old merge job PandaIDs
767
776
  def getOldMergeJobPandaIDs_JEDI(self, jediTaskID, pandaID):
768
777
  with self.proxyPool.get() as proxy:
@@ -149,7 +149,8 @@ class AtlasAnalWatchDog(TypicalWatchDogBase):
149
149
  maxTransfer = 1024
150
150
  # throttle interval
151
151
  thrInterval = 120
152
- # loop over all users
152
+ # loop over all user tasks with data motion
153
+ user_motion_to_keep_throttled = {}
153
154
  for userName, userDict in dispUserTasks.items():
154
155
  # loop over all transfer types
155
156
  for transferType, maxSize in [("prestaging", maxPrestaging), ("transfer", maxTransfer)]:
@@ -166,17 +167,116 @@ class AtlasAnalWatchDog(TypicalWatchDogBase):
166
167
  tmpLog.debug(f"action=throttle_{transferType} jediTaskID={taskID} for user={userName}")
167
168
  errDiag = f"throttled since transferring large data volume in total={userTotal}GB > limit={maxSize}GB type={transferType}"
168
169
  self.taskBufferIF.throttleTask_JEDI(taskID, thrInterval, errDiag)
169
- # remove the user from the list
170
- if userName in thrUserTasks and transferType in thrUserTasks[userName]:
171
- del thrUserTasks[userName][transferType]
172
- # release users
170
+ # keep throttled
171
+ user_motion_to_keep_throttled.setdefault(userName, set()).add(transferType)
172
+ # release tasks related to data motion
173
173
  for userName, taskData in thrUserTasks.items():
174
174
  for transferType, taskIDs in taskData.items():
175
+ if transferType not in ["prestaging", "transfer"]:
176
+ continue
177
+ if userName in user_motion_to_keep_throttled and transferType in user_motion_to_keep_throttled[userName]:
178
+ continue
175
179
  tmpLog.debug(f"user={userName} release throttled tasks with {transferType}")
176
180
  # unthrottle tasks
177
181
  for taskID in taskIDs:
178
182
  tmpLog.debug(f"action=release_{transferType} jediTaskID={taskID} for user={userName}")
179
183
  self.taskBufferIF.release_task_on_hold(taskID, "throttled")
184
+
185
+ # throttle users with too many running/queued jobs
186
+ queue_factor = 2
187
+ throttle_threshold = 0.95
188
+ release_threshold = 0.85
189
+ gdp_token_group_jobs = "CAP_RUNNING_GROUP_JOBS"
190
+ gdp_token_group_cores = "CAP_RUNNING_GROUP_CORES"
191
+ max_num_run_group_jobs = self.taskBufferIF.getConfigValue("prio_mgr", gdp_token_group_jobs)
192
+ max_num_run_group_cores = self.taskBufferIF.getConfigValue("prio_mgr", gdp_token_group_cores)
193
+ gdp_token_user_jobs = "CAP_RUNNING_USER_JOBS"
194
+ gdp_token_user_cores = "CAP_RUNNING_USER_CORES"
195
+ max_num_run_user_jobs = self.taskBufferIF.getConfigValue("prio_mgr", gdp_token_user_jobs)
196
+ max_num_run_user_cores = self.taskBufferIF.getConfigValue("prio_mgr", gdp_token_user_cores)
197
+ # get job count per uid
198
+ job_count_per_uid = self.taskBufferIF.count_jobs_per_uid_JEDI(self.vo, self.prodSourceLabel)
199
+ users_to_keep_throttled = set()
200
+ for uid, count_dict in job_count_per_uid.items():
201
+ to_throttle = True
202
+ to_release = True
203
+ msg = None
204
+ if count_dict["is_user"]:
205
+ # user
206
+ if max_num_run_user_jobs:
207
+ if count_dict["nRunJobs"] > max_num_run_user_jobs * throttle_threshold:
208
+ msg = f"""throttle due to too many running jobs {count_dict["nRunJobs"]} > {gdp_token_user_jobs}x{throttle_threshold} type=jobs"""
209
+ elif count_dict["nQueuedJobs"] > max_num_run_user_jobs * queue_factor * throttle_threshold:
210
+ msg = f"""throttle due to too many queued jobs {count_dict["nQueuedJobs"]} > {gdp_token_user_jobs}x{throttle_threshold}x{queue_factor} type=jobs"""
211
+ if msg is None and max_num_run_user_cores:
212
+ if count_dict["nRunCores"] > max_num_run_user_cores:
213
+ msg = (
214
+ f"""throttle due to too many running cores {count_dict["nRunCores"]} > {gdp_token_user_cores}x{throttle_threshold} type=jobs"""
215
+ )
216
+ elif count_dict["nQueuedCores"] > max_num_run_user_cores * queue_factor * throttle_threshold:
217
+ msg = f"""throttle due to too many queued cores {count_dict["nQueuedCores"]} > {gdp_token_user_cores}x{throttle_threshold}x{queue_factor} type=jobs"""
218
+ if msg is None:
219
+ to_throttle = False
220
+ # check if can be released
221
+ if max_num_run_user_jobs:
222
+ if (
223
+ count_dict["nRunJobs"] > max_num_run_user_jobs * release_threshold
224
+ or count_dict["nQueuedJobs"] > max_num_run_user_jobs * queue_factor * release_threshold
225
+ ):
226
+ to_release = False
227
+ if max_num_run_user_cores:
228
+ if (
229
+ count_dict["nRunCores"] > max_num_run_user_cores * release_threshold
230
+ or count_dict["nQueuedCores"] > max_num_run_user_cores * queue_factor * release_threshold
231
+ ):
232
+ to_release = False
233
+ else:
234
+ # group
235
+ if max_num_run_group_jobs:
236
+ if count_dict["nRunJobs"] > max_num_run_group_jobs:
237
+ msg = f"""throttle due to too many running jobs {count_dict["nRunJobs"]} > {gdp_token_group_jobs}x{throttle_threshold} type=jobs"""
238
+ elif count_dict["nQueuedJobs"] > max_num_run_group_jobs * queue_factor * throttle_threshold:
239
+ msg = f"""throttle due to too many queued jobs {count_dict["nQueuedJobs"]} > {gdp_token_group_jobs}x{throttle_threshold}x{queue_factor} type=jobs"""
240
+ if msg is None and max_num_run_group_cores:
241
+ if count_dict["nRunCores"] > max_num_run_group_cores:
242
+ msg = (
243
+ f"""throttle due to too many running cores {count_dict["nRunCores"]} > {gdp_token_group_cores}x{throttle_threshold} type=jobs"""
244
+ )
245
+ elif count_dict["nQueuedCores"] > max_num_run_group_cores * queue_factor * throttle_threshold:
246
+ msg = f"""throttle due to too many queued cores {count_dict["nQueuedCores"]} > {gdp_token_group_cores}x{throttle_threshold}x{queue_factor} type=jobs"""
247
+ if msg is None:
248
+ to_throttle = False
249
+ # check if can be released
250
+ if max_num_run_group_jobs:
251
+ if (
252
+ count_dict["nRunJobs"] > max_num_run_group_jobs * release_threshold
253
+ or count_dict["nQueuedJobs"] > max_num_run_group_jobs * queue_factor * release_threshold
254
+ ):
255
+ to_release = False
256
+ if max_num_run_group_cores:
257
+ if (
258
+ count_dict["nRunCores"] > max_num_run_group_cores * release_threshold
259
+ or count_dict["nQueuedCores"] > max_num_run_group_cores * queue_factor * release_threshold
260
+ ):
261
+ to_release = False
262
+ if to_throttle:
263
+ tmpLog.debug(f"uid={uid} {msg}")
264
+ throttled_tasks = self.taskBufferIF.throttle_tasks_with_uid(self.vo, self.prodSourceLabel, thrInterval, msg, uid, count_dict["is_user"])
265
+ tmpLog.debug(f"throttled tasks: {throttled_tasks}")
266
+ if to_throttle or not to_release:
267
+ users_to_keep_throttled.add(uid)
268
+ # unthrottle users which are currently throttled but no more exceed the limit
269
+ for userName, taskData in thrUserTasks.items():
270
+ for transferType, taskIDs in taskData.items():
271
+ if transferType not in ["jobs"]:
272
+ continue
273
+ if userName in users_to_keep_throttled:
274
+ continue
275
+ tmpLog.debug(f"user={userName} release throttled tasks since no more excess of queued and running job counts")
276
+ # unthrottle tasks
277
+ for taskID in taskIDs:
278
+ tmpLog.debug(f"action=release_{transferType} jediTaskID={taskID} for user={userName}")
279
+ self.taskBufferIF.release_task_on_hold(taskID, "throttled")
180
280
  tmpLog.debug("done")
181
281
  except Exception:
182
282
  errtype, errvalue = sys.exc_info()[:2]
@@ -1503,6 +1503,8 @@ class JobGeneratorThread(WorkerThread):
1503
1503
  # on-site merging
1504
1504
  if taskSpec.on_site_merging():
1505
1505
  jobSpec.set_on_site_merging()
1506
+ if inputChunk.isMerging:
1507
+ jobSpec.set_pmerge_job_flag()
1506
1508
  # set task queued time
1507
1509
  jobSpec.set_task_queued_time(task_queued_time)
1508
1510
  # extract middle name
@@ -1985,6 +1987,7 @@ class JobGeneratorThread(WorkerThread):
1985
1987
  specialHandling = specialHandling[:-1]
1986
1988
  if specialHandling != "":
1987
1989
  jobSpec.specialHandling = specialHandling
1990
+ jobSpec.set_build_job_flag()
1988
1991
  jobSpec.set_task_queued_time(taskSpec.get_queued_time())
1989
1992
  libDsFileNameBase = libDsName + ".$JEDIFILEID"
1990
1993
  # make lib.tgz
@@ -241,11 +241,11 @@ class AtlasAnalTaskRefiner(TaskRefinerBase):
241
241
  self.taskSpec.reqID = tmpJobID
242
242
  # site limitation
243
243
  if "excludedSite" in taskParamMap and "includedSite" in taskParamMap:
244
- self.taskSpec.setLimitedSites("incexc")
244
+ self.taskSpec.setLimitedSites("with_allow_and_denylist")
245
245
  elif "excludedSite" in taskParamMap:
246
- self.taskSpec.setLimitedSites("exc")
246
+ self.taskSpec.setLimitedSites("with_denylist")
247
247
  elif "includedSite" in taskParamMap:
248
- self.taskSpec.setLimitedSites("inc")
248
+ self.taskSpec.setLimitedSites("with_allowlist")
249
249
  # input prestaging
250
250
  if self.taskSpec.inputPreStaging():
251
251
  # set first contents feed flag
@@ -50,7 +50,7 @@ def change_staging_destination(req: PandaRequest, request_id: int | None = None,
50
50
  Change destination of staging
51
51
 
52
52
  The current active staging request will be cancelled, and a new request will be created with the newly selected destination RSE, excluding the original destination.
53
- The reqeusts can be specified by request_id or dataset (if both exist, request_id is taken).
53
+ The requests can be specified by request_id or dataset (if both exist, request_id is taken).
54
54
  Requires a secure connection production role.
55
55
 
56
56
  API details:
@@ -210,7 +210,7 @@ def force_to_staging(req: PandaRequest, request_id: int | None = None, dataset:
210
210
 
211
211
  The request will skip the queue and go to staging immediately (will submit DDM rules).
212
212
  Only effective on queued requests.
213
- The reqeusts can be specified by request_id or dataset (if both exist, request_id is taken).
213
+ The requests can be specified by request_id or dataset (if both exist, request_id is taken).
214
214
  Requires a secure connection production role.
215
215
 
216
216
  API details:
@@ -262,3 +262,63 @@ def force_to_staging(req: PandaRequest, request_id: int | None = None, dataset:
262
262
  tmp_logger.debug(f"Done. Took {time_delta.seconds}.{time_delta.microseconds // 1000:03d} sec")
263
263
 
264
264
  return generate_response(success, message, data)
265
+
266
+
267
+ @request_validation(_logger, secure=True, production=True, request_method="POST")
268
+ def retire_unused(req: PandaRequest, request_id: int | None = None, dataset: str | None = None) -> dict:
269
+ """
270
+ Retire unused staging request
271
+
272
+ If the request is done and has no related tasks, it can be retired to clean up the DDM rules and replicas.
273
+ The requests can be specified by request_id or dataset (if both exist, request_id is taken).
274
+ Requires a secure connection production role.
275
+
276
+ API details:
277
+ HTTP Method: POST
278
+ Path: /v1/data_carousel/retire_unused
279
+
280
+ Args:
281
+ req(PandaRequest): internally generated request object
282
+ request_id (int|None): request_id of the staging request, e.g. `123`
283
+ dataset (str|None): dataset name of the staging request in the format of Rucio DID, e.g. `"mc20_13TeV:mc20_13TeV.700449.Sh_2211_Wtaunu_mW_120_ECMS_BFilter.merge.AOD.e8351_s3681_r13144_r13146_tid36179107_00"`
284
+
285
+ Returns:
286
+ dict: dictionary `{'success': True/False, 'message': 'Description of error', 'data': <requested data>}`
287
+ """
288
+ tmp_logger = LogWrapper(_logger, f"retire_unused request_id={request_id} dataset={dataset}")
289
+ tmp_logger.debug("Start")
290
+ success, message, data = False, "", None
291
+ time_start = naive_utcnow()
292
+
293
+ dc_req_spec = None
294
+ if request_id is not None:
295
+ # specified by request_id
296
+ dc_req_spec = global_dcif.get_request_by_id(request_id)
297
+ elif request_id is None and dataset is not None:
298
+ # specified by dataset
299
+ dc_req_spec = global_dcif.get_request_by_dataset(dataset)
300
+
301
+ if dc_req_spec is not None:
302
+ is_ok, dc_req_spec, err_msg = global_dcif.retire_unused_request(dc_req_spec)
303
+ if not is_ok:
304
+ err_msg = f"failed to retire request_id={dc_req_spec.request_id} : {err_msg}"
305
+ tmp_logger.error(err_msg)
306
+ success, message = False, err_msg
307
+ else:
308
+ success = True
309
+ message = f"retired successfully"
310
+ data = {
311
+ "request_id": dc_req_spec.request_id,
312
+ "dataset": dc_req_spec.dataset,
313
+ "status": dc_req_spec.status,
314
+ "ddm_rule_id": dc_req_spec.ddm_rule_id,
315
+ }
316
+ else:
317
+ err_msg = f"failed to get corresponding request"
318
+ tmp_logger.error(err_msg)
319
+ success, message = False, err_msg
320
+
321
+ time_delta = naive_utcnow() - time_start
322
+ tmp_logger.debug(f"Done. Took {time_delta.seconds}.{time_delta.microseconds // 1000:03d} sec")
323
+
324
+ return generate_response(success, message, data)
@@ -1417,57 +1417,6 @@ def get_parent_detailed_info(req: PandaRequest, task_id: int) -> Dict[str, Any]:
1417
1417
  return generate_response(True, data=task_info)
1418
1418
 
1419
1419
 
1420
- @request_validation(_logger, secure=True, request_method="GET")
1421
- def get_scout_job_descriptions(req: PandaRequest, task_id: int) -> Dict:
1422
- """
1423
- Get scout job descriptions for a task.
1424
-
1425
- Resolves all PanDA job IDs associated with a JEDI task, retrieves their job
1426
- descriptions including archive lookup, and returns only scout jobs. Scout
1427
- jobs are identified by the ``sj`` token in the comma-separated
1428
- ``specialHandling`` field.
1429
- Requires a secure connection.
1430
-
1431
- API details:
1432
- HTTP Method: GET
1433
- Path: /v1/task/get_scout_job_descriptions
1434
-
1435
- Args:
1436
- req(PandaRequest): internally generated request object containing the env variables.
1437
- task_id (int): JEDI task ID.
1438
-
1439
- Returns:
1440
- dict: The system response `{"success": success, "message": message, "data": data}`.
1441
- When successful, the data field contains a list of scout job descriptions.
1442
- If no jobs are found or no scout jobs exist, returns success=True with empty list.
1443
- """
1444
- tmp_logger = LogWrapper(_logger, f"get_scout_job_descriptions task_id={task_id}")
1445
- tmp_logger.debug("Start")
1446
-
1447
- try:
1448
- task_id = int(task_id)
1449
- except Exception:
1450
- tmp_logger.error("Failed due to invalid task_id")
1451
- return generate_response(False, message=MESSAGE_TASK_ID)
1452
-
1453
- job_ids = global_task_buffer.getPandaIDsWithTaskID(task_id, scout_only=True)
1454
- if not job_ids:
1455
- tmp_logger.debug("No scout jobs found for task")
1456
- return generate_response(True, data=[])
1457
-
1458
- tmp_logger.debug(f"Found {len(job_ids)} scout job IDs for task")
1459
-
1460
- max_ids = 5500
1461
- if len(job_ids) > max_ids:
1462
- tmp_logger.error(f"List of PanDA IDs is longer than {max_ids}. Truncating the list.")
1463
- job_ids = job_ids[:max_ids]
1464
-
1465
- scout_jobs = [job.to_dict_advanced() for job in global_task_buffer.getFullJobStatus(job_ids) if job is not None]
1466
-
1467
- tmp_logger.debug(f"Done with {len(scout_jobs)} scout jobs")
1468
- return generate_response(True, data=scout_jobs)
1469
-
1470
-
1471
1420
  @request_validation(_logger, secure=True, request_method="GET")
1472
1421
  def get_job_descriptions(req: PandaRequest, task_id: int, unsuccessful_only: bool = False) -> Dict:
1473
1422
  """
@@ -1514,7 +1463,7 @@ def get_job_descriptions(req: PandaRequest, task_id: int, unsuccessful_only: boo
1514
1463
  tmp_logger.error(f"List of PanDA IDs is longer than {max_ids}. Truncating the list.")
1515
1464
  job_ids = job_ids[:max_ids]
1516
1465
 
1517
- jobs = [job.to_dict_advanced() for job in global_task_buffer.getFullJobStatus(job_ids) if job is not None]
1466
+ jobs = [job.to_dict_advanced(add_extra_info=True) for job in global_task_buffer.getFullJobStatus(job_ids) if job is not None]
1518
1467
 
1519
1468
  tmp_logger.debug(f"Done with {len(jobs)} jobs")
1520
1469
  return generate_response(True, data=jobs)
@@ -542,26 +542,6 @@ class TestTaskAPI(unittest.TestCase):
542
542
  self.assertEqual(output, expected_response)
543
543
 
544
544
 
545
- def test_get_scout_job_descriptions(self):
546
- # def get_scout_job_descriptions(req: PandaRequest, task_id: int) -> Dict:
547
- url = f"{api_url_ssl}/task/get_scout_job_descriptions"
548
- print(f"Testing URL: {url}")
549
- data = {"task_id": JEDI_TASK_ID}
550
- status, output = self.http_client.get(url, data)
551
- print(output)
552
- output["status"] = status
553
-
554
- if JEDI_TASK_ID == -1:
555
- # Fake task has no scout jobs, returns empty list
556
- output["message"] = ""
557
- expected_response = {"status": 0, "success": True, "data": [], "message": ""}
558
- self.assertEqual(output, expected_response)
559
- else:
560
- # Real task: success with a list of scout job descriptions
561
- self.assertEqual(status, 0)
562
- self.assertTrue(output["success"])
563
- self.assertIsInstance(output["data"], list)
564
-
565
545
  def test_get_job_descriptions(self):
566
546
  # def get_job_descriptions(req: PandaRequest, task_id: int, unsuccessful_only: bool = False) -> Dict:
567
547
  url = f"{api_url_ssl}/task/get_job_descriptions"
@@ -285,12 +285,8 @@ class SiteMapper:
285
285
  if cloud == WORLD_CLOUD:
286
286
  return self.worldCloudSpec
287
287
 
288
- # return some default sites
289
- default_cloud = {
290
- "source": "default",
291
- "sites": self.cloudSpec["US"]["sites"],
292
- }
293
- return default_cloud
288
+ # return all sites (WORLD) as fallback for unknown clouds
289
+ return self.worldCloudSpec
294
290
 
295
291
  # accessor for cloud
296
292
  def checkCloud(self, cloud):