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.
- panda_server_source-0.8.0.dist-info/METADATA +55 -0
- panda_server_source-0.8.0.dist-info/RECORD +375 -0
- panda_server_source-0.8.0.dist-info/WHEEL +4 -0
- panda_server_source-0.8.0.dist-info/licenses/LICENSE.txt +202 -0
- pandajedi/__init__.py +0 -0
- pandajedi/jedibrokerage/AtlasAnalJobBroker.py +2343 -0
- pandajedi/jedibrokerage/AtlasBrokerUtils.py +1292 -0
- pandajedi/jedibrokerage/AtlasProdJobBroker.py +2064 -0
- pandajedi/jedibrokerage/AtlasProdTaskBroker.py +629 -0
- pandajedi/jedibrokerage/GenJobBroker.py +381 -0
- pandajedi/jedibrokerage/JobBrokerBase.py +133 -0
- pandajedi/jedibrokerage/TaskBrokerBase.py +15 -0
- pandajedi/jedibrokerage/__init__.py +0 -0
- pandajedi/jediconfig/__init__.py +0 -0
- pandajedi/jediconfig/jedi_config.py +40 -0
- pandajedi/jedicore/FactoryBase.py +182 -0
- pandajedi/jedicore/Interaction.py +433 -0
- pandajedi/jedicore/JediDBProxy.py +56 -0
- pandajedi/jedicore/JediDBProxyPool.py +37 -0
- pandajedi/jedicore/JediDBSchemaInfo.py +17 -0
- pandajedi/jedicore/JediException.py +13 -0
- pandajedi/jedicore/JediTaskBuffer.py +984 -0
- pandajedi/jedicore/JediTaskBufferInterface.py +50 -0
- pandajedi/jedicore/MsgWrapper.py +124 -0
- pandajedi/jedicore/ProcessUtils.py +34 -0
- pandajedi/jedicore/SiteCandidate.py +90 -0
- pandajedi/jedicore/ThreadUtils.py +205 -0
- pandajedi/jedicore/__init__.py +0 -0
- pandajedi/jediddm/AtlasDDMClient.py +1708 -0
- pandajedi/jediddm/DDMClientBase.py +16 -0
- pandajedi/jediddm/DDMInterface.py +83 -0
- pandajedi/jediddm/GenDDMClient.py +17 -0
- pandajedi/jediddm/__init__.py +0 -0
- pandajedi/jedidog/AtlasAnalWatchDog.py +648 -0
- pandajedi/jedidog/AtlasDataCarouselWatchDog.py +189 -0
- pandajedi/jedidog/AtlasDataLocalityUpdaterWatchDog.py +215 -0
- pandajedi/jedidog/AtlasProdWatchDog.py +443 -0
- pandajedi/jedidog/AtlasQueueFillerWatchDog.py +800 -0
- pandajedi/jedidog/AtlasTaskWithholderWatchDog.py +245 -0
- pandajedi/jedidog/AtlasWorkflowManagerWatchDog.py +63 -0
- pandajedi/jedidog/GenWatchDog.py +21 -0
- pandajedi/jedidog/JumboWatchDog.py +147 -0
- pandajedi/jedidog/TypicalWatchDogBase.py +122 -0
- pandajedi/jedidog/WatchDogBase.py +53 -0
- pandajedi/jedidog/__init__.py +0 -0
- pandajedi/jediexec/reniceJEDI.py +25 -0
- pandajedi/jedigen/AtlasTaskGenerator.py +110 -0
- pandajedi/jedigen/TaskGeneratorBase.py +15 -0
- pandajedi/jedigen/__init__.py +0 -0
- pandajedi/jedimsgprocessor/__init__.py +0 -0
- pandajedi/jedimsgprocessor/ai_parameter_adjuster_msg_processor +71 -0
- pandajedi/jedimsgprocessor/atlas_idds_msg_processor.py +66 -0
- pandajedi/jedimsgprocessor/base_msg_processor.py +33 -0
- pandajedi/jedimsgprocessor/forwarding_msg_processor.py +29 -0
- pandajedi/jedimsgprocessor/hpo_msg_processor.py +93 -0
- pandajedi/jedimsgprocessor/jedi_contents_feeder_msg_processor.py +63 -0
- pandajedi/jedimsgprocessor/jedi_job_generator_msg_processor.py +185 -0
- pandajedi/jedimsgprocessor/jedi_post_processor_msg_processor.py +82 -0
- pandajedi/jedimsgprocessor/kafka_msg_processor.py +44 -0
- pandajedi/jedimsgprocessor/panda_callback_msg_processor.py +182 -0
- pandajedi/jedimsgprocessor/panda_to_jedi_msg_processor.py +74 -0
- pandajedi/jedimsgprocessor/processing_msg_processor.py +134 -0
- pandajedi/jedimsgprocessor/status_report_msg_processor.py +129 -0
- pandajedi/jedimsgprocessor/tape_carousel_msg_processor.py +118 -0
- pandajedi/jedimsgprocessor/workflow_manager_msg_processor.py +89 -0
- pandajedi/jediorder/ContentsFeeder.py +785 -0
- pandajedi/jediorder/JediDaemon.py +27 -0
- pandajedi/jediorder/JediKnight.py +55 -0
- pandajedi/jediorder/JediMaster.py +238 -0
- pandajedi/jediorder/JediMsgProcessor.py +32 -0
- pandajedi/jediorder/JobBroker.py +33 -0
- pandajedi/jediorder/JobGenerator.py +2763 -0
- pandajedi/jediorder/JobSplitter.py +308 -0
- pandajedi/jediorder/JobThrottler.py +28 -0
- pandajedi/jediorder/PostProcessor.py +166 -0
- pandajedi/jediorder/TaskBroker.py +268 -0
- pandajedi/jediorder/TaskCommando.py +334 -0
- pandajedi/jediorder/TaskGenerator.py +17 -0
- pandajedi/jediorder/TaskRefiner.py +611 -0
- pandajedi/jediorder/TaskSetupper.py +17 -0
- pandajedi/jediorder/WatchDog.py +79 -0
- pandajedi/jediorder/__init__.py +0 -0
- pandajedi/jedipprocess/AtlasAnalPostProcessor.py +404 -0
- pandajedi/jedipprocess/AtlasPostProcessorUtils.py +50 -0
- pandajedi/jedipprocess/AtlasProdPostProcessor.py +178 -0
- pandajedi/jedipprocess/GenPostProcessor.py +35 -0
- pandajedi/jedipprocess/MailTemplates.py +185 -0
- pandajedi/jedipprocess/PostProcessorBase.py +269 -0
- pandajedi/jedipprocess/__init__.py +0 -0
- pandajedi/jedirefine/AtlasAnalTaskRefiner.py +259 -0
- pandajedi/jedirefine/AtlasProdTaskRefiner.py +162 -0
- pandajedi/jedirefine/GenTaskRefiner.py +61 -0
- pandajedi/jedirefine/RefinerUtils.py +154 -0
- pandajedi/jedirefine/TaskRefinerBase.py +996 -0
- pandajedi/jedirefine/__init__.py +0 -0
- pandajedi/jedisetup/AtlasTaskSetupper.py +309 -0
- pandajedi/jedisetup/GenTaskSetupper.py +16 -0
- pandajedi/jedisetup/SimpleTaskSetupper.py +152 -0
- pandajedi/jedisetup/TaskSetupperBase.py +15 -0
- pandajedi/jedisetup/__init__.py +0 -0
- pandajedi/jeditest/SchemaChecker.py +41 -0
- pandajedi/jeditest/addContWoSoTask.py +54 -0
- pandajedi/jeditest/addDataCarouselRequest.py +47 -0
- pandajedi/jeditest/addEventServiceTask.py +101 -0
- pandajedi/jeditest/addHpoTask.py +81 -0
- pandajedi/jeditest/addIDDSStageInRequest.py +56 -0
- pandajedi/jeditest/addNonAtlasTask.py +71 -0
- pandajedi/jeditest/addNonAtlasTaskEnc.py +64 -0
- pandajedi/jeditest/addTestTask.py +124 -0
- pandajedi/jeditest/addTestTaskParamToDEFT.py +70 -0
- pandajedi/jeditest/addTestTaskWithMerger.py +97 -0
- pandajedi/jeditest/brokerTest.py +78 -0
- pandajedi/jeditest/cancelDataCarouselRequest.py +35 -0
- pandajedi/jeditest/contentsFeederTest.py +28 -0
- pandajedi/jeditest/contentsFeederTestWithTask.py +18 -0
- pandajedi/jeditest/ddmTest.py +4 -0
- pandajedi/jeditest/jobGenForOneTask.py +38 -0
- pandajedi/jeditest/jobGeneratorTest.py +43 -0
- pandajedi/jeditest/jobSplitterTest.py +104 -0
- pandajedi/jeditest/jobThrottlerTest.py +22 -0
- pandajedi/jeditest/msgProcessorTest.py +9 -0
- pandajedi/jeditest/postProcessorTest.py +18 -0
- pandajedi/jeditest/resubmitDataCarouselRequest.py +35 -0
- pandajedi/jeditest/resubmitTaskParam.py +20 -0
- pandajedi/jeditest/taskBrokerTest.py +22 -0
- pandajedi/jeditest/taskBrokerTestWithTask.py +38 -0
- pandajedi/jeditest/taskBufferTest.py +5 -0
- pandajedi/jeditest/taskCommandoTest.py +28 -0
- pandajedi/jeditest/taskRefinerTest.py +30 -0
- pandajedi/jeditest/testOneTaskToRefine.py +49 -0
- pandajedi/jeditest/testOneTaskToTaskBroker.py +42 -0
- pandajedi/jeditest/testPandaDDMMap.py +62 -0
- pandajedi/jeditest/updateDataCarouselRequestParams.py +50 -0
- pandajedi/jeditest/watchDogTest.py +25 -0
- pandajedi/jeditest/workQueueTest.py +22 -0
- pandajedi/jedithrottle/AtlasAnalJobThrottler.py +19 -0
- pandajedi/jedithrottle/AtlasProdJobThrottler.py +18 -0
- pandajedi/jedithrottle/GenJobThrottler.py +26 -0
- pandajedi/jedithrottle/JobThrottlerBase.py +496 -0
- pandajedi/jedithrottle/__init__.py +0 -0
- pandaserver/__init__.py +0 -0
- pandaserver/api/__init__.py +0 -0
- pandaserver/api/v1/__init__.py +0 -0
- pandaserver/api/v1/common.py +339 -0
- pandaserver/api/v1/credential_management_api.py +372 -0
- pandaserver/api/v1/data_carousel_api.py +264 -0
- pandaserver/api/v1/event_api.py +269 -0
- pandaserver/api/v1/file_server_api.py +942 -0
- pandaserver/api/v1/harvester_api.py +445 -0
- pandaserver/api/v1/http_client.py +166 -0
- pandaserver/api/v1/idds_api.py +180 -0
- pandaserver/api/v1/job_api.py +463 -0
- pandaserver/api/v1/metaconfig_api.py +122 -0
- pandaserver/api/v1/pilot_api.py +895 -0
- pandaserver/api/v1/statistics_api.py +207 -0
- pandaserver/api/v1/system_api.py +186 -0
- pandaserver/api/v1/task_api.py +1520 -0
- pandaserver/api/v1/tests/__init__.py +0 -0
- pandaserver/api/v1/tests/credential_management_api_tests.py +116 -0
- pandaserver/api/v1/tests/data_carousel_api_tests.py +82 -0
- pandaserver/api/v1/tests/harvester_api_tests.py +188 -0
- pandaserver/api/v1/tests/idds_api_tests.py +45 -0
- pandaserver/api/v1/tests/job_api_tests.py +112 -0
- pandaserver/api/v1/tests/pilot_api_tests.py +154 -0
- pandaserver/api/v1/tests/statistics_api_tests.py +104 -0
- pandaserver/api/v1/tests/system_api_tests.py +58 -0
- pandaserver/api/v1/tests/task_api_tests.py +590 -0
- pandaserver/api/v1/version.py +2 -0
- pandaserver/api/v1/workflow_api.py +136 -0
- pandaserver/brokerage/SiteMapper.py +406 -0
- pandaserver/brokerage/__init__.py +0 -0
- pandaserver/brokerage/broker.py +272 -0
- pandaserver/config/__init__.py +0 -0
- pandaserver/config/config_utils.py +15 -0
- pandaserver/config/daemon_config.py +29 -0
- pandaserver/config/mcp_config.py +38 -0
- pandaserver/config/panda_config.py +233 -0
- pandaserver/configurator/Carbon.py +65 -0
- pandaserver/configurator/Configurator.py +908 -0
- pandaserver/configurator/__init__.py +0 -0
- pandaserver/configurator/aux.py +73 -0
- pandaserver/daemons/__init__.py +0 -0
- pandaserver/daemons/master.py +110 -0
- pandaserver/daemons/master_systemd.py +79 -0
- pandaserver/daemons/scripts/__init__.py +0 -0
- pandaserver/daemons/scripts/add_main.py +264 -0
- pandaserver/daemons/scripts/add_sub.py +221 -0
- pandaserver/daemons/scripts/cache_pilots.py +47 -0
- pandaserver/daemons/scripts/cache_schedconfig.py +286 -0
- pandaserver/daemons/scripts/carbon.py +50 -0
- pandaserver/daemons/scripts/configurator.py +94 -0
- pandaserver/daemons/scripts/copyArchive.py +1387 -0
- pandaserver/daemons/scripts/datasetManager.py +1154 -0
- pandaserver/daemons/scripts/dummy_test.py +25 -0
- pandaserver/daemons/scripts/evpPD2P.py +144 -0
- pandaserver/daemons/scripts/hs_scrapers.py +264 -0
- pandaserver/daemons/scripts/metric_collector.py +927 -0
- pandaserver/daemons/scripts/panda_activeusers_query.py +80 -0
- pandaserver/daemons/scripts/pilotStreaming.py +109 -0
- pandaserver/daemons/scripts/process_workflow_files_daemon.py +166 -0
- pandaserver/daemons/scripts/recover_lost_files_daemon.py +177 -0
- pandaserver/daemons/scripts/task_evaluator.py +405 -0
- pandaserver/daemons/scripts/tmpwatch.py +70 -0
- pandaserver/daemons/scripts/worker_synchronization.py +97 -0
- pandaserver/daemons/utils.py +753 -0
- pandaserver/dataservice/DataServiceUtils.py +323 -0
- pandaserver/dataservice/ErrorCode.py +25 -0
- pandaserver/dataservice/RecoverLostFilesCore.py +322 -0
- pandaserver/dataservice/__init__.py +0 -0
- pandaserver/dataservice/activator.py +79 -0
- pandaserver/dataservice/adder_atlas_plugin.py +1106 -0
- pandaserver/dataservice/adder_dummy_plugin.py +31 -0
- pandaserver/dataservice/adder_gen.py +954 -0
- pandaserver/dataservice/adder_plugin_base.py +27 -0
- pandaserver/dataservice/adder_result.py +75 -0
- pandaserver/dataservice/adder_simple_plugin.py +160 -0
- pandaserver/dataservice/closer.py +247 -0
- pandaserver/dataservice/closer_atlas_plugin.py +90 -0
- pandaserver/dataservice/ddm.py +1381 -0
- pandaserver/dataservice/ddm_handler.py +95 -0
- pandaserver/dataservice/dyn_data_distributer.py +824 -0
- pandaserver/dataservice/event_lookup_client_ei.py +77 -0
- pandaserver/dataservice/event_picker.py +268 -0
- pandaserver/dataservice/finisher.py +194 -0
- pandaserver/dataservice/setupper.py +225 -0
- pandaserver/dataservice/setupper_atlas_plugin.py +1851 -0
- pandaserver/dataservice/setupper_dummy_plugin.py +47 -0
- pandaserver/dataservice/setupper_plugin_base.py +67 -0
- pandaserver/jobdispatcher/DispatcherUtils.py +35 -0
- pandaserver/jobdispatcher/ErrorCode.py +19 -0
- pandaserver/jobdispatcher/JobDispatcher.py +1625 -0
- pandaserver/jobdispatcher/Protocol.py +443 -0
- pandaserver/jobdispatcher/Watcher.py +186 -0
- pandaserver/jobdispatcher/__init__.py +0 -0
- pandaserver/pandamcp/__init__.py +0 -0
- pandaserver/pandamcp/mcp_main.py +56 -0
- pandaserver/pandamcp/mcp_test_client.py +95 -0
- pandaserver/pandamcp/mcp_utils.py +74 -0
- pandaserver/proxycache/__init__.py +0 -0
- pandaserver/proxycache/panda_proxy_cache.py +240 -0
- pandaserver/proxycache/token_cache.py +141 -0
- pandaserver/server/.gacl +6 -0
- pandaserver/server/panda.py +539 -0
- pandaserver/srvcore/CoreUtils.py +572 -0
- pandaserver/srvcore/MailUtils.py +106 -0
- pandaserver/srvcore/__init__.py +0 -0
- pandaserver/srvcore/allowed_methods.py +100 -0
- pandaserver/srvcore/oidc_utils.py +152 -0
- pandaserver/srvcore/panda_request.py +196 -0
- pandaserver/srvcore/srv_msg_utils.py +42 -0
- pandaserver/taskbuffer/ConBridge.py +513 -0
- pandaserver/taskbuffer/DBProxyPool.py +95 -0
- pandaserver/taskbuffer/DataCarousel.py +3053 -0
- pandaserver/taskbuffer/DatasetSpec.py +137 -0
- pandaserver/taskbuffer/DdmSpec.py +201 -0
- pandaserver/taskbuffer/ErrorCode.py +87 -0
- pandaserver/taskbuffer/EventServiceUtils.py +396 -0
- pandaserver/taskbuffer/FileSpec.py +290 -0
- pandaserver/taskbuffer/GlobalShares.py +244 -0
- pandaserver/taskbuffer/HarvesterMetricsSpec.py +92 -0
- pandaserver/taskbuffer/Initializer.py +82 -0
- pandaserver/taskbuffer/InputChunk.py +1080 -0
- pandaserver/taskbuffer/JediCacheSpec.py +57 -0
- pandaserver/taskbuffer/JediDatasetSpec.py +588 -0
- pandaserver/taskbuffer/JediFileSpec.py +242 -0
- pandaserver/taskbuffer/JediTaskSpec.py +1687 -0
- pandaserver/taskbuffer/JobSpec.py +1006 -0
- pandaserver/taskbuffer/JobUtils.py +232 -0
- pandaserver/taskbuffer/NucleusSpec.py +116 -0
- pandaserver/taskbuffer/OraDBProxy.py +174 -0
- pandaserver/taskbuffer/PanDAMsgProcessor.py +8 -0
- pandaserver/taskbuffer/PandaDBSchemaInfo.py +18 -0
- pandaserver/taskbuffer/ParseJobXML.py +350 -0
- pandaserver/taskbuffer/PickleFileSpec.py +18 -0
- pandaserver/taskbuffer/PickleJobSpec.py +25 -0
- pandaserver/taskbuffer/PrioUtil.py +40 -0
- pandaserver/taskbuffer/ProcessGroups.py +111 -0
- pandaserver/taskbuffer/ResourceSpec.py +175 -0
- pandaserver/taskbuffer/SQLDumper.py +37 -0
- pandaserver/taskbuffer/SQLManager.py +60 -0
- pandaserver/taskbuffer/SiteSpec.py +304 -0
- pandaserver/taskbuffer/SupErrors.py +10 -0
- pandaserver/taskbuffer/TaskBuffer.py +2882 -0
- pandaserver/taskbuffer/TaskBufferInterface.py +163 -0
- pandaserver/taskbuffer/Utils.py +848 -0
- pandaserver/taskbuffer/WorkQueue.py +227 -0
- pandaserver/taskbuffer/WorkQueueMapper.py +203 -0
- pandaserver/taskbuffer/WorkerSpec.py +143 -0
- pandaserver/taskbuffer/WrappedCursor.py +487 -0
- pandaserver/taskbuffer/WrappedPickle.py +88 -0
- pandaserver/taskbuffer/WrappedPostgresConn.py +24 -0
- pandaserver/taskbuffer/__init__.py +0 -0
- pandaserver/taskbuffer/db_proxy_mods/OraDBProxy_structure.png +0 -0
- pandaserver/taskbuffer/db_proxy_mods/__init__.py +7 -0
- pandaserver/taskbuffer/db_proxy_mods/base_module.py +841 -0
- pandaserver/taskbuffer/db_proxy_mods/data_carousel_module.py +772 -0
- pandaserver/taskbuffer/db_proxy_mods/entity_module.py +3804 -0
- pandaserver/taskbuffer/db_proxy_mods/job_complex_module.py +5661 -0
- pandaserver/taskbuffer/db_proxy_mods/job_standalone_module.py +2640 -0
- pandaserver/taskbuffer/db_proxy_mods/metrics_module.py +874 -0
- pandaserver/taskbuffer/db_proxy_mods/misc_standalone_module.py +4272 -0
- pandaserver/taskbuffer/db_proxy_mods/task_complex_module.py +6172 -0
- pandaserver/taskbuffer/db_proxy_mods/task_event_module.py +4953 -0
- pandaserver/taskbuffer/db_proxy_mods/task_standalone_module.py +4999 -0
- pandaserver/taskbuffer/db_proxy_mods/task_utils_module.py +2063 -0
- pandaserver/taskbuffer/db_proxy_mods/worker_module.py +1944 -0
- pandaserver/taskbuffer/db_proxy_mods/workflow_module.py +832 -0
- pandaserver/taskbuffer/retryModule.py +552 -0
- pandaserver/taskbuffer/task_split_rules.py +308 -0
- pandaserver/taskbuffer/workflow_processor.py +249 -0
- pandaserver/taskbuffer/wrapped_oracle_conn.py +18 -0
- pandaserver/test/SchemaChecker.py +40 -0
- pandaserver/test/__init__.py +0 -0
- pandaserver/test/banUser.py +43 -0
- pandaserver/test/boostPrio.py +19 -0
- pandaserver/test/boostUser.py +35 -0
- pandaserver/test/callbackDDM.py +11 -0
- pandaserver/test/daod_on_demand.py +95 -0
- pandaserver/test/finishJob.py +184 -0
- pandaserver/test/finishTaskJEDI.py +11 -0
- pandaserver/test/getJobs.py +53 -0
- pandaserver/test/killJob.py +79 -0
- pandaserver/test/killJobLowPrio.py +99 -0
- pandaserver/test/killJobsInTask.py +56 -0
- pandaserver/test/killTask.py +80 -0
- pandaserver/test/killTaskJEDI.py +11 -0
- pandaserver/test/killUser.py +83 -0
- pandaserver/test/lsst/README.txt +7 -0
- pandaserver/test/lsst/lsstSubmit.py +139 -0
- pandaserver/test/lsst/lsstSubmitMERGEtest.py +141 -0
- pandaserver/test/lsst/lsstSubmitPhosim332.py +53 -0
- pandaserver/test/lsst/prepare-client-tarball-from-bigpanda-server.sh +41 -0
- pandaserver/test/reassignJobs.py +17 -0
- pandaserver/test/reassignSite.py +82 -0
- pandaserver/test/reassignTask.py +117 -0
- pandaserver/test/reassignWaiting.py +39 -0
- pandaserver/test/recoverLostFiles.py +7 -0
- pandaserver/test/reloadInputDS.py +51 -0
- pandaserver/test/sendCommandToJob.py +26 -0
- pandaserver/test/setDebugMode.py +38 -0
- pandaserver/test/setPriority.py +28 -0
- pandaserver/test/testEvgen.py +60 -0
- pandaserver/test/testEvgen17.py +58 -0
- pandaserver/test/testG4sim.py +81 -0
- pandaserver/test/testG4sim17.py +90 -0
- pandaserver/test/testGlobalShares.py +131 -0
- pandaserver/test/testReco.py +103 -0
- pandaserver/test/testSimulReco14.py +98 -0
- pandaserver/test/testSiteMap.py +26 -0
- pandaserver/test/testUpdateWorkerPilotStatus.py +9 -0
- pandaserver/userinterface/Client.py +1686 -0
- pandaserver/userinterface/UserIF.py +1799 -0
- pandaserver/userinterface/__init__.py +0 -0
- pandaserver/workflow/__init__.py +0 -0
- pandaserver/workflow/data_handler_plugins/base_data_handler.py +48 -0
- pandaserver/workflow/data_handler_plugins/ddm_collection_data_handler.py +100 -0
- pandaserver/workflow/data_handler_plugins/panda_task_data_handler.py +140 -0
- pandaserver/workflow/pcwl_test.py +122 -0
- pandaserver/workflow/pcwl_utils.py +384 -0
- pandaserver/workflow/psnakemake_container.json +68 -0
- pandaserver/workflow/psnakemake_task.json +62 -0
- pandaserver/workflow/psnakemake_test.py +60 -0
- pandaserver/workflow/snakeparser/__init__.py +3 -0
- pandaserver/workflow/snakeparser/extensions.py +74 -0
- pandaserver/workflow/snakeparser/log.py +53 -0
- pandaserver/workflow/snakeparser/names.py +3 -0
- pandaserver/workflow/snakeparser/parser.py +332 -0
- pandaserver/workflow/snakeparser/utils.py +29 -0
- pandaserver/workflow/step_handler_plugins/base_step_handler.py +85 -0
- pandaserver/workflow/step_handler_plugins/panda_task_step_handler.py +280 -0
- pandaserver/workflow/workflow_base.py +531 -0
- pandaserver/workflow/workflow_core.py +1974 -0
- pandaserver/workflow/workflow_core_smoketest.py +388 -0
- pandaserver/workflow/workflow_parser.py +222 -0
- pandaserver/workflow/workflow_utils.py +1047 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# Definitions
|
|
2
|
+
EXECUTING = "executing"
|
|
3
|
+
QUEUED = "queued"
|
|
4
|
+
PLEDGED = "pledged"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Node(object):
|
|
8
|
+
def __init__(self):
|
|
9
|
+
self.children = []
|
|
10
|
+
|
|
11
|
+
def add_child(self, node):
|
|
12
|
+
self.children.append(node)
|
|
13
|
+
|
|
14
|
+
def get_leaves(self, leaves=[]):
|
|
15
|
+
# If the node has no leaves, return the node in a list
|
|
16
|
+
if not self.children:
|
|
17
|
+
leaves.append(self)
|
|
18
|
+
return leaves
|
|
19
|
+
|
|
20
|
+
# Recursively get to the bottom
|
|
21
|
+
for child in self.children:
|
|
22
|
+
child.get_leaves(leaves)
|
|
23
|
+
|
|
24
|
+
return leaves
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class Share(Node):
|
|
28
|
+
"""
|
|
29
|
+
Implement the share node
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
_attributes = (
|
|
33
|
+
"name",
|
|
34
|
+
"value",
|
|
35
|
+
"parent",
|
|
36
|
+
"prodsourcelabel",
|
|
37
|
+
"workinggroup",
|
|
38
|
+
"campaign",
|
|
39
|
+
"processingtype",
|
|
40
|
+
"transpath",
|
|
41
|
+
"vo",
|
|
42
|
+
"rtype",
|
|
43
|
+
"queue_id",
|
|
44
|
+
"throttled",
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
def __str__(self, level=0):
|
|
48
|
+
"""
|
|
49
|
+
Print the tree structure
|
|
50
|
+
"""
|
|
51
|
+
ret = "{0} name: {1}, value: {2}\n".format("\t" * level, self.name, self.value)
|
|
52
|
+
for child in self.children:
|
|
53
|
+
ret += child.__str__(level + 1)
|
|
54
|
+
return ret
|
|
55
|
+
|
|
56
|
+
def __repr__(self):
|
|
57
|
+
return self.__str__()
|
|
58
|
+
|
|
59
|
+
def __mul__(self, other):
|
|
60
|
+
"""
|
|
61
|
+
If I multiply a share object by a number, multiply the value field
|
|
62
|
+
"""
|
|
63
|
+
self.value *= other
|
|
64
|
+
return self.value
|
|
65
|
+
|
|
66
|
+
def __rmul__(self, other):
|
|
67
|
+
return self.__mul__
|
|
68
|
+
|
|
69
|
+
def __imul__(self, other):
|
|
70
|
+
return self.__mul__
|
|
71
|
+
|
|
72
|
+
def __init__(
|
|
73
|
+
self,
|
|
74
|
+
name,
|
|
75
|
+
value,
|
|
76
|
+
parent,
|
|
77
|
+
prodsourcelabel,
|
|
78
|
+
workinggroup,
|
|
79
|
+
campaign,
|
|
80
|
+
processingtype,
|
|
81
|
+
transpath,
|
|
82
|
+
rtype,
|
|
83
|
+
vo,
|
|
84
|
+
queue_id,
|
|
85
|
+
throttled,
|
|
86
|
+
):
|
|
87
|
+
# Create default attributes
|
|
88
|
+
for attr in self._attributes:
|
|
89
|
+
setattr(self, attr, None)
|
|
90
|
+
|
|
91
|
+
Node.__init__(self)
|
|
92
|
+
self.name = name
|
|
93
|
+
self.value = value
|
|
94
|
+
self.parent = parent
|
|
95
|
+
self.prodsourcelabel = prodsourcelabel
|
|
96
|
+
self.workinggroup = workinggroup
|
|
97
|
+
self.campaign = campaign
|
|
98
|
+
self.processingtype = processingtype
|
|
99
|
+
self.transpath = transpath
|
|
100
|
+
self.rtype = rtype
|
|
101
|
+
self.vo = vo
|
|
102
|
+
self.queue_id = queue_id
|
|
103
|
+
self.throttled = throttled
|
|
104
|
+
|
|
105
|
+
def pretty_print_hs_distribution(self, hs_distribution, level=0):
|
|
106
|
+
try:
|
|
107
|
+
executing = hs_distribution[self.name][EXECUTING] / 1000.0
|
|
108
|
+
except Exception:
|
|
109
|
+
executing = 0
|
|
110
|
+
|
|
111
|
+
try:
|
|
112
|
+
target = hs_distribution[self.name][PLEDGED] / 1000.0
|
|
113
|
+
except Exception:
|
|
114
|
+
target = 0
|
|
115
|
+
|
|
116
|
+
try:
|
|
117
|
+
queued = hs_distribution[self.name][QUEUED] / 1000.0
|
|
118
|
+
except Exception:
|
|
119
|
+
queued = 0
|
|
120
|
+
|
|
121
|
+
ret = "{0} name: {1}, values: {2:.1f}k|{3:.1f}k|{4:.1f}k\n".format("\t" * level, self.name, executing, target, queued)
|
|
122
|
+
for child in self.children:
|
|
123
|
+
ret += child.pretty_print_hs_distribution(hs_distribution, level + 1)
|
|
124
|
+
return ret
|
|
125
|
+
|
|
126
|
+
def normalize(self, multiplier=100, divider=100):
|
|
127
|
+
"""
|
|
128
|
+
Will run down the branch and normalize values beneath
|
|
129
|
+
"""
|
|
130
|
+
self.value *= multiplier * 1.0 / divider
|
|
131
|
+
if not self.children:
|
|
132
|
+
return
|
|
133
|
+
|
|
134
|
+
divider = 0
|
|
135
|
+
for child in self.children:
|
|
136
|
+
divider += child.value
|
|
137
|
+
|
|
138
|
+
multiplier = self.value
|
|
139
|
+
|
|
140
|
+
for child in self.children:
|
|
141
|
+
child.normalize(multiplier=multiplier, divider=divider)
|
|
142
|
+
|
|
143
|
+
return
|
|
144
|
+
|
|
145
|
+
def sort_branch_by_current_hs_distribution(self, hs_distribution):
|
|
146
|
+
"""
|
|
147
|
+
Runs down the branch in order of under-pledging. It returns a list of sorted leave shares
|
|
148
|
+
"""
|
|
149
|
+
sorted_shares = []
|
|
150
|
+
|
|
151
|
+
# If the node has no leaves, return the node in a list
|
|
152
|
+
if not self.children:
|
|
153
|
+
sorted_shares = [self]
|
|
154
|
+
return sorted_shares
|
|
155
|
+
|
|
156
|
+
# If the node has leaves, sort the children
|
|
157
|
+
children_sorted = []
|
|
158
|
+
for child1 in self.children:
|
|
159
|
+
loop_index = 0
|
|
160
|
+
insert_index = len(children_sorted) # insert at the end, if not deemed otherwise
|
|
161
|
+
|
|
162
|
+
# Calculate under-pledging
|
|
163
|
+
try:
|
|
164
|
+
child1_under_pledge = hs_distribution[child1.name][EXECUTING] * 1.0 / hs_distribution[child1.name][PLEDGED]
|
|
165
|
+
except ZeroDivisionError:
|
|
166
|
+
child1_under_pledge = 10**6 # Initialize to a large default number
|
|
167
|
+
|
|
168
|
+
for child2 in children_sorted:
|
|
169
|
+
try:
|
|
170
|
+
# Calculate under-pledging
|
|
171
|
+
child2_under_pledge = hs_distribution[child2.name][EXECUTING] * 1.0 / hs_distribution[child2.name][PLEDGED]
|
|
172
|
+
except ZeroDivisionError:
|
|
173
|
+
child2_under_pledge = 10**6 # Initialize to a large default number
|
|
174
|
+
except KeyError:
|
|
175
|
+
continue # Does not exist
|
|
176
|
+
|
|
177
|
+
if child1_under_pledge < child2_under_pledge:
|
|
178
|
+
insert_index = loop_index
|
|
179
|
+
break
|
|
180
|
+
|
|
181
|
+
loop_index += 1
|
|
182
|
+
|
|
183
|
+
# Insert the child into the list
|
|
184
|
+
children_sorted.insert(insert_index, child1)
|
|
185
|
+
|
|
186
|
+
# Go recursively and sort the grand* children
|
|
187
|
+
for child in children_sorted:
|
|
188
|
+
sorted_shares.extend(child.sort_branch_by_current_hs_distribution(hs_distribution))
|
|
189
|
+
|
|
190
|
+
return sorted_shares
|
|
191
|
+
|
|
192
|
+
def aggregate_hs_distribution(self, hs_distribution):
|
|
193
|
+
"""
|
|
194
|
+
We have the current HS distribution values for the leaves, but want to propagate it updwards to the parents.
|
|
195
|
+
We will traverse the tree from top to bottom and bring up the aggregated values.
|
|
196
|
+
"""
|
|
197
|
+
executing, queued, pledged = 0, 0, 0
|
|
198
|
+
|
|
199
|
+
# If the node has no children, it's a leave and should have an entry in the hs_distribution
|
|
200
|
+
if not self.children:
|
|
201
|
+
try:
|
|
202
|
+
executing = hs_distribution[self.name][EXECUTING]
|
|
203
|
+
queued = hs_distribution[self.name][QUEUED]
|
|
204
|
+
pledged = hs_distribution[self.name][PLEDGED]
|
|
205
|
+
except KeyError:
|
|
206
|
+
pass
|
|
207
|
+
|
|
208
|
+
return executing, queued, pledged
|
|
209
|
+
|
|
210
|
+
# If the node has children, sum up the values of the children
|
|
211
|
+
executing = 0
|
|
212
|
+
queued = 0
|
|
213
|
+
pledged = 0
|
|
214
|
+
|
|
215
|
+
for child in self.children:
|
|
216
|
+
(
|
|
217
|
+
executing_child,
|
|
218
|
+
queued_child,
|
|
219
|
+
pledged_child,
|
|
220
|
+
) = child.aggregate_hs_distribution(hs_distribution)
|
|
221
|
+
executing += executing_child
|
|
222
|
+
queued += queued_child
|
|
223
|
+
pledged += pledged_child
|
|
224
|
+
|
|
225
|
+
# Add the aggregated value to the map
|
|
226
|
+
hs_distribution[self.name] = {
|
|
227
|
+
EXECUTING: executing,
|
|
228
|
+
QUEUED: queued,
|
|
229
|
+
PLEDGED: pledged,
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
# Return the aggregated values
|
|
233
|
+
return executing, queued, pledged
|
|
234
|
+
|
|
235
|
+
# return column names
|
|
236
|
+
def column_names(cls):
|
|
237
|
+
ret = ""
|
|
238
|
+
for attr in cls._attributes:
|
|
239
|
+
if ret != "":
|
|
240
|
+
ret += ","
|
|
241
|
+
ret += attr
|
|
242
|
+
return ret
|
|
243
|
+
|
|
244
|
+
column_names = classmethod(column_names)
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"""
|
|
2
|
+
worker specification
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import datetime
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class HarvesterMetricsSpec(object):
|
|
10
|
+
# attributes
|
|
11
|
+
_attributes = ("harvester_ID", "creation_time", "harvester_host", "metrics")
|
|
12
|
+
# slots
|
|
13
|
+
__slots__ = _attributes + ("_changedAttrs",)
|
|
14
|
+
# attributes which have 0 by default
|
|
15
|
+
_zeroAttrs = ()
|
|
16
|
+
|
|
17
|
+
# constructor
|
|
18
|
+
def __init__(self):
|
|
19
|
+
# install attributes
|
|
20
|
+
for attr in self._attributes:
|
|
21
|
+
object.__setattr__(self, attr, None)
|
|
22
|
+
# map of changed attributes
|
|
23
|
+
object.__setattr__(self, "_changedAttrs", {})
|
|
24
|
+
|
|
25
|
+
# override __setattr__ to collecte the changed attributes
|
|
26
|
+
def __setattr__(self, name, value):
|
|
27
|
+
oldVal = getattr(self, name)
|
|
28
|
+
# convert string to datetime
|
|
29
|
+
if isinstance(value, str) and value.startswith("datetime/"):
|
|
30
|
+
value = datetime.datetime.strptime(value.split("/")[-1], "%Y-%m-%d %H:%M:%S.%f")
|
|
31
|
+
object.__setattr__(self, name, value)
|
|
32
|
+
# collect changed attributes
|
|
33
|
+
if oldVal != value:
|
|
34
|
+
self._changedAttrs[name] = value
|
|
35
|
+
|
|
36
|
+
# reset changed attribute list
|
|
37
|
+
def resetChangedList(self):
|
|
38
|
+
self._oldPandaID = self.PandaID
|
|
39
|
+
object.__setattr__(self, "_changedAttrs", {})
|
|
40
|
+
|
|
41
|
+
# return map of values
|
|
42
|
+
def valuesMap(self, onlyChanged=False):
|
|
43
|
+
ret = {}
|
|
44
|
+
for attr in self._attributes:
|
|
45
|
+
if onlyChanged and attr not in self._changedAttrs:
|
|
46
|
+
continue
|
|
47
|
+
val = getattr(self, attr)
|
|
48
|
+
if val is None:
|
|
49
|
+
if attr in self._zeroAttrs:
|
|
50
|
+
val = 0
|
|
51
|
+
ret[f":{attr}"] = val
|
|
52
|
+
return ret
|
|
53
|
+
|
|
54
|
+
# pack tuple into FileSpec
|
|
55
|
+
def pack(self, values):
|
|
56
|
+
for i in range(len(self._attributes)):
|
|
57
|
+
attr = self._attributes[i]
|
|
58
|
+
val = values[i]
|
|
59
|
+
object.__setattr__(self, attr, val)
|
|
60
|
+
|
|
61
|
+
# return column names for INSERT
|
|
62
|
+
def columnNames(cls):
|
|
63
|
+
ret = ""
|
|
64
|
+
for attr in cls._attributes:
|
|
65
|
+
ret += f"{attr},"
|
|
66
|
+
ret = ret[:-1]
|
|
67
|
+
return ret
|
|
68
|
+
|
|
69
|
+
columnNames = classmethod(columnNames)
|
|
70
|
+
|
|
71
|
+
# return expression of bind variables for INSERT
|
|
72
|
+
def bindValuesExpression(cls):
|
|
73
|
+
from pandaserver.config import panda_config
|
|
74
|
+
|
|
75
|
+
ret = "VALUES("
|
|
76
|
+
for attr in cls._attributes:
|
|
77
|
+
ret += f":{attr},"
|
|
78
|
+
ret = ret[:-1]
|
|
79
|
+
ret += ")"
|
|
80
|
+
return ret
|
|
81
|
+
|
|
82
|
+
bindValuesExpression = classmethod(bindValuesExpression)
|
|
83
|
+
|
|
84
|
+
# return an expression of bind variables for UPDATE to update only changed attributes
|
|
85
|
+
def bindUpdateChangesExpression(self):
|
|
86
|
+
ret = ""
|
|
87
|
+
for attr in self._attributes:
|
|
88
|
+
if attr not in self._changedAttrs:
|
|
89
|
+
continue
|
|
90
|
+
ret += "{0}=:{0},".format(attr)
|
|
91
|
+
ret = ret[:-1]
|
|
92
|
+
return ret
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from threading import Lock
|
|
3
|
+
|
|
4
|
+
from pandacommon.pandalogger.PandaLogger import PandaLogger
|
|
5
|
+
|
|
6
|
+
from pandaserver.config import panda_config
|
|
7
|
+
|
|
8
|
+
_logger = PandaLogger().getLogger("Initializer")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Initializer:
|
|
12
|
+
"""
|
|
13
|
+
Initialize a dummy database connection.
|
|
14
|
+
|
|
15
|
+
Returns:
|
|
16
|
+
bool: True if the initialization is successful, False otherwise.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __init__(self):
|
|
20
|
+
self.lock = Lock()
|
|
21
|
+
self.first = True
|
|
22
|
+
|
|
23
|
+
def init(self):
|
|
24
|
+
_logger.debug(f"init new={self.first}")
|
|
25
|
+
# do nothing when nDBConnection is 0
|
|
26
|
+
if panda_config.nDBConnection == 0:
|
|
27
|
+
return True
|
|
28
|
+
# lock
|
|
29
|
+
self.lock.acquire()
|
|
30
|
+
if self.first:
|
|
31
|
+
self.first = False
|
|
32
|
+
try:
|
|
33
|
+
_logger.debug("connect")
|
|
34
|
+
# connect
|
|
35
|
+
if panda_config.backend == "oracle":
|
|
36
|
+
import oracledb
|
|
37
|
+
|
|
38
|
+
oracledb.init_oracle_client()
|
|
39
|
+
conn = oracledb.connect(user=panda_config.dbuser, password=panda_config.dbpasswd, dsn=panda_config.dbhost)
|
|
40
|
+
|
|
41
|
+
elif panda_config.backend == "postgres":
|
|
42
|
+
import psycopg2
|
|
43
|
+
|
|
44
|
+
conn = psycopg2.connect(
|
|
45
|
+
host=panda_config.dbhost,
|
|
46
|
+
dbname=panda_config.dbname,
|
|
47
|
+
port=panda_config.dbport,
|
|
48
|
+
connect_timeout=panda_config.dbtimeout,
|
|
49
|
+
user=panda_config.dbuser,
|
|
50
|
+
password=panda_config.dbpasswd,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
else:
|
|
54
|
+
import MySQLdb
|
|
55
|
+
|
|
56
|
+
conn = MySQLdb.connect(
|
|
57
|
+
host=panda_config.dbhost,
|
|
58
|
+
db=panda_config.dbname,
|
|
59
|
+
port=panda_config.dbport,
|
|
60
|
+
connect_timeout=panda_config.dbtimeout,
|
|
61
|
+
user=panda_config.dbuser,
|
|
62
|
+
passwd=panda_config.dbpasswd,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
# close
|
|
66
|
+
conn.close()
|
|
67
|
+
_logger.debug("done")
|
|
68
|
+
|
|
69
|
+
except Exception:
|
|
70
|
+
self.lock.release()
|
|
71
|
+
exception_type, exception_value, traceback = sys.exc_info()
|
|
72
|
+
_logger.error(f"connect : {exception_type} {exception_value}")
|
|
73
|
+
return False
|
|
74
|
+
|
|
75
|
+
# release the lock
|
|
76
|
+
self.lock.release()
|
|
77
|
+
return True
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
# singleton
|
|
81
|
+
initializer = Initializer()
|
|
82
|
+
del Initializer
|