key4hep / k4FWCore

Core Components for the Gaudi-based Key4hep Framework
Apache License 2.0
10 stars 26 forks source link

Fix accessing input file metadata in MetadataSvc #223

Open m-fila opened 4 weeks ago

m-fila commented 4 weeks ago

BEGINRELEASENOTES

ENDRELEASENOTES

In the MetadataSvc added in #215 the matadata was split into two frames:

In this PR I propose to have one metadata frame containing both metadata from input and anything set in current processing. The frame will be not saved if it doesn't exist:

Reading parameters from not existing frame gives empty optional

tmadlener commented 1 week ago

One small thing I just realized as well, we have the MetadataSvc but we have MetaDataHandles. IIUC both of them will stay around right? Should we try to homogenize the naming of the two things?

Another question: Does the MetadataSvc still work with podio < 1.0? I.e. before the Frame::getParameter started to return std::optional?

m-fila commented 1 week ago

I feel like these are questions for @jmcarcell as he was the original author of the service

From my understanding:

tmadlener commented 1 week ago

I'd prefer to use MetadataWhatever rather than MetaDataWhatever as "metadata" is a legit word, but probably it'd be easier to do the opposite and rename toMetaDataSvc

I also like the Metadata better than MetaData, but I also agree with your assessment. Let's see whether the MetaDataHandle is supposed to stay before we discuss this further.

m-fila commented 1 week ago

tl;dr I really don't like having and exposing public unique_ptr member as part of the interface

Having a look at this, it's possible to fix the issue of the two frames by removing the redeclaration in

https://github.com/key4hep/k4FWCore/blob/941da762dda23886e13b4a53a6341c80c1eca5ce/k4FWCore/components/MetadataSvc.h#L39 , then there will only be one frame, all the tests work and empty optional is returned when there isn't a value.

I'd argue that the frame should go from IMetaDataSvc rather than from MetaDataSvc. The IMetaDataSvc is supposed to be an interface and shouldn't contain implementation. Having implementation of set and put is already pushing it, but since they are supposed to be templates then this is the easiest way

The rest of the changes are interface changes to use getFrame and setFrame instead of accessing directly m_frame (which would be possible after deleting the redeclaration and having only one). For simplicity I prefer accessing m_frame directly,

I agree that having the setter and getter on this service isn't pretty. But I see them as lesser evil:

I see there is a strong coupling between IOSvc and MetadataSvc and I'm not sure if overall it wouldn't be better to have a single concrete class that implements bothIIOSvc and IMetadataSvc rather than having two separate implementations that depend on each other (IOSvc even creates the MetadataSvc)

There is also a check for whether the frame is valid or not and then give you an std::nullopt but this is already implemented in getParameter

I'm not sure to which getParameter you are referring to. The service creates a frame on the first put or if there is a frame from the input data given to it by IOSvc. So there is a state in which there is no frame in the service

tmadlener commented 1 week ago

The public const getter is due to the coupling with Writer. I think that giving access to a const raw pointer is safer than exposing a std::unique_ptr. The getter gives raw pointer becasue this is an idiomatic way for not giving an ownership - there is no need to transfer ownership to the reader as it accepts a const Frame&

I suppose we can't make that return references, because it's possible that getFrame is called, when we don't have a valid m_frame yet, and we need the fact that we can do the nullptr check? I agree that the raw pointer already signifies that the caller doesn't get ownership.

m-fila commented 1 week ago

I suppose we can't make that return references, because it's possible that getFrame is called, when we don't have a valid m_frame yet, and we need the fact that we can do the nullptr check? I agree that the raw pointer already signifies that the caller doesn't get ownership.

Yes, getFrame should return either a valid frame or signalize invalid state, so a reference is not good for that. Optional also doesn't work since we need reference semantic and there is no std optional reference