CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
StorageFactory.cc
Go to the documentation of this file.
1 #include <memory>
2 
12 
13 using namespace edm::storage;
14 
16 
18  : m_cacheHint(CACHE_HINT_AUTO_DETECT),
19  m_readHint(READ_HINT_AUTO),
20  m_accounting(false),
21  m_tempfree(4.), // GB
22  m_temppath(".:$TMPDIR"),
23  m_timeout(0U),
24  m_debugLevel(0U) {
26 }
27 
29 
31 
33 
35  bool old = m_accounting;
37  return old;
38 }
39 
40 bool StorageFactory::accounting(void) const { return m_accounting; }
41 
43 
45 
47 
49 
51 
52 unsigned int StorageFactory::timeout(void) const { return m_timeout; }
53 
55 
56 unsigned int StorageFactory::debugLevel(void) const { return m_debugLevel; }
57 
58 void StorageFactory::setTempDir(const std::string &s, double minFreeSpace) {
59 #if 0
60  std::cerr /* edm::LogInfo("StorageFactory") */
61  << "Considering path '" << s
62  << "', min free space " << minFreeSpace
63  << "GB for temp dir" << std::endl;
64 #endif
65 
66  size_t begin = 0;
67  std::vector<std::string> dirs;
68  dirs.reserve(std::count(s.begin(), s.end(), ':') + 1);
69 
70  while (true) {
71  size_t end = s.find(':', begin);
72  if (end == std::string::npos) {
73  dirs.push_back(s.substr(begin, end));
74  break;
75  } else {
76  dirs.push_back(s.substr(begin, end - begin));
77  begin = end + 1;
78  }
79  }
80 
81  m_temppath = s;
82  m_tempfree = minFreeSpace;
83  std::tie(m_tempdir, m_unusableDirWarnings) = m_lfs.findCachePath(dirs, minFreeSpace);
84 
85 #if 0
86  std::cerr /* edm::LogInfo("StorageFactory") */
87  << "Using '" << m_tempdir << "' for temp dir"
88  << std::endl;
89 #endif
90 }
91 
93 
95 
96 double StorageFactory::tempMinFree(void) const { return m_tempfree; }
97 
99  auto itFound = m_makers.find(proto);
100  if (itFound != m_makers.end()) {
101  return itFound->second.get();
102  }
105  }
106  std::shared_ptr<StorageMaker> instance{StorageMakerFactory::get()->tryToCreate(proto)};
107  auto insertResult = m_makers.insert(MakerTable::value_type(proto, instance));
108  //Can't use instance since it is possible that another thread beat
109  // us to the insertion so the map contains a different instance.
110  return insertResult.first->second.get();
111 }
112 
114  size_t p = url.find(':');
115  if (p != std::string::npos) {
116  protocol = url.substr(0, p);
117  rest = url.substr(p + 1);
118  } else {
119  protocol = "file";
120  rest = url;
121  }
122 
123  return getMaker(protocol);
124 }
125 
126 std::unique_ptr<Storage> StorageFactory::open(const std::string &url, int mode /* = IOFlags::OpenRead */) const {
127  std::string protocol;
128  std::string rest;
129  std::unique_ptr<Storage> ret;
130  std::unique_ptr<StorageAccount::Stamp> stats;
131  if (StorageMaker *maker = getMaker(url, protocol, rest)) {
132  if (m_accounting) {
134  stats = std::make_unique<StorageAccount::Stamp>(StorageAccount::counter(token, StorageAccount::Operation::open));
135  }
136  try {
137  if (auto storage = maker->open(
139  if (dynamic_cast<LocalCacheFile *>(storage.get()))
140  protocol = "local-cache";
141 
142  if (m_accounting)
143  ret = std::make_unique<StorageAccountProxy>(protocol, std::move(storage));
144  else
145  ret = std::move(storage);
146 
147  if (stats)
148  stats->tick();
149  }
150  } catch (cms::Exception &err) {
151  err.addContext("Calling StorageFactory::open()");
152  err.addAdditionalInfo(err.message());
153  err.clearMessage();
154  err << "Failed to open the file '" << url << "'";
155  throw;
156  }
157  }
158  return ret;
159 }
160 
161 void StorageFactory::stagein(const std::string &url) const {
162  std::string protocol;
163  std::string rest;
164 
165  std::unique_ptr<StorageAccount::Stamp> stats;
166  if (StorageMaker *maker = getMaker(url, protocol, rest)) {
167  if (m_accounting) {
168  auto token = StorageAccount::tokenForStorageClassName(protocol);
169  stats =
170  std::make_unique<StorageAccount::Stamp>(StorageAccount::counter(token, StorageAccount::Operation::stagein));
171  }
172  try {
173  maker->stagein(protocol, rest, StorageMaker::AuxSettings{}.setDebugLevel(m_debugLevel).setTimeout(m_timeout));
174  if (stats)
175  stats->tick();
176  } catch (cms::Exception &err) {
177  edm::LogWarning("StorageFactory::stagein()") << "Failed to stage in file '" << url << "' because:\n"
178  << err.explainSelf();
179  }
180  }
181 }
182 
183 bool StorageFactory::check(const std::string &url, IOOffset *size /* = 0 */) const {
184  std::string protocol;
185  std::string rest;
186 
187  bool ret = false;
188  std::unique_ptr<StorageAccount::Stamp> stats;
189  if (StorageMaker *maker = getMaker(url, protocol, rest)) {
190  if (m_accounting) {
191  auto token = StorageAccount::tokenForStorageClassName(protocol);
192  stats = std::make_unique<StorageAccount::Stamp>(StorageAccount::counter(token, StorageAccount::Operation::check));
193  }
194  try {
195  ret = maker->check(
196  protocol, rest, StorageMaker::AuxSettings{}.setDebugLevel(m_debugLevel).setTimeout(m_timeout), size);
197  if (stats)
198  stats->tick();
199  } catch (cms::Exception &err) {
200  edm::LogWarning("StorageFactory::check()")
201  << "Existence or size check for the file '" << url << "' failed because:\n"
202  << err.explainSelf();
203  }
204  }
205 
206  return ret;
207 }
208 
209 std::unique_ptr<Storage> StorageFactory::wrapNonLocalFile(std::unique_ptr<Storage> s,
210  const std::string &proto,
211  const std::string &path,
212  int mode) const {
213  StorageFactory::CacheHint hint = cacheHint();
214  if ((hint == StorageFactory::CACHE_HINT_LAZY_DOWNLOAD) || (mode & IOFlags::OpenWrap)) {
215  if (mode & IOFlags::OpenWrite) {
216  // For now, issue no warning - otherwise, we'd always warn on output files.
217  } else if (m_tempdir.empty()) {
218  edm::LogWarning("StorageFactory") << m_unusableDirWarnings;
219  } else if ((not path.empty()) and m_lfs.isLocalPath(path)) {
220  // For now, issue no warning - otherwise, we'd always warn on local input files.
221  } else {
222  if (accounting()) {
223  s = std::make_unique<StorageAccountProxy>(proto, std::move(s));
224  }
225  s = std::make_unique<LocalCacheFile>(std::move(s), m_tempdir);
226  }
227  }
228 
229  return s;
230 }
std::string tempDir(void) const
int64_t IOOffset
Definition: IOTypes.h:20
tuple ret
prodAgent to be discontinued
static StorageClassToken tokenForStorageClassName(std::string const &iName)
double tempMinFree(void) const
static PluginManager & configure(const Config &)
void setReadHint(ReadHint value)
static PFTauRenderPlugin instance
virtual std::string explainSelf() const
Definition: Exception.cc:108
AuxSettings & setTimeout(unsigned int iTime)
Definition: StorageMaker.h:21
static Counter & counter(StorageClassToken token, Operation operation)
std::pair< std::string, std::string > findCachePath(const std::vector< std::string > &paths, double minFreeSpace) const
void setTimeout(unsigned int timeout)
std::string message() const
Definition: Exception.cc:145
ReadHint readHint(void) const
unsigned int debugLevel(void) const
int timeout
Definition: mps_check.py:53
CacheHint cacheHint(void) const
void setTempDir(const std::string &s, double minFreeSpace)
unsigned int timeout(void) const
bool enableAccounting(bool enabled)
PluginManager::Config config()
Definition: standard.cc:21
static StorageFactory s_instance
StorageMaker * getMaker(const std::string &proto) const
def move
Definition: eostools.py:511
void addAdditionalInfo(std::string const &info)
Definition: Exception.cc:169
void setCacheHint(CacheHint value)
void clearMessage()
Definition: Exception.cc:159
static StorageFactory * getToModify(void)
bool accounting(void) const
void addContext(std::string const &context)
Definition: Exception.cc:165
std::unique_ptr< Storage > open(const std::string &url, int mode=IOFlags::OpenRead) const
static std::atomic< unsigned int > counter
void setDebugLevel(unsigned int level)
string end
Definition: dataset.py:937
AuxSettings & setDebugLevel(unsigned int iLevel)
Definition: StorageMaker.h:16
tuple level
Definition: testEve_cfg.py:47
#define get
Log< level::Warning, false > LogWarning
static const StorageFactory * get(void)
tuple size
Write out results.
std::string tempPath(void) const