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,182 @@
1
+ import sys
2
+
3
+ from .MsgWrapper import MsgWrapper
4
+
5
+ _factoryModuleName = __name__.split(".")[-1]
6
+
7
+
8
+ # base class for factory
9
+ class FactoryBase:
10
+ # constructor
11
+ def __init__(self, vos, sourceLabels, logger, modConfig):
12
+ if isinstance(vos, list):
13
+ self.vos = vos
14
+ else:
15
+ try:
16
+ self.vos = vos.split("|")
17
+ except Exception:
18
+ self.vos = [vos]
19
+ if isinstance(sourceLabels, list):
20
+ self.sourceLabels = sourceLabels
21
+ else:
22
+ try:
23
+ self.sourceLabels = sourceLabels.split("|")
24
+ except Exception:
25
+ self.sourceLabels = [sourceLabels]
26
+ self.modConfig = modConfig
27
+ self.logger = MsgWrapper(logger, _factoryModuleName)
28
+ self.implMap = {}
29
+ self.className = None
30
+ self.classMap = {}
31
+
32
+ # initialize all modules
33
+ def initializeMods(self, *args):
34
+ # parse config
35
+ for configStr in self.modConfig.split(","):
36
+ configStr = configStr.strip()
37
+ items = configStr.split(":")
38
+ # check format
39
+ try:
40
+ vos = items[0].split("|")
41
+ sourceLabels = items[1].split("|")
42
+ moduleName = items[2]
43
+ className = items[3]
44
+ try:
45
+ subTypes = items[4].split("|")
46
+ except Exception:
47
+ subTypes = ["any"]
48
+ except Exception:
49
+ self.logger.error(f"wrong config definition : {configStr}")
50
+ continue
51
+ # loop over all VOs
52
+ for vo in vos:
53
+ # loop over all labels
54
+ for sourceLabel in sourceLabels:
55
+ # check vo and sourceLabel if specified
56
+ if vo not in ["", "any"] and vo not in self.vos and None not in self.vos and "any" not in self.vos:
57
+ continue
58
+ if (
59
+ sourceLabel not in ["", "any"]
60
+ and sourceLabel not in self.sourceLabels
61
+ and None not in self.sourceLabels
62
+ and "any" not in self.sourceLabels
63
+ ):
64
+ continue
65
+ # loop over all sub types
66
+ for subType in subTypes:
67
+ # import
68
+ try:
69
+ # import module
70
+ self.logger.info(f"vo={vo} label={sourceLabel} subtype={subType}")
71
+ self.logger.info(f"importing {moduleName}")
72
+ mod = __import__(moduleName)
73
+ for subModuleName in moduleName.split(".")[1:]:
74
+ mod = getattr(mod, subModuleName)
75
+ # get class
76
+ self.logger.info(f"getting class {className}")
77
+ cls = getattr(mod, className)
78
+ # instantiate
79
+ self.logger.info("instantiating")
80
+ impl = cls(*args)
81
+ # set vo
82
+ impl.vo = vo
83
+ impl.prodSourceLabel = sourceLabel
84
+ # append
85
+ if vo not in self.implMap:
86
+ self.implMap[vo] = {}
87
+ self.classMap[vo] = {}
88
+ if sourceLabel not in self.implMap[vo]:
89
+ self.implMap[vo][sourceLabel] = {}
90
+ self.classMap[vo][sourceLabel] = {}
91
+ self.implMap[vo][sourceLabel][subType] = impl
92
+ self.classMap[vo][sourceLabel][subType] = cls
93
+ self.logger.info(f"{cls} is ready for {vo}:{sourceLabel}:{subType}")
94
+ except Exception:
95
+ errtype, errvalue = sys.exc_info()[:2]
96
+ self.logger.error(
97
+ "failed to import {mn}.{cn} for vo={vo} label={lb} subtype={st} due to {et} {ev}".format(
98
+ et=errtype.__name__, ev=errvalue, st=subType, vo=vo, lb=sourceLabel, cn=className, mn=moduleName
99
+ )
100
+ )
101
+ raise ImportError(f"failed to import {moduleName}.{className}")
102
+ # return
103
+ return True
104
+
105
+ # get implementation for vo and sourceLabel. Only work with initializeMods()
106
+ def getImpl(self, vo, sourceLabel, subType="any", doRefresh=True):
107
+ # check VO
108
+ if vo in self.implMap:
109
+ # match VO
110
+ voImplMap = self.implMap[vo]
111
+ elif "any" in self.implMap:
112
+ # catch all
113
+ voImplMap = self.implMap["any"]
114
+ else:
115
+ return None
116
+ # check sourceLabel
117
+ if sourceLabel in voImplMap:
118
+ # match sourceLabel
119
+ srcImplMap = voImplMap[sourceLabel]
120
+ elif "any" in voImplMap:
121
+ # catch all
122
+ srcImplMap = voImplMap["any"]
123
+ else:
124
+ return None
125
+ # check subType
126
+ if subType in srcImplMap:
127
+ # match subType
128
+ tmpImpl = srcImplMap[subType]
129
+ if doRefresh:
130
+ tmpImpl.refresh()
131
+ return tmpImpl
132
+ elif "any" in srcImplMap:
133
+ # catch all
134
+ tmpImpl = srcImplMap["any"]
135
+ if doRefresh:
136
+ tmpImpl.refresh()
137
+ return tmpImpl
138
+ else:
139
+ return None
140
+
141
+ # instantiate implementation for vo and sourceLabel. Only work with initializeMods()
142
+ def instantiateImpl(self, vo, sourceLabel, subType, *args):
143
+ # check VO
144
+ if vo in self.classMap:
145
+ # match VO
146
+ voImplMap = self.classMap[vo]
147
+ elif "any" in self.classMap:
148
+ # catch all
149
+ voImplMap = self.classMap["any"]
150
+ else:
151
+ return None
152
+ # check sourceLabel
153
+ if sourceLabel in voImplMap:
154
+ # match sourceLabel
155
+ srcImplMap = voImplMap[sourceLabel]
156
+ elif "any" in voImplMap:
157
+ # catch all
158
+ srcImplMap = voImplMap["any"]
159
+ else:
160
+ return None
161
+ # check subType
162
+ if subType in srcImplMap:
163
+ # match subType
164
+ impl = srcImplMap[subType](*args)
165
+ impl.vo = vo
166
+ impl.prodSourceLabel = sourceLabel
167
+ return impl
168
+ elif "any" in srcImplMap:
169
+ # catch all
170
+ impl = srcImplMap["any"](*args)
171
+ impl.vo = vo
172
+ impl.prodSourceLabel = sourceLabel
173
+ return impl
174
+ else:
175
+ return None
176
+
177
+ # get class name of impl
178
+ def getClassName(self, vo=None, sourceLabel=None):
179
+ impl = self.getImpl(vo, sourceLabel, doRefresh=False)
180
+ if impl is None:
181
+ return None
182
+ return impl.__class__.__name__
@@ -0,0 +1,433 @@
1
+ import datetime
2
+ import multiprocessing
3
+ import multiprocessing.reduction
4
+ import os
5
+ import signal
6
+ import sys
7
+ import time
8
+
9
+ from pandacommon.pandautils.PandaUtils import naive_utcnow
10
+
11
+ try:
12
+ from multiprocessing.connection import reduce_connection
13
+ except ImportError:
14
+ from multiprocessing.reduction import reduce_connection
15
+
16
+ # import multiprocessing
17
+ # logger = multiprocessing.log_to_stderr()
18
+ # logger.setLevel(multiprocessing.SUBDEBUG)
19
+
20
+ ###########################################################
21
+ #
22
+ # status codes for IPC
23
+ #
24
+
25
+
26
+ # class for status code
27
+ class StatusCode(object):
28
+ def __init__(self, value):
29
+ self.value = value
30
+
31
+ def __str__(self):
32
+ return f"{self.value}"
33
+
34
+ # comparator
35
+ def __eq__(self, other):
36
+ try:
37
+ return self.value == other.value
38
+ except Exception:
39
+ return False
40
+
41
+ def __ne__(self, other):
42
+ try:
43
+ return self.value != other.value
44
+ except Exception:
45
+ return True
46
+
47
+
48
+ # mapping to accessors
49
+ statusCodeMap = {
50
+ "SC_SUCCEEDED": StatusCode(0),
51
+ "SC_FAILED": StatusCode(1),
52
+ "SC_FATAL": StatusCode(2),
53
+ }
54
+
55
+
56
+ # install the list of status codes to a class
57
+ def installSC(cls):
58
+ for sc, val in statusCodeMap.items():
59
+ setattr(cls, sc, val)
60
+
61
+
62
+ # install SCs in this module
63
+ installSC(sys.modules[__name__])
64
+
65
+
66
+ ###########################################################
67
+ #
68
+ # classes for IPC
69
+ #
70
+
71
+
72
+ # log message with timestamp
73
+ def dumpStdOut(sender, message):
74
+ timeNow = naive_utcnow()
75
+ print(f"{str(timeNow)} {sender}: INFO {message}")
76
+
77
+
78
+ # object class for command
79
+ class CommandObject(object):
80
+ # constructor
81
+ def __init__(self, methodName, argList, argMap):
82
+ self.methodName = methodName
83
+ self.argList = argList
84
+ self.argMap = argMap
85
+
86
+
87
+ # object class for response
88
+ class ReturnObject(object):
89
+ # constructor
90
+ def __init__(self):
91
+ self.statusCode = None
92
+ self.errorValue = None
93
+ self.returnValue = None
94
+
95
+
96
+ # process class
97
+ class ProcessClass(object):
98
+ # constructor
99
+ def __init__(self, pid, connection):
100
+ self.pid = pid
101
+ self.nused = 0
102
+ self.usedMemory = 0
103
+ self.nMemLookup = 20
104
+ # reduce connection to make it picklable
105
+ self.reduced_pipe = reduce_connection(connection)
106
+
107
+ # get connection
108
+ def connection(self):
109
+ # rebuild connection
110
+ return self.reduced_pipe[0](*self.reduced_pipe[1])
111
+
112
+ # reduce connection
113
+ def reduceConnection(self, connection):
114
+ self.reduced_pipe = reduce_connection(connection)
115
+
116
+ # get memory usage
117
+ def getMemUsage(self):
118
+ # update memory info
119
+ if self.nused % self.nMemLookup == 0:
120
+ try:
121
+ # read memory info from /proc
122
+ t = open(f"/proc/{self.pid}/status")
123
+ v = t.read()
124
+ t.close()
125
+ value = 0
126
+ for line in v.split("\n"):
127
+ if line.startswith("VmRSS"):
128
+ items = line.split()
129
+ value = int(items[1])
130
+ if items[2] in ["kB", "KB"]:
131
+ value /= 1024
132
+ elif items[2] in ["mB", "MB"]:
133
+ pass
134
+ break
135
+ self.usedMemory = value
136
+ except Exception:
137
+ pass
138
+ return self.usedMemory
139
+ else:
140
+ return None
141
+
142
+
143
+ # method class
144
+ class MethodClass(object):
145
+ # constructor
146
+ def __init__(self, className, methodName, vo, connectionQueue, voIF):
147
+ self.className = className
148
+ self.methodName = methodName
149
+ self.vo = vo
150
+ self.connectionQueue = connectionQueue
151
+ self.voIF = voIF
152
+ self.pipeList = []
153
+
154
+ # method emulation
155
+ def __call__(self, *args, **kwargs):
156
+ commandObj = CommandObject(self.methodName, args, kwargs)
157
+ nTry = 3
158
+ for iTry in range(nTry):
159
+ # exceptions
160
+ retException = None
161
+ strException = None
162
+ try:
163
+ stepIdx = 0
164
+ # get child process
165
+ child_process = self.connectionQueue.get()
166
+ # get pipe
167
+ stepIdx = 1
168
+ pipe = child_process.connection()
169
+ # get ack
170
+ stepIdx = 2
171
+ timeoutPeriodACK = 30
172
+ if not pipe.poll(timeoutPeriodACK):
173
+ raise JEDITimeoutError(f"did not get ACK for {timeoutPeriodACK}sec")
174
+ ack = pipe.recv()
175
+ # send command
176
+ stepIdx = 3
177
+ pipe.send(commandObj)
178
+ # wait response
179
+ stepIdx = 4
180
+ timeoutPeriod = 600
181
+ timeNow = naive_utcnow()
182
+ if not pipe.poll(timeoutPeriod):
183
+ raise JEDITimeoutError(f"did not get response for {timeoutPeriod}sec")
184
+ regTime = naive_utcnow() - timeNow
185
+ if regTime > datetime.timedelta(seconds=60):
186
+ dumpStdOut(
187
+ self.className,
188
+ f"methodName={self.methodName} took {regTime.seconds}.{int(regTime.microseconds / 1000):03d} sec in pid={child_process.pid}",
189
+ )
190
+ # get response
191
+ stepIdx = 5
192
+ ret = pipe.recv()
193
+ # set exception type based on error
194
+ stepIdx = 6
195
+ if ret.statusCode == SC_FAILED:
196
+ retException = JEDITemporaryError
197
+ elif ret.statusCode == SC_FATAL:
198
+ retException = JEDIFatalError
199
+ except Exception:
200
+ errtype, errvalue = sys.exc_info()[:2]
201
+ retException = errtype
202
+ argStr = f"args={str(args)} kargs={str(kwargs)}"
203
+ strException = f"VO={self.vo} type={errtype.__name__} stepIdx={stepIdx} : {self.className}.{self.methodName} {errvalue} {argStr[:200]}"
204
+ # increment nused
205
+ child_process.nused += 1
206
+ # memory check
207
+ largeMemory = False
208
+ memUsed = child_process.getMemUsage()
209
+ if memUsed is not None:
210
+ memStr = f"pid={child_process.pid} memory={memUsed}MB"
211
+ if memUsed > 1.5 * 1024:
212
+ largeMemory = True
213
+ memStr += " exceeds memory limit"
214
+ dumpStdOut(self.className, memStr)
215
+ # kill old or problematic process
216
+ if child_process.nused > 1000 or retException not in [None, JEDITemporaryError, JEDIFatalError] or largeMemory:
217
+ dumpStdOut(
218
+ self.className,
219
+ f"methodName={self.methodName} ret={retException} nused={child_process.nused} {strException} in pid={child_process.pid}",
220
+ )
221
+ # close connection
222
+ try:
223
+ pipe.close()
224
+ except Exception:
225
+ pass
226
+ # terminate child process
227
+ try:
228
+ dumpStdOut(self.className, f"killing pid={child_process.pid}")
229
+ os.kill(child_process.pid, signal.SIGKILL)
230
+ dumpStdOut(self.className, f"waiting pid={child_process.pid}")
231
+ os.waitpid(child_process.pid, 0)
232
+ dumpStdOut(self.className, f"terminated pid={child_process.pid}")
233
+ except Exception:
234
+ errtype, errvalue = sys.exc_info()[:2]
235
+ if "No child processes" not in str(errvalue):
236
+ dumpStdOut(self.className, f"failed to terminate {child_process.pid} with {errtype}:{errvalue}")
237
+ # make new child process
238
+ self.voIF.launchChild()
239
+ else:
240
+ # reduce process object to avoid deadlock due to rebuilding of connection
241
+ child_process.reduceConnection(pipe)
242
+ self.connectionQueue.put(child_process)
243
+ # success, fatal error, or maximally attempted
244
+ if retException in [None, JEDIFatalError] or (iTry + 1 == nTry):
245
+ break
246
+ # sleep
247
+ time.sleep(1)
248
+ # raise exception
249
+ if retException is not None:
250
+ if strException is None:
251
+ strException = f"VO={self.vo} {ret.errorValue}"
252
+ raise retException(strException)
253
+ # return
254
+ if ret.statusCode == SC_SUCCEEDED:
255
+ return ret.returnValue
256
+ else:
257
+ raise retException(f"VO={self.vo} {ret.errorValue}")
258
+
259
+
260
+ # interface class to send command
261
+ class CommandSendInterface(object):
262
+ # constructor
263
+ def __init__(self, vo, maxChild, moduleName, className):
264
+ self.vo = vo
265
+ self.maxChild = maxChild
266
+ self.connectionQueue = multiprocessing.Queue(maxChild)
267
+ self.moduleName = moduleName
268
+ self.className = className
269
+
270
+ # factory method
271
+ def __getattr__(self, attrName):
272
+ return MethodClass(self.className, attrName, self.vo, self.connectionQueue, self)
273
+
274
+ # launcher for child processe
275
+ def launcher(self, channel):
276
+ # import module
277
+ mod = __import__(self.moduleName)
278
+ for subModuleName in self.moduleName.split(".")[1:]:
279
+ mod = getattr(mod, subModuleName)
280
+ # get class
281
+ cls = getattr(mod, self.className)
282
+ # start child process
283
+ msg = f"start {self.className} with pid={os.getpid()}"
284
+ dumpStdOut(self.moduleName, msg)
285
+ timeNow = naive_utcnow()
286
+ try:
287
+ cls(channel).start()
288
+ except Exception:
289
+ errtype, errvalue = sys.exc_info()[:2]
290
+ dumpStdOut(self.className, f"launcher crashed with {errtype}:{errvalue}")
291
+
292
+ # launch child processes to interact with DDM
293
+ def launchChild(self):
294
+ # make pipe
295
+ parent_conn, child_conn = multiprocessing.Pipe()
296
+ # make child process
297
+ child_process = multiprocessing.Process(target=self.launcher, args=(child_conn,))
298
+ # start child process
299
+ child_process.daemon = True
300
+ child_process.start()
301
+ # keep process in queue
302
+ processObj = ProcessClass(child_process.pid, parent_conn)
303
+ # sync to wait until object in the child process is instantiated
304
+ pipe = processObj.connection()
305
+ pipe.recv()
306
+ processObj.reduceConnection(pipe)
307
+ # ready
308
+ self.connectionQueue.put(processObj)
309
+
310
+ # initialize
311
+ def initialize(self):
312
+ for i in range(self.maxChild):
313
+ self.launchChild()
314
+
315
+
316
+ # interface class to receive command
317
+ class CommandReceiveInterface(object):
318
+ # constructor
319
+ def __init__(self, con):
320
+ self.con = con
321
+ self.cacheMap = {}
322
+
323
+ # make key for cache
324
+ def makeKey(self, className, methodName, argList, argMap):
325
+ try:
326
+ tmpKey = f"{className}:{methodName}:"
327
+ for argItem in argList:
328
+ tmpKey += f"{str(argItem)}:"
329
+ for argKey, argVal in argMap.items():
330
+ tmpKey += f"{argKey}={str(argVal)}:"
331
+ tmpKey = tmpKey[:-1]
332
+ return tmpKey
333
+ except Exception:
334
+ return None
335
+
336
+ # main loop
337
+ def start(self):
338
+ # sync
339
+ self.con.send("ready")
340
+ # main loop
341
+ while True:
342
+ # send ACK
343
+ self.con.send("ack")
344
+ # get command
345
+ commandObj = self.con.recv()
346
+ # make return
347
+ retObj = ReturnObject()
348
+ # get class name
349
+ className = self.__class__.__name__
350
+ # check method name
351
+ if not hasattr(self, commandObj.methodName):
352
+ # method not found
353
+ retObj.statusCode = self.SC_FATAL
354
+ retObj.errorValue = f"type=AttributeError : {className} instance has no attribute {commandObj.methodName}"
355
+ else:
356
+ try:
357
+ # use cache
358
+ useCache = False
359
+ doExec = True
360
+ if "useResultCache" in commandObj.argMap:
361
+ # get time range
362
+ timeRange = commandObj.argMap["useResultCache"]
363
+ # delete from args map
364
+ del commandObj.argMap["useResultCache"]
365
+ # make key for cache
366
+ tmpCacheKey = self.makeKey(className, commandObj.methodName, commandObj.argList, commandObj.argMap)
367
+ if tmpCacheKey is not None:
368
+ useCache = True
369
+ # cache is fresh
370
+ if tmpCacheKey in self.cacheMap and self.cacheMap[tmpCacheKey]["utime"] + datetime.timedelta(seconds=timeRange) > naive_utcnow():
371
+ tmpRet = self.cacheMap[tmpCacheKey]["value"]
372
+ doExec = False
373
+ # exec
374
+ if doExec:
375
+ # get function
376
+ functionObj = getattr(self, commandObj.methodName)
377
+ # exec
378
+ tmpRet = functionObj(*commandObj.argList, **commandObj.argMap)
379
+ if isinstance(tmpRet, StatusCode):
380
+ # only status code was returned
381
+ retObj.statusCode = tmpRet
382
+ elif (isinstance(tmpRet, tuple) or isinstance(tmpRet, list)) and len(tmpRet) > 0 and isinstance(tmpRet[0], StatusCode):
383
+ retObj.statusCode = tmpRet[0]
384
+ # status code + return values
385
+ if len(tmpRet) > 1:
386
+ if retObj.statusCode == self.SC_SUCCEEDED:
387
+ if len(tmpRet) == 2:
388
+ retObj.returnValue = tmpRet[1]
389
+ else:
390
+ retObj.returnValue = tmpRet[1:]
391
+ else:
392
+ if len(tmpRet) == 2:
393
+ retObj.errorValue = tmpRet[1]
394
+ else:
395
+ retObj.errorValue = tmpRet[1:]
396
+ else:
397
+ retObj.statusCode = self.SC_SUCCEEDED
398
+ retObj.returnValue = tmpRet
399
+ except Exception:
400
+ errtype, errvalue = sys.exc_info()[:2]
401
+ # failed
402
+ retObj.statusCode = self.SC_FATAL
403
+ retObj.errorValue = f"type={errtype.__name__} : {className}.{commandObj.methodName} : {errvalue}"
404
+ # cache
405
+ if useCache and doExec and retObj.statusCode == self.SC_SUCCEEDED:
406
+ self.cacheMap[tmpCacheKey] = {"utime": naive_utcnow(), "value": tmpRet}
407
+ # return
408
+ self.con.send(retObj)
409
+
410
+
411
+ # install SCs
412
+ installSC(CommandReceiveInterface)
413
+
414
+
415
+ ###########################################################
416
+ #
417
+ # exceptions for IPC
418
+ #
419
+
420
+
421
+ # exception for temporary error
422
+ class JEDITemporaryError(Exception):
423
+ pass
424
+
425
+
426
+ # exception for fatal error
427
+ class JEDIFatalError(Exception):
428
+ pass
429
+
430
+
431
+ # exception for timeout error
432
+ class JEDITimeoutError(Exception):
433
+ pass
@@ -0,0 +1,56 @@
1
+ import atexit
2
+ import logging
3
+
4
+ from pandacommon.pandalogger.PandaLogger import PandaLogger
5
+
6
+ from pandajedi.jediconfig import jedi_config
7
+ from pandaserver.taskbuffer import OraDBProxy
8
+
9
+ logger = PandaLogger().getLogger(__name__.split(".")[-1])
10
+ OraDBProxy._logger = logger
11
+
12
+
13
+ # add handlers of filtered logger
14
+ tmpLoggerFiltered = PandaLogger().getLogger(__name__.split(".")[-1] + "Filtered")
15
+ for tmpHdr in tmpLoggerFiltered.handlers:
16
+ tmpHdr.setLevel(logging.INFO)
17
+ logger.addHandler(tmpHdr)
18
+ tmpLoggerFiltered.removeHandler(tmpHdr)
19
+
20
+
21
+ # get mb proxies used in DBProxy methods
22
+ def get_mb_proxy_dict():
23
+ if hasattr(jedi_config, "mq") and hasattr(jedi_config.mq, "configFile") and jedi_config.mq.configFile:
24
+ # delay import to open logger file inside python daemon
25
+ from pandajedi.jediorder.JediMsgProcessor import MsgProcAgent
26
+
27
+ in_q_list = []
28
+ out_q_list = ["jedi_jobtaskstatus", "jedi_contents_feeder", "jedi_job_generator"]
29
+ mq_agent = MsgProcAgent(config_file=jedi_config.mq.configFile)
30
+ mb_proxy_dict = mq_agent.start_passive_mode(in_q_list=in_q_list, out_q_list=out_q_list)
31
+ # stop with atexit
32
+ atexit.register(mq_agent.stop_passive_mode)
33
+ # return
34
+ return mb_proxy_dict
35
+
36
+
37
+ # main class
38
+ class DBProxy(OraDBProxy.DBProxy):
39
+ # constructor
40
+ def __init__(self, useOtherError=False):
41
+ OraDBProxy.DBProxy.__init__(self, useOtherError)
42
+
43
+ # set JEDI attributes
44
+ self.set_jedi_attributes(jedi_config, get_mb_proxy_dict)
45
+
46
+ # connect to DB (just for INTR)
47
+ def connect(
48
+ self,
49
+ dbhost=jedi_config.db.dbhost,
50
+ dbpasswd=jedi_config.db.dbpasswd,
51
+ dbuser=jedi_config.db.dbuser,
52
+ dbname=jedi_config.db.dbname,
53
+ dbtimeout=None,
54
+ reconnect=False,
55
+ ):
56
+ return OraDBProxy.DBProxy.connect(self, dbhost=dbhost, dbpasswd=dbpasswd, dbuser=dbuser, dbname=dbname, dbtimeout=dbtimeout, reconnect=reconnect)