diff --git a/k4FWCore/components/MetadataSvc.cpp b/k4FWCore/components/MetadataSvc.cpp index fb9d7d76..1b32f549 100644 --- a/k4FWCore/components/MetadataSvc.cpp +++ b/k4FWCore/components/MetadataSvc.cpp @@ -22,8 +22,10 @@ #include "podio/Frame.h" #include +#include #include #include +#include #include @@ -43,6 +45,12 @@ StatusCode MetadataSvc::initialize() { StatusCode MetadataSvc::finalize() { return Service::finalize(); } +void MetadataSvc::throwIfRunning() const { + if (targetFSMState() == Gaudi::StateMachine::RUNNING) { + throw GaudiException("putParameter cannot be called during the event loop", name(), StatusCode::FAILURE); + } +} + const podio::Frame* MetadataSvc::getFrame() const { return m_frame.get(); } podio::Frame* MetadataSvc::getFrame() { return m_frame.get(); } void MetadataSvc::setFrame(podio::Frame frame) { m_frame = std::make_unique(std::move(frame)); } diff --git a/k4FWCore/components/MetadataSvc.h b/k4FWCore/components/MetadataSvc.h index eb482dd9..ed2ea201 100644 --- a/k4FWCore/components/MetadataSvc.h +++ b/k4FWCore/components/MetadataSvc.h @@ -43,6 +43,7 @@ class MetadataSvc : public extends { const podio::Frame* getFrame() const override; podio::Frame* getFrame() override; void setFrame(podio::Frame frame) override; + void throwIfRunning() const override; }; #endif diff --git a/k4FWCore/include/k4FWCore/IMetadataSvc.h b/k4FWCore/include/k4FWCore/IMetadataSvc.h index c0365e84..9ec3ecd1 100644 --- a/k4FWCore/include/k4FWCore/IMetadataSvc.h +++ b/k4FWCore/include/k4FWCore/IMetadataSvc.h @@ -50,9 +50,11 @@ class IMetadataSvc : virtual public IInterface { protected: virtual podio::Frame* getFrame() = 0; virtual const podio::Frame* getFrame() const = 0; + virtual void throwIfRunning() const {} private: podio::Frame* getFrameForWrite() { + throwIfRunning(); if (!getFrame()) { setFrame(podio::Frame()); } diff --git a/test/k4FWCoreTest/CMakeLists.txt b/test/k4FWCoreTest/CMakeLists.txt index fd956945..f8f79ab8 100644 --- a/test/k4FWCoreTest/CMakeLists.txt +++ b/test/k4FWCoreTest/CMakeLists.txt @@ -218,6 +218,8 @@ add_test_fwcore(FunctionalCollectionMerger options/ExampleFunctionalCollectionMe add_test_fwcore(FunctionalFilterFile options/ExampleFunctionalFilterFile.py ADD_TO_CHECK_FILES) add_test_fwcore(FunctionalMetadata options/ExampleFunctionalMetadata.py ADD_TO_CHECK_FILES PROPERTIES FIXTURES_SETUP FunctionalMetadataFile) add_test_fwcore(FunctionalMetadataRead options/ExampleFunctionalMetadataRead.py PROPERTIES FIXTURES_REQUIRED FunctionalMetadataFile ADD_TO_CHECK_FILES) +add_test_fwcore(FunctionalMetadataEventLoop options/ExampleFunctionalMetadataEventLoop.py + PROPERTIES PASS_REGULAR_EXPRESSION "putParameter cannot be called during the event loop") add_test_fwcore(FunctionalMetadataOldAlgorithm options/ExampleFunctionalMetadataOldAlgorithm.py ADD_TO_CHECK_FILES PROPERTIES FIXTURES_SETUP OldAlgorithmFile) add_test_fwcore(createEventHeaderConcurrent options/createEventHeaderConcurrent.py ADD_TO_CHECK_FILES) add_test_fwcore(FunctionalMetadataReadOldAlgorithm options/ExampleFunctionalMetadataReadOldAlgorithm.py PROPERTIES FIXTURES_REQUIRED OldAlgorithmFile ADD_TO_CHECK_FILES) diff --git a/test/k4FWCoreTest/options/ExampleFunctionalMetadataEventLoop.py b/test/k4FWCoreTest/options/ExampleFunctionalMetadataEventLoop.py new file mode 100644 index 00000000..297abc51 --- /dev/null +++ b/test/k4FWCoreTest/options/ExampleFunctionalMetadataEventLoop.py @@ -0,0 +1,39 @@ +# +# Copyright (c) 2014-2024 Key4hep-Project. +# +# This file is part of Key4hep. +# See https://key4hep.github.io/key4hep-doc/ for further info. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This test verifies that calling putParameter during the event loop raises an error + +from Gaudi.Configuration import INFO +from Configurables import ExampleFunctionalMetadataProducer +from k4FWCore import ApplicationMgr +from Configurables import EventDataSvc, MetadataSvc + +producer = ExampleFunctionalMetadataProducer( + "Producer", + OutputCollection=["MCParticles"], + PutMetadataInEventLoop=True, +) + +ApplicationMgr( + TopAlg=[producer], + EvtSel="NONE", + EvtMax=3, + ExtSvc=[EventDataSvc("EventDataSvc"), MetadataSvc("MetadataSvc")], + OutputLevel=INFO, +) diff --git a/test/k4FWCoreTest/src/components/ExampleFunctionalMetadataProducer.cpp b/test/k4FWCoreTest/src/components/ExampleFunctionalMetadataProducer.cpp index 2e568d99..ee6e6019 100644 --- a/test/k4FWCoreTest/src/components/ExampleFunctionalMetadataProducer.cpp +++ b/test/k4FWCoreTest/src/components/ExampleFunctionalMetadataProducer.cpp @@ -42,8 +42,9 @@ struct ExampleFunctionalMetadataProducer final : k4FWCore::Producer m_putMetadataInEventLoop{this, "PutMetadataInEventLoop", false, + "If true, attempt to put metadata during the event loop (will throw)"}; Gaudi::Property m_intProp{this, "intProp", 42, "An integer property"}; Gaudi::Property m_intProp2{this, "intProp2", 42, "An integer property"}; Gaudi::Property m_floatProp{this, "floatProp", 3.14, "A float property"};