Belle II Software  release-05-02-19
TestingPayloadStorage Class Reference

Class to store and retrieve temporary payloads. More...

#include <TestingPayloadStorage.h>

Collaboration diagram for TestingPayloadStorage:

Public Member Functions

 TestingPayloadStorage (const std::string &filename)
 Create a new instance to work on a given filename.
 
bool get (const EventMetaData &event, PayloadMetadata &info)
 Try to fill the PayloadMetaData for the given EventMetaData, return true on success, false if no machting payload could be found.
 
bool storeData (const std::string &name, TObject *object, const IntervalOfValidity &iov)
 Store a TObject instance as a payload with given name and interval of validity. More...
 
bool storePayload (const std::string &name, const std::string &fileName, const IntervalOfValidity &iov)
 Store an existing file as payload with given name and interval of validity. More...
 
void reset ()
 Reset the list of known payloads. More...
 

Private Member Functions

void read ()
 Read the given storage file, done lazily on first access to get() after construction or call to reset()
 
bool writePayload (const std::string &fileName, const std::string &name, const TObject *object)
 Write a payload file from the given object and name. More...
 
bool store (const std::string &name, const IntervalOfValidity &iov, const std::function< bool(const std::string &)> &writer)
 Try to store a new payload with the given name and interval of validity. More...
 

Static Private Member Functions

static std::string payloadFilename (const std::string &path, const std::string &name, int revision)
 Build the filename for a new payload with a given name and revision in a directory.
 

Private Attributes

std::unordered_map< std::string, std::vector< std::tuple< size_t, IntervalOfValidity > > > m_payloads
 Map of known payloads to a list of known revisions and their interval of validity.
 
std::string m_filename
 Storage file where to look for payloads. More...
 
std::string m_absoluteFilename
 Storage file where to look for payloads converted to an absolute path to be robust against directory changes.
 
std::string m_payloadDir
 Directory containing the storage file as absolute file name. More...
 
bool m_initialized {false}
 Remember whether we read the file already.
 

Detailed Description

Class to store and retrieve temporary payloads.

Temporary payloads are stored in a directory where we create a root files and a plain text file with name, revision and iov for each of these files. This is not very safe but ideal for testing and manual adjustments before final validation and upload to the cental server.

The interface is very basic: We create an instance with a filename and then we either get() payload information for a given event and payload metadata struct or we store a given payload either from an object (storeData()) or from an existing file (storePayload()).

Both call the underlying store() which tries to be robust against multiple processes trying to create payloads at the same time.

Definition at line 49 of file TestingPayloadStorage.h.

Member Function Documentation

◆ reset()

void reset ( )
inline

Reset the list of known payloads.

Will trigger re-reading the file on next access to get()

Definition at line 65 of file TestingPayloadStorage.h.

◆ store()

bool store ( const std::string &  name,
const IntervalOfValidity iov,
const std::function< bool(const std::string &)> &  writer 
)
private

Try to store a new payload with the given name and interval of validity.

This function first tries to find the next free revision and then call the writer function to write the payload to the given filename. If the writer function returns success the payload is added to the storage file

Definition at line 166 of file TestingPayloadStorage.cc.

