panda-server-source 0.8.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (375) hide show
  1. panda_server_source-0.8.0.dist-info/METADATA +55 -0
  2. panda_server_source-0.8.0.dist-info/RECORD +375 -0
  3. panda_server_source-0.8.0.dist-info/WHEEL +4 -0
  4. panda_server_source-0.8.0.dist-info/licenses/LICENSE.txt +202 -0
  5. pandajedi/__init__.py +0 -0
  6. pandajedi/jedibrokerage/AtlasAnalJobBroker.py +2343 -0
  7. pandajedi/jedibrokerage/AtlasBrokerUtils.py +1292 -0
  8. pandajedi/jedibrokerage/AtlasProdJobBroker.py +2064 -0
  9. pandajedi/jedibrokerage/AtlasProdTaskBroker.py +629 -0
  10. pandajedi/jedibrokerage/GenJobBroker.py +381 -0
  11. pandajedi/jedibrokerage/JobBrokerBase.py +133 -0
  12. pandajedi/jedibrokerage/TaskBrokerBase.py +15 -0
  13. pandajedi/jedibrokerage/__init__.py +0 -0
  14. pandajedi/jediconfig/__init__.py +0 -0
  15. pandajedi/jediconfig/jedi_config.py +40 -0
  16. pandajedi/jedicore/FactoryBase.py +182 -0
  17. pandajedi/jedicore/Interaction.py +433 -0
  18. pandajedi/jedicore/JediDBProxy.py +56 -0
  19. pandajedi/jedicore/JediDBProxyPool.py +37 -0
  20. pandajedi/jedicore/JediDBSchemaInfo.py +17 -0
  21. pandajedi/jedicore/JediException.py +13 -0
  22. pandajedi/jedicore/JediTaskBuffer.py +984 -0
  23. pandajedi/jedicore/JediTaskBufferInterface.py +50 -0
  24. pandajedi/jedicore/MsgWrapper.py +124 -0
  25. pandajedi/jedicore/ProcessUtils.py +34 -0
  26. pandajedi/jedicore/SiteCandidate.py +90 -0
  27. pandajedi/jedicore/ThreadUtils.py +205 -0
  28. pandajedi/jedicore/__init__.py +0 -0
  29. pandajedi/jediddm/AtlasDDMClient.py +1708 -0
  30. pandajedi/jediddm/DDMClientBase.py +16 -0
  31. pandajedi/jediddm/DDMInterface.py +83 -0
  32. pandajedi/jediddm/GenDDMClient.py +17 -0
  33. pandajedi/jediddm/__init__.py +0 -0
  34. pandajedi/jedidog/AtlasAnalWatchDog.py +648 -0
  35. pandajedi/jedidog/AtlasDataCarouselWatchDog.py +189 -0
  36. pandajedi/jedidog/AtlasDataLocalityUpdaterWatchDog.py +215 -0
  37. pandajedi/jedidog/AtlasProdWatchDog.py +443 -0
  38. pandajedi/jedidog/AtlasQueueFillerWatchDog.py +800 -0
  39. pandajedi/jedidog/AtlasTaskWithholderWatchDog.py +245 -0
  40. pandajedi/jedidog/AtlasWorkflowManagerWatchDog.py +63 -0
  41. pandajedi/jedidog/GenWatchDog.py +21 -0
  42. pandajedi/jedidog/JumboWatchDog.py +147 -0
  43. pandajedi/jedidog/TypicalWatchDogBase.py +122 -0
  44. pandajedi/jedidog/WatchDogBase.py +53 -0
  45. pandajedi/jedidog/__init__.py +0 -0
  46. pandajedi/jediexec/reniceJEDI.py +25 -0
  47. pandajedi/jedigen/AtlasTaskGenerator.py +110 -0
  48. pandajedi/jedigen/TaskGeneratorBase.py +15 -0
  49. pandajedi/jedigen/__init__.py +0 -0
  50. pandajedi/jedimsgprocessor/__init__.py +0 -0
  51. pandajedi/jedimsgprocessor/ai_parameter_adjuster_msg_processor +71 -0
  52. pandajedi/jedimsgprocessor/atlas_idds_msg_processor.py +66 -0
  53. pandajedi/jedimsgprocessor/base_msg_processor.py +33 -0
  54. pandajedi/jedimsgprocessor/forwarding_msg_processor.py +29 -0
  55. pandajedi/jedimsgprocessor/hpo_msg_processor.py +93 -0
  56. pandajedi/jedimsgprocessor/jedi_contents_feeder_msg_processor.py +63 -0
  57. pandajedi/jedimsgprocessor/jedi_job_generator_msg_processor.py +185 -0
  58. pandajedi/jedimsgprocessor/jedi_post_processor_msg_processor.py +82 -0
  59. pandajedi/jedimsgprocessor/kafka_msg_processor.py +44 -0
  60. pandajedi/jedimsgprocessor/panda_callback_msg_processor.py +182 -0
  61. pandajedi/jedimsgprocessor/panda_to_jedi_msg_processor.py +74 -0
  62. pandajedi/jedimsgprocessor/processing_msg_processor.py +134 -0
  63. pandajedi/jedimsgprocessor/status_report_msg_processor.py +129 -0
  64. pandajedi/jedimsgprocessor/tape_carousel_msg_processor.py +118 -0
  65. pandajedi/jedimsgprocessor/workflow_manager_msg_processor.py +89 -0
  66. pandajedi/jediorder/ContentsFeeder.py +785 -0
  67. pandajedi/jediorder/JediDaemon.py +27 -0
  68. pandajedi/jediorder/JediKnight.py +55 -0
  69. pandajedi/jediorder/JediMaster.py +238 -0
  70. pandajedi/jediorder/JediMsgProcessor.py +32 -0
  71. pandajedi/jediorder/JobBroker.py +33 -0
  72. pandajedi/jediorder/JobGenerator.py +2763 -0
  73. pandajedi/jediorder/JobSplitter.py +308 -0
  74. pandajedi/jediorder/JobThrottler.py +28 -0
  75. pandajedi/jediorder/PostProcessor.py +166 -0
  76. pandajedi/jediorder/TaskBroker.py +268 -0
  77. pandajedi/jediorder/TaskCommando.py +334 -0
  78. pandajedi/jediorder/TaskGenerator.py +17 -0
  79. pandajedi/jediorder/TaskRefiner.py +611 -0
  80. pandajedi/jediorder/TaskSetupper.py +17 -0
  81. pandajedi/jediorder/WatchDog.py +79 -0
  82. pandajedi/jediorder/__init__.py +0 -0
  83. pandajedi/jedipprocess/AtlasAnalPostProcessor.py +404 -0
  84. pandajedi/jedipprocess/AtlasPostProcessorUtils.py +50 -0
  85. pandajedi/jedipprocess/AtlasProdPostProcessor.py +178 -0
  86. pandajedi/jedipprocess/GenPostProcessor.py +35 -0
  87. pandajedi/jedipprocess/MailTemplates.py +185 -0
  88. pandajedi/jedipprocess/PostProcessorBase.py +269 -0
  89. pandajedi/jedipprocess/__init__.py +0 -0
  90. pandajedi/jedirefine/AtlasAnalTaskRefiner.py +259 -0
  91. pandajedi/jedirefine/AtlasProdTaskRefiner.py +162 -0
  92. pandajedi/jedirefine/GenTaskRefiner.py +61 -0
  93. pandajedi/jedirefine/RefinerUtils.py +154 -0
  94. pandajedi/jedirefine/TaskRefinerBase.py +996 -0
  95. pandajedi/jedirefine/__init__.py +0 -0
  96. pandajedi/jedisetup/AtlasTaskSetupper.py +309 -0
  97. pandajedi/jedisetup/GenTaskSetupper.py +16 -0
  98. pandajedi/jedisetup/SimpleTaskSetupper.py +152 -0
  99. pandajedi/jedisetup/TaskSetupperBase.py +15 -0
  100. pandajedi/jedisetup/__init__.py +0 -0
  101. pandajedi/jeditest/SchemaChecker.py +41 -0
  102. pandajedi/jeditest/addContWoSoTask.py +54 -0
  103. pandajedi/jeditest/addDataCarouselRequest.py +47 -0
  104. pandajedi/jeditest/addEventServiceTask.py +101 -0
  105. pandajedi/jeditest/addHpoTask.py +81 -0
  106. pandajedi/jeditest/addIDDSStageInRequest.py +56 -0
  107. pandajedi/jeditest/addNonAtlasTask.py +71 -0
  108. pandajedi/jeditest/addNonAtlasTaskEnc.py +64 -0
  109. pandajedi/jeditest/addTestTask.py +124 -0
  110. pandajedi/jeditest/addTestTaskParamToDEFT.py +70 -0
  111. pandajedi/jeditest/addTestTaskWithMerger.py +97 -0
  112. pandajedi/jeditest/brokerTest.py +78 -0
  113. pandajedi/jeditest/cancelDataCarouselRequest.py +35 -0
  114. pandajedi/jeditest/contentsFeederTest.py +28 -0
  115. pandajedi/jeditest/contentsFeederTestWithTask.py +18 -0
  116. pandajedi/jeditest/ddmTest.py +4 -0
  117. pandajedi/jeditest/jobGenForOneTask.py +38 -0
  118. pandajedi/jeditest/jobGeneratorTest.py +43 -0
  119. pandajedi/jeditest/jobSplitterTest.py +104 -0
  120. pandajedi/jeditest/jobThrottlerTest.py +22 -0
  121. pandajedi/jeditest/msgProcessorTest.py +9 -0
  122. pandajedi/jeditest/postProcessorTest.py +18 -0
  123. pandajedi/jeditest/resubmitDataCarouselRequest.py +35 -0
  124. pandajedi/jeditest/resubmitTaskParam.py +20 -0
  125. pandajedi/jeditest/taskBrokerTest.py +22 -0
  126. pandajedi/jeditest/taskBrokerTestWithTask.py +38 -0
  127. pandajedi/jeditest/taskBufferTest.py +5 -0
  128. pandajedi/jeditest/taskCommandoTest.py +28 -0
  129. pandajedi/jeditest/taskRefinerTest.py +30 -0
  130. pandajedi/jeditest/testOneTaskToRefine.py +49 -0
  131. pandajedi/jeditest/testOneTaskToTaskBroker.py +42 -0
  132. pandajedi/jeditest/testPandaDDMMap.py +62 -0
  133. pandajedi/jeditest/updateDataCarouselRequestParams.py +50 -0
  134. pandajedi/jeditest/watchDogTest.py +25 -0
  135. pandajedi/jeditest/workQueueTest.py +22 -0
  136. pandajedi/jedithrottle/AtlasAnalJobThrottler.py +19 -0
  137. pandajedi/jedithrottle/AtlasProdJobThrottler.py +18 -0
  138. pandajedi/jedithrottle/GenJobThrottler.py +26 -0
  139. pandajedi/jedithrottle/JobThrottlerBase.py +496 -0
  140. pandajedi/jedithrottle/__init__.py +0 -0
  141. pandaserver/__init__.py +0 -0
  142. pandaserver/api/__init__.py +0 -0
  143. pandaserver/api/v1/__init__.py +0 -0
  144. pandaserver/api/v1/common.py +339 -0
  145. pandaserver/api/v1/credential_management_api.py +372 -0
  146. pandaserver/api/v1/data_carousel_api.py +264 -0
  147. pandaserver/api/v1/event_api.py +269 -0
  148. pandaserver/api/v1/file_server_api.py +942 -0
  149. pandaserver/api/v1/harvester_api.py +445 -0
  150. pandaserver/api/v1/http_client.py +166 -0
  151. pandaserver/api/v1/idds_api.py +180 -0
  152. pandaserver/api/v1/job_api.py +463 -0
  153. pandaserver/api/v1/metaconfig_api.py +122 -0
  154. pandaserver/api/v1/pilot_api.py +895 -0
  155. pandaserver/api/v1/statistics_api.py +207 -0
  156. pandaserver/api/v1/system_api.py +186 -0
  157. pandaserver/api/v1/task_api.py +1520 -0
  158. pandaserver/api/v1/tests/__init__.py +0 -0
  159. pandaserver/api/v1/tests/credential_management_api_tests.py +116 -0
  160. pandaserver/api/v1/tests/data_carousel_api_tests.py +82 -0
  161. pandaserver/api/v1/tests/harvester_api_tests.py +188 -0
  162. pandaserver/api/v1/tests/idds_api_tests.py +45 -0
  163. pandaserver/api/v1/tests/job_api_tests.py +112 -0
  164. pandaserver/api/v1/tests/pilot_api_tests.py +154 -0
  165. pandaserver/api/v1/tests/statistics_api_tests.py +104 -0
  166. pandaserver/api/v1/tests/system_api_tests.py +58 -0
  167. pandaserver/api/v1/tests/task_api_tests.py +590 -0
  168. pandaserver/api/v1/version.py +2 -0
  169. pandaserver/api/v1/workflow_api.py +136 -0
  170. pandaserver/brokerage/SiteMapper.py +406 -0
  171. pandaserver/brokerage/__init__.py +0 -0
  172. pandaserver/brokerage/broker.py +272 -0
  173. pandaserver/config/__init__.py +0 -0
  174. pandaserver/config/config_utils.py +15 -0
  175. pandaserver/config/daemon_config.py +29 -0
  176. pandaserver/config/mcp_config.py +38 -0
  177. pandaserver/config/panda_config.py +233 -0
  178. pandaserver/configurator/Carbon.py +65 -0
  179. pandaserver/configurator/Configurator.py +908 -0
  180. pandaserver/configurator/__init__.py +0 -0
  181. pandaserver/configurator/aux.py +73 -0
  182. pandaserver/daemons/__init__.py +0 -0
  183. pandaserver/daemons/master.py +110 -0
  184. pandaserver/daemons/master_systemd.py +79 -0
  185. pandaserver/daemons/scripts/__init__.py +0 -0
  186. pandaserver/daemons/scripts/add_main.py +264 -0
  187. pandaserver/daemons/scripts/add_sub.py +221 -0
  188. pandaserver/daemons/scripts/cache_pilots.py +47 -0
  189. pandaserver/daemons/scripts/cache_schedconfig.py +286 -0
  190. pandaserver/daemons/scripts/carbon.py +50 -0
  191. pandaserver/daemons/scripts/configurator.py +94 -0
  192. pandaserver/daemons/scripts/copyArchive.py +1387 -0
  193. pandaserver/daemons/scripts/datasetManager.py +1154 -0
  194. pandaserver/daemons/scripts/dummy_test.py +25 -0
  195. pandaserver/daemons/scripts/evpPD2P.py +144 -0
  196. pandaserver/daemons/scripts/hs_scrapers.py +264 -0
  197. pandaserver/daemons/scripts/metric_collector.py +927 -0
  198. pandaserver/daemons/scripts/panda_activeusers_query.py +80 -0
  199. pandaserver/daemons/scripts/pilotStreaming.py +109 -0
  200. pandaserver/daemons/scripts/process_workflow_files_daemon.py +166 -0
  201. pandaserver/daemons/scripts/recover_lost_files_daemon.py +177 -0
  202. pandaserver/daemons/scripts/task_evaluator.py +405 -0
  203. pandaserver/daemons/scripts/tmpwatch.py +70 -0
  204. pandaserver/daemons/scripts/worker_synchronization.py +97 -0
  205. pandaserver/daemons/utils.py +753 -0
  206. pandaserver/dataservice/DataServiceUtils.py +323 -0
  207. pandaserver/dataservice/ErrorCode.py +25 -0
  208. pandaserver/dataservice/RecoverLostFilesCore.py +322 -0
  209. pandaserver/dataservice/__init__.py +0 -0
  210. pandaserver/dataservice/activator.py +79 -0
  211. pandaserver/dataservice/adder_atlas_plugin.py +1106 -0
  212. pandaserver/dataservice/adder_dummy_plugin.py +31 -0
  213. pandaserver/dataservice/adder_gen.py +954 -0
  214. pandaserver/dataservice/adder_plugin_base.py +27 -0
  215. pandaserver/dataservice/adder_result.py +75 -0
  216. pandaserver/dataservice/adder_simple_plugin.py +160 -0
  217. pandaserver/dataservice/closer.py +247 -0
  218. pandaserver/dataservice/closer_atlas_plugin.py +90 -0
  219. pandaserver/dataservice/ddm.py +1381 -0
  220. pandaserver/dataservice/ddm_handler.py +95 -0
  221. pandaserver/dataservice/dyn_data_distributer.py +824 -0
  222. pandaserver/dataservice/event_lookup_client_ei.py +77 -0
  223. pandaserver/dataservice/event_picker.py +268 -0
  224. pandaserver/dataservice/finisher.py +194 -0
  225. pandaserver/dataservice/setupper.py +225 -0
  226. pandaserver/dataservice/setupper_atlas_plugin.py +1851 -0
  227. pandaserver/dataservice/setupper_dummy_plugin.py +47 -0
  228. pandaserver/dataservice/setupper_plugin_base.py +67 -0
  229. pandaserver/jobdispatcher/DispatcherUtils.py +35 -0
  230. pandaserver/jobdispatcher/ErrorCode.py +19 -0
  231. pandaserver/jobdispatcher/JobDispatcher.py +1625 -0
  232. pandaserver/jobdispatcher/Protocol.py +443 -0
  233. pandaserver/jobdispatcher/Watcher.py +186 -0
  234. pandaserver/jobdispatcher/__init__.py +0 -0
  235. pandaserver/pandamcp/__init__.py +0 -0
  236. pandaserver/pandamcp/mcp_main.py +56 -0
  237. pandaserver/pandamcp/mcp_test_client.py +95 -0
  238. pandaserver/pandamcp/mcp_utils.py +74 -0
  239. pandaserver/proxycache/__init__.py +0 -0
  240. pandaserver/proxycache/panda_proxy_cache.py +240 -0
  241. pandaserver/proxycache/token_cache.py +141 -0
  242. pandaserver/server/.gacl +6 -0
  243. pandaserver/server/panda.py +539 -0
  244. pandaserver/srvcore/CoreUtils.py +572 -0
  245. pandaserver/srvcore/MailUtils.py +106 -0
  246. pandaserver/srvcore/__init__.py +0 -0
  247. pandaserver/srvcore/allowed_methods.py +100 -0
  248. pandaserver/srvcore/oidc_utils.py +152 -0
  249. pandaserver/srvcore/panda_request.py +196 -0
  250. pandaserver/srvcore/srv_msg_utils.py +42 -0
  251. pandaserver/taskbuffer/ConBridge.py +513 -0
  252. pandaserver/taskbuffer/DBProxyPool.py +95 -0
  253. pandaserver/taskbuffer/DataCarousel.py +3053 -0
  254. pandaserver/taskbuffer/DatasetSpec.py +137 -0
  255. pandaserver/taskbuffer/DdmSpec.py +201 -0
  256. pandaserver/taskbuffer/ErrorCode.py +87 -0
  257. pandaserver/taskbuffer/EventServiceUtils.py +396 -0
  258. pandaserver/taskbuffer/FileSpec.py +290 -0
  259. pandaserver/taskbuffer/GlobalShares.py +244 -0
  260. pandaserver/taskbuffer/HarvesterMetricsSpec.py +92 -0
  261. pandaserver/taskbuffer/Initializer.py +82 -0
  262. pandaserver/taskbuffer/InputChunk.py +1080 -0
  263. pandaserver/taskbuffer/JediCacheSpec.py +57 -0
  264. pandaserver/taskbuffer/JediDatasetSpec.py +588 -0
  265. pandaserver/taskbuffer/JediFileSpec.py +242 -0
  266. pandaserver/taskbuffer/JediTaskSpec.py +1687 -0
  267. pandaserver/taskbuffer/JobSpec.py +1006 -0
  268. pandaserver/taskbuffer/JobUtils.py +232 -0
  269. pandaserver/taskbuffer/NucleusSpec.py +116 -0
  270. pandaserver/taskbuffer/OraDBProxy.py +174 -0
  271. pandaserver/taskbuffer/PanDAMsgProcessor.py +8 -0
  272. pandaserver/taskbuffer/PandaDBSchemaInfo.py +18 -0
  273. pandaserver/taskbuffer/ParseJobXML.py +350 -0
  274. pandaserver/taskbuffer/PickleFileSpec.py +18 -0
  275. pandaserver/taskbuffer/PickleJobSpec.py +25 -0
  276. pandaserver/taskbuffer/PrioUtil.py +40 -0
  277. pandaserver/taskbuffer/ProcessGroups.py +111 -0
  278. pandaserver/taskbuffer/ResourceSpec.py +175 -0
  279. pandaserver/taskbuffer/SQLDumper.py +37 -0
  280. pandaserver/taskbuffer/SQLManager.py +60 -0
  281. pandaserver/taskbuffer/SiteSpec.py +304 -0
  282. pandaserver/taskbuffer/SupErrors.py +10 -0
  283. pandaserver/taskbuffer/TaskBuffer.py +2882 -0
  284. pandaserver/taskbuffer/TaskBufferInterface.py +163 -0
  285. pandaserver/taskbuffer/Utils.py +848 -0
  286. pandaserver/taskbuffer/WorkQueue.py +227 -0
  287. pandaserver/taskbuffer/WorkQueueMapper.py +203 -0
  288. pandaserver/taskbuffer/WorkerSpec.py +143 -0
  289. pandaserver/taskbuffer/WrappedCursor.py +487 -0
  290. pandaserver/taskbuffer/WrappedPickle.py +88 -0
  291. pandaserver/taskbuffer/WrappedPostgresConn.py +24 -0
  292. pandaserver/taskbuffer/__init__.py +0 -0
  293. pandaserver/taskbuffer/db_proxy_mods/OraDBProxy_structure.png +0 -0
  294. pandaserver/taskbuffer/db_proxy_mods/__init__.py +7 -0
  295. pandaserver/taskbuffer/db_proxy_mods/base_module.py +841 -0
  296. pandaserver/taskbuffer/db_proxy_mods/data_carousel_module.py +772 -0
  297. pandaserver/taskbuffer/db_proxy_mods/entity_module.py +3804 -0
  298. pandaserver/taskbuffer/db_proxy_mods/job_complex_module.py +5661 -0
  299. pandaserver/taskbuffer/db_proxy_mods/job_standalone_module.py +2640 -0
  300. pandaserver/taskbuffer/db_proxy_mods/metrics_module.py +874 -0
  301. pandaserver/taskbuffer/db_proxy_mods/misc_standalone_module.py +4272 -0
  302. pandaserver/taskbuffer/db_proxy_mods/task_complex_module.py +6172 -0
  303. pandaserver/taskbuffer/db_proxy_mods/task_event_module.py +4953 -0
  304. pandaserver/taskbuffer/db_proxy_mods/task_standalone_module.py +4999 -0
  305. pandaserver/taskbuffer/db_proxy_mods/task_utils_module.py +2063 -0
  306. pandaserver/taskbuffer/db_proxy_mods/worker_module.py +1944 -0
  307. pandaserver/taskbuffer/db_proxy_mods/workflow_module.py +832 -0
  308. pandaserver/taskbuffer/retryModule.py +552 -0
  309. pandaserver/taskbuffer/task_split_rules.py +308 -0
  310. pandaserver/taskbuffer/workflow_processor.py +249 -0
  311. pandaserver/taskbuffer/wrapped_oracle_conn.py +18 -0
  312. pandaserver/test/SchemaChecker.py +40 -0
  313. pandaserver/test/__init__.py +0 -0
  314. pandaserver/test/banUser.py +43 -0
  315. pandaserver/test/boostPrio.py +19 -0
  316. pandaserver/test/boostUser.py +35 -0
  317. pandaserver/test/callbackDDM.py +11 -0
  318. pandaserver/test/daod_on_demand.py +95 -0
  319. pandaserver/test/finishJob.py +184 -0
  320. pandaserver/test/finishTaskJEDI.py +11 -0
  321. pandaserver/test/getJobs.py +53 -0
  322. pandaserver/test/killJob.py +79 -0
  323. pandaserver/test/killJobLowPrio.py +99 -0
  324. pandaserver/test/killJobsInTask.py +56 -0
  325. pandaserver/test/killTask.py +80 -0
  326. pandaserver/test/killTaskJEDI.py +11 -0
  327. pandaserver/test/killUser.py +83 -0
  328. pandaserver/test/lsst/README.txt +7 -0
  329. pandaserver/test/lsst/lsstSubmit.py +139 -0
  330. pandaserver/test/lsst/lsstSubmitMERGEtest.py +141 -0
  331. pandaserver/test/lsst/lsstSubmitPhosim332.py +53 -0
  332. pandaserver/test/lsst/prepare-client-tarball-from-bigpanda-server.sh +41 -0
  333. pandaserver/test/reassignJobs.py +17 -0
  334. pandaserver/test/reassignSite.py +82 -0
  335. pandaserver/test/reassignTask.py +117 -0
  336. pandaserver/test/reassignWaiting.py +39 -0
  337. pandaserver/test/recoverLostFiles.py +7 -0
  338. pandaserver/test/reloadInputDS.py +51 -0
  339. pandaserver/test/sendCommandToJob.py +26 -0
  340. pandaserver/test/setDebugMode.py +38 -0
  341. pandaserver/test/setPriority.py +28 -0
  342. pandaserver/test/testEvgen.py +60 -0
  343. pandaserver/test/testEvgen17.py +58 -0
  344. pandaserver/test/testG4sim.py +81 -0
  345. pandaserver/test/testG4sim17.py +90 -0
  346. pandaserver/test/testGlobalShares.py +131 -0
  347. pandaserver/test/testReco.py +103 -0
  348. pandaserver/test/testSimulReco14.py +98 -0
  349. pandaserver/test/testSiteMap.py +26 -0
  350. pandaserver/test/testUpdateWorkerPilotStatus.py +9 -0
  351. pandaserver/userinterface/Client.py +1686 -0
  352. pandaserver/userinterface/UserIF.py +1799 -0
  353. pandaserver/userinterface/__init__.py +0 -0
  354. pandaserver/workflow/__init__.py +0 -0
  355. pandaserver/workflow/data_handler_plugins/base_data_handler.py +48 -0
  356. pandaserver/workflow/data_handler_plugins/ddm_collection_data_handler.py +100 -0
  357. pandaserver/workflow/data_handler_plugins/panda_task_data_handler.py +140 -0
  358. pandaserver/workflow/pcwl_test.py +122 -0
  359. pandaserver/workflow/pcwl_utils.py +384 -0
  360. pandaserver/workflow/psnakemake_container.json +68 -0
  361. pandaserver/workflow/psnakemake_task.json +62 -0
  362. pandaserver/workflow/psnakemake_test.py +60 -0
  363. pandaserver/workflow/snakeparser/__init__.py +3 -0
  364. pandaserver/workflow/snakeparser/extensions.py +74 -0
  365. pandaserver/workflow/snakeparser/log.py +53 -0
  366. pandaserver/workflow/snakeparser/names.py +3 -0
  367. pandaserver/workflow/snakeparser/parser.py +332 -0
  368. pandaserver/workflow/snakeparser/utils.py +29 -0
  369. pandaserver/workflow/step_handler_plugins/base_step_handler.py +85 -0
  370. pandaserver/workflow/step_handler_plugins/panda_task_step_handler.py +280 -0
  371. pandaserver/workflow/workflow_base.py +531 -0
  372. pandaserver/workflow/workflow_core.py +1974 -0
  373. pandaserver/workflow/workflow_core_smoketest.py +388 -0
  374. pandaserver/workflow/workflow_parser.py +222 -0
  375. pandaserver/workflow/workflow_utils.py +1047 -0
