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