169  {
170  fs::create_directories(m_payloadDir);
171  }
172  // get lock for write access to database file
173  FileSystem::Lock lock(m_absoluteFilename);
174  if (!lock.lock()) {
175  B2ERROR("Locking of testing payload storage file failed, cannot create payload"
176  << LogVar("storage file", m_filename));
177  return false;
178  }
179  std::ofstream file(m_absoluteFilename.c_str(), std::ios::app);
180  if (!file.is_open()) {
181  B2ERROR("Could not open testing payload storage file for writing" << LogVar("storage file", m_filename));
182  }
183 
184  // Find the next free revision number
185  for (int revision = 1; revision < INT_MAX; ++revision) {
186  auto filename = payloadFilename(m_payloadDir, name, revision);
187  // FIXME: This could be a race condition, we check for existence and then
188  // create which could fail if two processes try this at the same time and
189  // thus overwrite the files of each other. We could instead check if an
190  // `open(filename.c_str(), O_CREAT|O_EXCL)` is successful in which the
191  // file is ours however I'm a bit sceptical if this will work on SL6. But
192  // since we locked the database file and no longer support the payloads be
193  // in a different directory then the text files this almost fine. However
194  // there could still be multiple text files in the same directory so still
195  // a slight chance for race conditions. Or locking could just not work on
196  // some file systems, for example misconfigured NFS
197  if (FileSystem::fileExists(filename)) continue;
198  // free revision found, try to save
199  if (!writer(filename)) return false;
200  // Ok, now we need to add it to the database file
201  file << "dbstore/" << name << " " << revision << " " << iov << std::endl;
202  B2DEBUG(32, "Storing testing payload" << LogVar("storage file", m_filename) << LogVar("name", name)
203  << LogVar("local revision", revision) << LogVar("iov", iov));
204  // And make sure we reread the file on next request to payloads
205  m_initialized = false;
206  return true;
207  }
208  B2ERROR("Could not find a suitable revision to create payload" << LogVar("storage file", m_filename) << LogVar("name", name));
209  return false;
210  }
211 
212  bool TestingPayloadStorage::writePayload(const std::string& fileName, const std::string& name, const TObject* object)
213  {
214  // Save the current gDirectory
215  TDirectory::TContext saveDir;
216  // And create a reproducible TFile: one that has the same checksum every time it's created as long as the content is the same
217  std::unique_ptr<TFile> file{TFile::Open((fileName + "?reproducible=PayloadFile").c_str(), "RECREATE")};
218  if (!file || !file->IsOpen()) {

◆ storeData()

bool storeData ( const std::string &  name,
TObject *  object,
const IntervalOfValidity iov 
)

Store a TObject instance as a payload with given name and interval of validity.

This will create a new ROOT file containing the object in the directory of the storage file

Definition at line 144 of file TestingPayloadStorage.cc.

◆ storePayload()

bool storePayload ( const std::string &  name,
const std::string &  fileName,
const IntervalOfValidity iov 
)

Store an existing file as payload with given name and interval of validity.

This will create a copy of the file with a different name in the directory of the storage file

Definition at line 151 of file TestingPayloadStorage.cc.

◆ writePayload()

bool writePayload ( const std::string &  fileName,
const std::string &  name,
const TObject *  object 
)
private

Write a payload file from the given object and name.

Will create new root file containing object under the Key name with the name fileName

Definition at line 220 of file TestingPayloadStorage.cc.

Member Data Documentation

◆ m_filename

std::string m_filename
private

Storage file where to look for payloads.

This is the logical file name as given by the user

Definition at line 72 of file TestingPayloadStorage.h.

◆ m_payloadDir

std::string m_payloadDir
private

Directory containing the storage file as absolute file name.

Will try to create it if it doesn't exist and storeData() or storePayload() is called

Definition at line 78 of file TestingPayloadStorage.h.


The documentation for this class was generated from the following files:
Belle2::Conditions::TestingPayloadStorage::m_initialized
bool m_initialized
Remember whether we read the file already.
Definition: TestingPayloadStorage.h:80
Belle2::Conditions::TestingPayloadStorage::m_filename
std::string m_filename
Storage file where to look for payloads.
Definition: TestingPayloadStorage.h:72
Belle2::Conditions::TestingPayloadStorage::m_payloadDir
std::string m_payloadDir
Directory containing the storage file as absolute file name.
Definition: TestingPayloadStorage.h:78
LogVar
Class to store variables with their name which were sent to the logging service.
Definition: LogVariableStream.h:24
Belle2::FileSystem::fileExists
static bool fileExists(const std::string &filename)
Check if the file with given filename exists.
Definition: FileSystem.cc:33
alignment.constraints_generator.filename
filename
File name.
Definition: constraints_generator.py:224
Belle2::Conditions::TestingPayloadStorage::writePayload
bool writePayload(const std::string &fileName, const std::string &name, const TObject *object)
Write a payload file from the given object and name.
Definition: TestingPayloadStorage.cc:220
Belle2::Conditions::TestingPayloadStorage::m_absoluteFilename
std::string m_absoluteFilename
Storage file where to look for payloads converted to an absolute path to be robust against directory ...
Definition: TestingPayloadStorage.h:74
Belle2::Conditions::TestingPayloadStorage::payloadFilename
static std::string payloadFilename(const std::string &path, const std::string &name, int revision)
Build the filename for a new payload with a given name and revision in a directory.
Definition: TestingPayloadStorage.cc:135