@@ -0,0 +1,27 @@
1
+ """
2
+ The Adder module is the core for add_main to post-process jobs’ output data, such as data registration, trigger data aggregation and so on.
3
+ Those post-processing procedures are experiment-dependent so that the Adder also has a plugin structure to load an experiment-specific plugin.
4
+
5
+ """
6
+
7
+ from .adder_result import AdderResult
8
+
9
+
10
+ class AdderPluginBase:
11
+ """
12
+ Base class for Adder plugins.
13
+ """
14
+
15
+ def __init__(self, job, params):
16
+ """
17
+ Initialize the AdderPluginBase.
18
+
19
+ :param job: The job object.
20
+ :param params: Additional parameters.
21
+ """
22
+ self.job = job
23
+ self.logger = None
24
+ self.result = AdderResult()
25
+ self.extra_info = {}
26
+ for key, value in params.items():
27
+ setattr(self, key, value)
@@ -0,0 +1,75 @@
1
+ """
2
+ Class to represent the result of the Adder operation
3
+
4
+ """
5
+
6
+ class AdderResult:
7
+ """
8
+ Class to represent the result of the Adder operation.
9
+ """
10
+ # slot
11
+ __slot__ = ("statusCode", "transferringFiles")
12
+
13
+ # return code
14
+ rc_succeeded = 0
15
+ rc_temporary = 1
16
+ rc_fatal = 2
17
+
18
+ # constructor
19
+ def __init__(self) -> None:
20
+ """
21
+ Initialize the AdderResult with default values.
22
+ """
23
+ # result of interactions with data management system (DMS)
24
+ self.status_code = None
25
+
26
+ # list of files which are being transferred by DMS
27
+ self.transferring_files = []
28
+
29
+ # list of files which are being merged
30
+ self.merging_files = []
31
+
32
+ # succeeded
33
+ def set_succeeded(self):
34
+ """
35
+ Set the status to succeeded.
36
+ """
37
+ self.status_code = self.rc_succeeded
38
+
39
+ # temporary error to retry later
40
+ def set_temporary(self):
41
+ """
42
+ Set the status to temporary error.
43
+ """
44
+ self.status_code = self.rc_temporary
45
+
46
+ # fatal error
47
+ def set_fatal(self):
48
+ """
49
+ Set the status to fatal.
50
+ """
51
+ self.status_code = self.rc_fatal
52
+
53
+ # check if succeeded
54
+ def is_succeeded(self):
55
+ """
56
+ Check if the status is 'succeeded'.
57
+ True if status is 'succeeded', False otherwise.
58
+ """
59
+ return self.status_code == self.rc_succeeded
60
+
61
+ # check if temporary
62
+ def is_temporary(self):
63
+ """
64
+ Check if the status is 'temporary'.
65
+ True if status is 'temporary', False otherwise.
66
+ """
67
+ return self.status_code == self.rc_temporary
68
+
69
+ # check if fatal error
70
+ def is_fatal(self):
71
+ """
72
+ Check if the status is 'fatal'.
73
+ True if status is 'fatal', False otherwise.
74
+ """
75
+ return self.status_code == self.rc_fatal
@@ -0,0 +1,160 @@
1
+ """
2
+ Simple plugin of Adder for VOs with Rucio
3
+
4
+ """
5
+
6
+ import datetime
7
+ import time
8
+ import traceback
9
+ import uuid
10
+
11
+ from pandacommon.pandautils.PandaUtils import naive_utcnow
12
+ from rucio.common.exception import (
13
+ DataIdentifierNotFound,
14
+ FileConsistencyMismatch,
15
+ InvalidObject,
16
+ InvalidPath,
17
+ InvalidRSEExpression,
18
+ RSEFileNameNotSupported,
19
+ RSENotFound,
20
+ RSEProtocolNotSupported,
21
+ UnsupportedOperation,
22
+ )
23
+
24
+ from pandaserver.dataservice import DataServiceUtils, ErrorCode
25
+ from pandaserver.dataservice.ddm import rucioAPI
26
+
27
+ from .adder_plugin_base import AdderPluginBase
28
+
29
+
30
+ class AdderSimplePlugin(AdderPluginBase):
31
+ """
32
+ Simple plugin of Adder for VOs with Rucio.
33
+ """
34
+
35
+ # constructor
36
+ def __init__(self, job, **params) -> None:
37
+ """
38
+ Initialize the AdderSimplePlugin.
39
+
40
+ :param job: The job object.
41
+ :param params: Additional parameters.
42
+ """
43
+ AdderPluginBase.__init__(self, job, params)
44
+
45
+ # main
46
+ def execute(self) -> None:
47
+ """
48
+ Execute the simple adder plugin.
49
+
50
+ :return: None
51
+ """
52
+ try:
53
+ # loop over all files
54
+ file_map = {}
55
+ for file_spec in self.job.Files:
56
+ # ignore inputs
57
+ if file_spec.type not in ["output", "log"]:
58
+ continue
59
+ # ignore local
60
+ if file_spec.destinationSE == "local":
61
+ continue
62
+ # collect file attributes
63
+ try:
64
+ file_size = int(file_spec.fsize)
65
+ except Exception:
66
+ file_size = None
67
+ # set GUID if empty
68
+ if not file_spec.GUID:
69
+ file_spec.GUID = str(uuid.uuid4())
70
+ file_attrs = {
71
+ "guid": file_spec.GUID,
72
+ "lfn": file_spec.lfn,
73
+ "size": file_size,
74
+ "checksum": file_spec.checksum,
75
+ "ds": file_spec.destinationDBlock,
76
+ }
77
+ if self.extra_info:
78
+ if "surl" in self.extra_info and file_spec.lfn in self.extra_info["surl"]:
79
+ file_attrs["surl"] = self.extra_info["surl"][file_spec.lfn]
80
+ if "nevents" in self.extra_info and file_spec.lfn in self.extra_info["nevents"]:
81
+ file_attrs["events"] = self.extra_info["nevents"][file_spec.lfn]
82
+ file_map.setdefault(file_spec.destinationDBlock, [])
83
+ file_map[file_spec.destinationDBlock].append(file_attrs)
84
+ # register files
85
+ if file_map:
86
+ destination_rse = self.siteMapper.getSite(self.job.computingSite).ddm_output["default"]
87
+ destination_id_map = {destination_rse: file_map}
88
+ max_attempt = 3
89
+ for attempt_number in range(max_attempt):
90
+ is_fatal = False
91
+ is_failed = False
92
+ registration_start = naive_utcnow()
93
+ try:
94
+ self.logger.debug(f"registerFilesInDatasets {str(destination_id_map)}")
95
+ out = rucioAPI.register_files_in_dataset(destination_id_map, {})
96
+ except (
97
+ DataIdentifierNotFound,
98
+ FileConsistencyMismatch,
99
+ UnsupportedOperation,
100
+ InvalidPath,
101
+ InvalidObject,
102
+ RSENotFound,
103
+ RSEProtocolNotSupported,
104
+ InvalidRSEExpression,
105
+ RSEFileNameNotSupported,
106
+ KeyError,
107
+ ) as e:
108
+ # fatal errors
109
+ out = f"failed with {str(e)}\n {traceback.format_exc()}"
110
+ is_fatal = True
111
+ is_failed = True
112
+ except Exception as e:
113
+ # unknown errors
114
+ is_failed = True
115
+ out = f"failed with unknown error: {str(e)}\n {traceback.format_exc()}"
116
+ if (
117
+ "value too large for column" in out
118
+ or "unique constraint (ATLAS_RUCIO.DIDS_GUID_IDX) violate" in out
119
+ or "unique constraint (ATLAS_RUCIO.DIDS_PK) violated" in out
120
+ or "unique constraint (ATLAS_RUCIO.ARCH_CONTENTS_PK) violated" in out
121
+ ):
122
+ is_fatal = True
123
+ else:
124
+ is_fatal = False
125
+ registration_time = naive_utcnow() - registration_start
126
+ self.logger.debug("took %s.%03d sec" % (registration_time.seconds, registration_time.microseconds / 1000))
127
+
128
+ # failed
129
+ if is_failed or is_fatal:
130
+ self.logger.error(f"{out}")
131
+ if (attempt_number + 1) == max_attempt or is_fatal:
132
+ self.job.ddmErrorCode = ErrorCode.EC_Adder
133
+ # extract important error string
134
+ extracted_error = DataServiceUtils.extractImportantError(out)
135
+ err_msg = "Could not add files to DDM: "
136
+ if extracted_error == "":
137
+ self.job.ddmErrorDiag = err_msg + out.split("\n")[-1]
138
+ else:
139
+ self.job.ddmErrorDiag = err_msg + extracted_error
140
+ if is_fatal:
141
+ self.result.set_fatal()
142
+ else:
143
+ self.result.set_temporary()
144
+ return
145
+ self.logger.error(f"Try:{attempt_number}")
146
+ # sleep
147
+ time.sleep(10)
148
+ else:
149
+ self.logger.debug(f"{str(out)}")
150
+ break
151
+ # done
152
+ self.result.set_succeeded()
153
+ self.logger.debug("end plugin")
154
+ except Exception as e:
155
+ err_str = f"failed to execute with {str(e)}\n"
156
+ err_str += traceback.format_exc()
157
+ self.logger.error(err_str)
158
+ self.result.set_temporary()
159
+ # return
160
+ return
@@ -0,0 +1,247 @@
1
+ """
2
+ update dataset DB, and then close dataset and start Activator if needed
3
+
4
+ """
5
+
6
+ import datetime
7
+ import sys
8
+ from typing import Dict, List
9
+
10
+ from pandacommon.pandalogger.LogWrapper import LogWrapper
11
+ from pandacommon.pandalogger.PandaLogger import PandaLogger
12
+ from pandacommon.pandautils.PandaUtils import naive_utcnow
13
+
14
+ from pandaserver.config import panda_config
15
+ from pandaserver.dataservice import DataServiceUtils
16
+ from pandaserver.dataservice.activator import Activator
17
+ from pandaserver.taskbuffer import EventServiceUtils
18
+
19
+ # logger
20
+ _logger = PandaLogger().getLogger("closer")
21
+
22
+
23
+ class Closer:
24
+ """
25
+ Update dataset DB, and then close dataset and start Activator if needed.
26
+ The class updates output-related dataset records (_sub, output, and log) in
27
+ the database, closes _sub datasets if necessary, and activates downstream
28
+ runJobs if the output dataset is for buildJob (libDS, library dataset).
29
+ Activator changes job status from defined/assigned to activated.
30
+ """
31
+
32
+ # constructor
33
+ def __init__(self, taskBuffer, destination_data_blocks: List[str], job, dataset_map: Dict = None) -> None:
34
+ """
35
+ Constructor
36
+
37
+ Args:
38
+ taskBuffer: Task buffer.
39
+ destination_data_blocks (List[str]): Destination Dispatch blocks.
40
+ job: Job.
41
+ dataset_map (Dict, optional): Dataset map. Defaults to {}.
42
+ """
43
+ self.task_buffer = taskBuffer
44
+ self.destination_data_blocks = destination_data_blocks
45
+ self.job = job
46
+ self.panda_id = job.PandaID
47
+ self.site_mapper = None
48
+ self.dataset_map = dataset_map if dataset_map is not None else {}
49
+ self.all_subscription_finished = None
50
+
51
+ def check_sub_datasets_in_jobset(self) -> bool:
52
+ """
53
+ Check sub datasets with the same jobset
54
+
55
+ Returns:
56
+ bool: True if all sub datasets are done, False otherwise.
57
+ """
58
+ tmp_log = LogWrapper(_logger, f"check_sub_datasets_in_jobset-{naive_utcnow().isoformat('/')}")
59
+ # skip already checked
60
+ if self.all_subscription_finished is not None:
61
+ return self.all_subscription_finished
62
+ # get consumers in the jobset
63
+ jobs = self.task_buffer.getOriginalConsumers(self.job.jediTaskID, self.job.jobsetID, self.job.panda_id)
64
+ checked_dataset = set()
65
+ for job_spec in jobs:
66
+ # collect all sub datasets
67
+ sub_datasets = set()
68
+ for file_spec in job_spec.Files:
69
+ if file_spec.type == "output":
70
+ sub_datasets.add(file_spec.destinationDBlock)
71
+ sub_datasets = sorted(sub_datasets)
72
+ if len(sub_datasets) > 0:
73
+ # use the first sub dataset
74
+ sub_dataset = sub_datasets[0]
75
+ # skip if already checked
76
+ if sub_dataset in checked_dataset:
77
+ continue
78
+ checked_dataset.add(sub_dataset)
79
+ # count the number of unfinished
80
+ not_finish = self.task_buffer.countFilesWithMap({"destinationDBlock": sub_dataset, "status": "unknown"})
81
+ if not_finish != 0:
82
+ tmp_log.debug(f"related sub dataset {sub_dataset} from {job_spec.PandaID} has {not_finish} unfinished files")
83
+ self.all_subscription_finished = False
84
+ break
85
+ if self.all_subscription_finished is None:
86
+ tmp_log.debug("all related sub datasets are done")
87
+ self.all_subscription_finished = True
88
+ return self.all_subscription_finished
89
+
90
+ def determine_final_status(self, destination_data_block: str) -> str:
91
+ """
92
+ Determine the final status of a dispatch block.
93
+
94
+ Args:
95
+ destination_data_block (str): The destination dispatch block.
96
+
97
+ Returns:
98
+ str: The final status.
99
+ """
100
+ # for queues without rucio storage element attached
101
+ if self.job.destinationSE == "local" and self.job.prodSourceLabel in ["user", "panda"]:
102
+ # close non-Rucio destinationDBlock immediately
103
+ return "closed"
104
+ if self.job.lockedby == "jedi" and DataServiceUtils.is_top_level_dataset(destination_data_block):
105
+ # set it closed in order not to trigger DDM cleanup. It will be closed by JEDI
106
+ return "closed"
107
+ if self.job.produceUnMerge():
108
+ return "doing"
109
+
110
+ # set status to 'tobeclosed' to trigger Rucio closing
111
+ return "tobeclosed"
112
+
113
+ def perform_vo_actions(self, final_status_dataset: list) -> None:
114
+ """
115
+ Perform special actions for vo.
116
+
117
+ Args:
118
+ final_status_dataset (list): The final status dataset.
119
+ """
120
+ closer_plugin_class = panda_config.getPlugin("closer_plugins", self.job.VO)
121
+ if closer_plugin_class is None and self.job.VO == "atlas":
122
+ # use ATLAS plugin for ATLAS
123
+ from pandaserver.dataservice.closer_atlas_plugin import CloserAtlasPlugin
124
+
125
+ closer_plugin_class = CloserAtlasPlugin
126
+ if closer_plugin_class is not None:
127
+ closer_plugin = closer_plugin_class(self.job, final_status_dataset, _logger)
128
+ closer_plugin.execute()
129
+
130
+ def start_activator(self, dataset):
131
+ """
132
+ Start the activator
133
+
134
+ Args:
135
+ dataset: Dataset.
136
+ final_status (str): Final status.
137
+ """
138
+ # start Activator
139
+ if (
140
+ not DataServiceUtils.is_sub_dataset(dataset.name)
141
+ and self.job.jobStatus == "finished"
142
+ and (self.job.prodSourceLabel != "panda" or self.job.processingType not in ["merge", "unmerge"])
143
+ ):
144
+ activator_thread = Activator(self.task_buffer, dataset)
145
+ activator_thread.run()
146
+
147
+ # main
148
+ def run(self):
149
+ """
150
+ Main method to run the Closer class. It processes each destination dispatch block,
151
+ updates the dataset status and finalizes pending jobs if necessary.
152
+ """
153
+ try:
154
+ tmp_log = LogWrapper(_logger, f"run-{naive_utcnow().isoformat('/')}-{self.panda_id}")
155
+ tmp_log.debug(f"Start with job status: {self.job.jobStatus}")
156
+ flag_complete = True
157
+ final_status_dataset = []
158
+
159
+ for destination_data_block in self.destination_data_blocks:
160
+ dataset_list = []
161
+ tmp_log.debug(f"start with destination dispatch block: {destination_data_block}")
162
+
163
+ # ignore task output datasets (tid) datasets
164
+ if DataServiceUtils.is_tid_dataset(destination_data_block):
165
+ tmp_log.debug(f"skip {destination_data_block}")
166
+ continue
167
+
168
+ # ignore HC datasets
169
+ if DataServiceUtils.is_hammercloud_dataset(destination_data_block) or DataServiceUtils.is_user_gangarbt_dataset(destination_data_block):
170
+ if not DataServiceUtils.is_sub_dataset(destination_data_block) and not DataServiceUtils.is_lib_dataset(destination_data_block):
171
+ tmp_log.debug(f"skip HC {destination_data_block}")
172
+ continue
173
+
174
+ # query dataset
175
+ if destination_data_block in self.dataset_map:
176
+ dataset = self.dataset_map[destination_data_block]
177
+ else:
178
+ dataset = self.task_buffer.queryDatasetWithMap({"name": destination_data_block})
179
+
180
+ if dataset is None:
181
+ tmp_log.error(f"Not found : {destination_data_block}")
182
+ flag_complete = False
183
+ continue
184
+
185
+ # skip tobedeleted/tobeclosed
186
+ if dataset.status in ["cleanup", "tobeclosed", "completed", "deleted"]:
187
+ tmp_log.debug(f"skip {destination_data_block} due to dataset status: {dataset.status}")
188
+ continue
189
+
190
+ dataset_list.append(dataset)
191
+ dataset_list.sort()
192
+
193
+ # count number of completed files
194
+ not_finish = self.task_buffer.countFilesWithMap({"destinationDBlock": destination_data_block, "status": "unknown"})
195
+ if not_finish < 0:
196
+ tmp_log.error(f"Invalid dispatch block file count: {not_finish}")
197
+ flag_complete = False
198
+ continue
199
+
200
+ # check if completed
201
+ tmp_log.debug(f"Pending file count: {not_finish}")
202
+ final_status = self.determine_final_status(destination_data_block)
203
+
204
+ if not_finish == 0 and EventServiceUtils.isEventServiceMerge(self.job):
205
+ all_in_jobset_finished = self.check_sub_datasets_in_jobset()
206
+ else:
207
+ all_in_jobset_finished = True
208
+
209
+ if not_finish == 0 and all_in_jobset_finished:
210
+ tmp_log.debug(f"Set final status: {final_status} to dataset: {destination_data_block}")
211
+ # set status
212
+ dataset.status = final_status
213
+ # update dataset in DB
214
+ ret_t = self.task_buffer.updateDatasets(
215
+ dataset_list,
216
+ withLock=True,
217
+ withCriteria="status<>:crStatus AND status<>:lockStatus ",
218
+ criteriaMap={":crStatus": final_status, ":lockStatus": "locked"},
219
+ )
220
+ if len(ret_t) > 0 and ret_t[0] == 1:
221
+ final_status_dataset += dataset_list
222
+ self.start_activator(dataset)
223
+ else:
224
+ # update dataset in DB
225
+ self.task_buffer.updateDatasets(
226
+ dataset_list,
227
+ withLock=True,
228
+ withCriteria="status<>:crStatus AND status<>:lockStatus ",
229
+ criteriaMap={":crStatus": final_status, ":lockStatus": "locked"},
230
+ )
231
+ # unset flag
232
+ flag_complete = False
233
+ # end
234
+ tmp_log.debug(f"end {destination_data_block}")
235
+ # special actions for vo
236
+ if flag_complete:
237
+ self.perform_vo_actions(final_status_dataset)
238
+
239
+ # update unmerged datasets in JEDI to trigger merging
240
+ if flag_complete and self.job.produceUnMerge() and final_status_dataset:
241
+ tmp_stat = self.task_buffer.updateUnmergedDatasets(self.job, final_status_dataset)
242
+ tmp_log.debug(f"updated unmerged datasets with {tmp_stat}")
243
+
244
+ tmp_log.debug("End")
245
+ except Exception:
246
+ err_type, err_value = sys.exc_info()[:2]
247
+ tmp_log.error(f"{err_type} {err_value}")
@@ -0,0 +1,90 @@
1
+ """
2
+ ATLAS plugin for closer
3
+ """
4
+ import sys
5
+
6
+ from pandacommon.pandalogger.LogWrapper import LogWrapper
7
+ from pandaserver.dataservice.ddm import rucioAPI
8
+ from pandaserver.dataservice import DataServiceUtils
9
+
10
+
11
+ # plugin for ATLAS closer
12
+ class CloserAtlasPlugin:
13
+ """
14
+ A class used to represent the ATLAS closer plugin.
15
+
16
+ ...
17
+
18
+ Attributes
19
+ ----------
20
+ jobSpec : object
21
+ an object representing the job specification
22
+ datasets : list
23
+ a list of datasets to be processed
24
+ tmp_log : LogWrapper
25
+ a LogWrapper object for logging
26
+
27
+ Methods
28
+ -------
29
+ __init__(self, job, datasets, log)
30
+ Constructs all the necessary attributes for the CloserAtlasPlugin object.
31
+ execute(self)
32
+ Executes the plugin's main functionality.
33
+ """
34
+
35
+ # constructor
36
+ def __init__(self, job, datasets, log):
37
+ """
38
+ Constructs all the necessary attributes for the CloserAtlasPlugin object.
39
+
40
+ Parameters
41
+ ----------
42
+ job : object
43
+ an object representing the job specification
44
+ datasets : list
45
+ a list of datasets to be processed
46
+ log : LogWrapper
47
+ a LogWrapper object for logging
48
+ """
49
+ self.jobSpec = job
50
+ self.datasets = datasets
51
+ self.tmp_log = LogWrapper(log, f"{self.jobSpec.PandaID} CloserAtlasPlugin")
52
+
53
+ # execute
54
+ def execute(self):
55
+ """
56
+ Executes the main functionality of the CloserAtlasPlugin.
57
+
58
+ This method is responsible for closing datasets that meet certain criteria.
59
+ It only operates on production jobs that are either 'urgent' or have a high priority.
60
+ For each dataset in the job, if the dataset's name ends with '_sub' followed by a number and its status is 'tobeclosed',
61
+ it attempts to close the dataset using the rucioAPI. If an error occurs during this process, it logs a warning message.
62
+
63
+ Returns
64
+ -------
65
+ bool
66
+ Always returns True regardless of whether the datasets were successfully closed or not.
67
+ """
68
+ try:
69
+ # only for production
70
+ if self.jobSpec.prodSourceLabel not in ["managed", "test"]:
71
+ return True
72
+ # only for urgent or high prio
73
+ if self.jobSpec.processingType not in ["urgent"] and self.jobSpec.currentPriority <= 1000:
74
+ return True
75
+ # close datasets
76
+ for datasetSpec in self.datasets:
77
+ if not DataServiceUtils.is_sub_dataset(datasetSpec.name):
78
+ continue
79
+ if datasetSpec.status != "tobeclosed":
80
+ continue
81
+ try:
82
+ self.tmp_log.debug(f"immediate close {datasetSpec.name}")
83
+ rucioAPI.close_dataset(datasetSpec.name)
84
+ except Exception:
85
+ errtype, errvalue = sys.exc_info()[:2]
86
+ self.tmp_log.warning(f"failed to close : {errtype} {errvalue}")
87
+ except Exception:
88
+ errtype, errvalue = sys.exc_info()[:2]
89
+ self.tmp_log.warning(f"failed to execute : {errtype} {errvalue}")
90
+ return True