ATLAS Offline Software
DiskWriterXRD.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 
8 //
9 // includes
10 //
11 
13 
14 #include <RootCoreUtils/Assert.h>
16 #include <RootCoreUtils/ThrowMsg.h>
17 #include <TFile.h>
18 #include <TSystem.h>
19 #include <format>
20 #include <boost/functional/hash.hpp>
21 #include <chrono>
22 #include <iostream>
23 #include <random>
24 #include <sstream>
25 #include <sys/types.h>
26 #include <thread>
27 #include <unistd.h>
28 
29 //
30 // method implementations
31 //
32 
33 namespace SH
34 {
36  testInvariant () const
37  {
38  }
39 
40 
41 
43  DiskWriterXRD (const std::string& val_path)
44  : m_path (val_path)
45  {
46  RCU_REQUIRE (val_path.find ("root://") == 0);
47 
48  const char *tmpdir = getenv ("TMPDIR");
49  std::size_t hash {0};
50  boost::hash_combine (hash, std::hash<pid_t>() (getpid()));
51  std::size_t tries = 0;
52  while (m_file == nullptr || !m_file->IsOpen())
53  {
54  if (++ tries == 10)
55  throw std::runtime_error ("infinite loop trying to create tempory file for DiskWriterXRD");
56 
57  auto time = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
58  boost::hash_combine (hash, std::hash<decltype(time)>() (time));
59  std::size_t hash16 {hash};
60  while (hash16 > 0xffff)
61  hash16 = (hash16&0xffff) ^ (hash16 >> 16);
62 
63  std::ostringstream str;
64  if (tmpdir)
65  str << tmpdir;
66  else
67  str << "/tmp";
68  str << "/SH-XRD-" << m_path.substr (m_path.rfind ("/")+1)
69  << "-" << std::format("{:04x}", hash16);
70  m_tmp = str.str();
71  if (gSystem->AccessPathName (m_tmp.c_str()) != 0)
72  m_file.reset (TFile::Open (m_tmp.c_str(), "CREATE"));
73  }
74 
75  RCU_NEW_INVARIANT (this);
76  }
77 
78 
79 
82  {
83  RCU_DESTROY_INVARIANT (this);
84 
85  if (m_file != nullptr)
86  {
87  try
88  {
89  close ();
90  } catch (std::exception& e)
91  {
92  std::cerr << "exception closing file " << m_path << ": "
93  << e.what() << std::endl;
94 
95  } catch (...)
96  {
97  std::cerr << "unknown exception closing file " << m_path << std::endl;
98  }
99  }
100  }
101 
102 
103 
104  std::string DiskWriterXRD ::
105  getPath () const
106  {
107  RCU_READ_INVARIANT (this);
108  return m_path;
109  }
110 
111 
112 
114  getFile ()
115  {
116  RCU_CHANGE_INVARIANT (this);
117  RCU_REQUIRE2_SOFT (m_file != nullptr, "file already closed");
118  return m_file.get();
119  }
120 
121 
122 
124  doClose ()
125  {
126  RCU_CHANGE_INVARIANT (this);
127  RCU_REQUIRE2_SOFT (m_file != nullptr, "file already closed");
128 
129  if (m_file->IsOpen())
130  {
131  if (m_file->Write () < 0)
132  RCU_THROW_MSG ("failed to write to file: " + m_path);
133  m_file->Close ();
134  }
135 
136  std::random_device rd;
137  std::mt19937 gen (rd());
138  bool success = false;
139  unsigned tries = 0u;
140  while (!success)
141  {
142  try
143  {
144  // using the -f flag, because if this copy failed previously
145  // we need to force an overwrite. note that there would be no
146  // point in leaving this out on the first try (even though
147  // there should be no file there), because it would just fail
148  // and retry with the flag set.
150  success = true;
151  } catch (...)
152  {
153  std::cerr << "encountered error copying files to XRD path: \"" << m_path << "\"" << std::endl;
154  if (tries < 10u)
155  {
156  tries += 1;
157  // sleeping for a random period of time, to reduce the
158  // chance that the problem is that multiple jobs finishing
159  // at the same time keep overloading the server by
160  // repeatedly hitting it at the same time.
161  unsigned seconds = std::uniform_int_distribution<>(30,60) (gen);
162  std::cerr << "sleeping for " << seconds << " seconds before retrying" << std::endl;
163  std::this_thread::sleep_for (std::chrono::seconds(seconds));
164  } else
165  {
166  std::cerr << "giving up, leaving file at " << m_tmp << std::endl;
167  throw std::runtime_error ("failed to copy file to XRD");
168  }
169  }
170  }
172  m_file.reset ();
173  }
174 }
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
vtune_athena.format
format
Definition: vtune_athena.py:14
DiskWriterXRD.h
RCU_REQUIRE
#define RCU_REQUIRE(x)
Definition: Assert.h:208
ShellExec.h
Assert.h
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:77
master.gen
gen
Definition: master.py:32
SH::DiskWriterXRD::m_file
std::unique_ptr< TFile > m_file
the actual file object
Definition: DiskWriterXRD.h:86
SH::DiskWriterXRD::testInvariant
void testInvariant() const
test the invariant of this object
Definition: DiskWriterXRD.cxx:36
python.handimod.now
now
Definition: handimod.py:675
m_path
std::string m_path
the path being used
Definition: OutputStreamData.cxx:88
calibdata.exception
exception
Definition: calibdata.py:496
SH::DiskWriterXRD::getFile
virtual TFile * getFile() override
the file we are writing to
Definition: DiskWriterXRD.cxx:114
python.LArCalib_HVCorrConfig.seconds
seconds
Definition: LArCalib_HVCorrConfig.py:86
SH::DiskWriterXRD::DiskWriterXRD
DiskWriterXRD(const std::string &val_path)
standard constructor
Definition: DiskWriterXRD.cxx:43
beamspotman.tmpdir
string tmpdir
Definition: beamspotman.py:412
SH::DiskWriterXRD::doClose
virtual void doClose() override
closes the file we are writing to
Definition: DiskWriterXRD.cxx:124
SH::DiskWriterXRD::m_path
std::string m_path
the path being used
Definition: DiskWriterXRD.h:82
ThrowMsg.h
RCU_REQUIRE2_SOFT
#define RCU_REQUIRE2_SOFT(x, y)
Definition: Assert.h:155
SH::DiskWriterXRD::getPath
virtual std::string getPath() const override
the path where this file can be accessed or the empty string if it is not known (yet).
Definition: DiskWriterXRD.cxx:105
SCT_ConditionsAlgorithms::CoveritySafe::getenv
std::string getenv(const std::string &variableName)
get an environment variable
Definition: SCT_ConditionsUtilities.cxx:17
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:109
RCU_DESTROY_INVARIANT
#define RCU_DESTROY_INVARIANT(x)
Definition: Assert.h:235
python.CaloScaleNoiseConfig.str
str
Definition: CaloScaleNoiseConfig.py:78
RCU::Shell::exec
void exec(const std::string &cmd)
effects: execute the given command guarantee: strong failures: out of memory II failures: system fail...
Definition: ShellExec.cxx:29
SH::DiskWriterXRD::~DiskWriterXRD
~DiskWriterXRD()
standard destructor
Definition: DiskWriterXRD.cxx:81
RCU_CHANGE_INVARIANT
#define RCU_CHANGE_INVARIANT(x)
Definition: Assert.h:231
str
Definition: BTagTrackIpAccessor.cxx:11
SH
This module provides a lot of global definitions, forward declarations and includes that are used by ...
Definition: PrunDriver.h:15
RCU_THROW_MSG
#define RCU_THROW_MSG(message)
Definition: PrintMsg.h:58
SH::DiskWriter::close
void close()
closes the file we are writing to
Definition: DiskWriter.cxx:67
RCU_READ_INVARIANT
#define RCU_READ_INVARIANT(x)
Definition: Assert.h:229
RCU::Shell::quote
std::string quote(const std::string &name)
effects: quote the given name to protect it from the shell returns: the quoted name guarantee: strong...
Definition: ShellExec.cxx:75
SH::DiskWriterXRD::m_tmp
std::string m_tmp
the temporary path being used
Definition: DiskWriterXRD.h:78
RCU_NEW_INVARIANT
#define RCU_NEW_INVARIANT(x)
Definition: Assert.h:233