CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
StorageFactory.cc
Go to the documentation of this file.
10 #include <boost/shared_ptr.hpp>
11 
13 
15  : m_cacheHint(CACHE_HINT_AUTO_DETECT),
16  m_readHint(READ_HINT_AUTO),
17  m_accounting (false),
18  m_tempfree (4.), // GB
19  m_temppath (".:$TMPDIR"),
20  m_timeout(0U),
21  m_debugLevel(0U)
22 {
24 }
25 
27 {
28 }
29 
32 { return &s_instance; }
33 
34 bool
36 {
37  bool old = m_accounting;
38  m_accounting = enabled;
39  return old;
40 }
41 
42 bool
44 { return m_accounting; }
45 
46 void
48 { m_cacheHint = value; }
49 
52 { return m_cacheHint; }
53 
54 void
56 { m_readHint = value; }
57 
60 { return m_readHint; }
61 
62 void
63 StorageFactory::setTimeout(unsigned int timeout)
64 { m_timeout = timeout; }
65 
66 unsigned int
68 { return m_timeout; }
69 
70 void
72 { m_debugLevel = level; }
73 
74 unsigned int
76 { return m_debugLevel; }
77 
78 void
79 StorageFactory::setTempDir(const std::string &s, double minFreeSpace)
80 {
81 #if 0
82  std::cerr /* edm::LogInfo("StorageFactory") */
83  << "Considering path '" << s
84  << "', min free space " << minFreeSpace
85  << "GB for temp dir" << std::endl;
86 #endif
87 
88  size_t begin = 0;
89  std::vector<std::string> dirs;
90  dirs.reserve(std::count(s.begin(), s.end(), ':') + 1);
91 
92  while (true)
93  {
94  size_t end = s.find(':', begin);
95  if (end == std::string::npos)
96  {
97  dirs.push_back(s.substr(begin, end));
98  break;
99  }
100  else
101  {
102  dirs.push_back(s.substr(begin, end - begin));
103  begin = end+1;
104  }
105  }
106 
107  m_temppath = s;
108  m_tempfree = minFreeSpace;
109  m_tempdir = m_lfs.findCachePath(dirs, minFreeSpace);
110 
111 #if 0
112  std::cerr /* edm::LogInfo("StorageFactory") */
113  << "Using '" << m_tempdir << "' for temp dir"
114  << std::endl;
115 #endif
116 }
117 
120 { return m_tempdir; }
121 
124 { return m_temppath; }
125 
126 double
128 { return m_tempfree; }
129 
130 StorageMaker *
132 {
133  auto itFound = m_makers.find(proto);
134  if(itFound != m_makers.end()) {
135  return itFound->second.get();
136  }
139  }
140  std::shared_ptr<StorageMaker> instance{ StorageMakerFactory::get()->tryToCreate(proto)};
141  auto insertResult = m_makers.insert(MakerTable::value_type(proto,instance));
142  //Can't use instance since it is possible that another thread beat
143  // us to the insertion so the map contains a different instance.
144  return insertResult.first->second.get();
145 }
146 
147 StorageMaker *
149  std::string &protocol,
150  std::string &rest)
151 {
152  size_t p = url.find(':');
153  if (p != std::string::npos)
154  {
155  protocol = url.substr(0,p);
156  rest = url.substr(p+1);
157  }
158  else
159  {
160  protocol = "file";
161  rest = url;
162  }
163 
164  return getMaker (protocol);
165 }
166 
167 Storage *
168 StorageFactory::open (const std::string &url, int mode /* = IOFlags::OpenRead */)
169 {
170  std::string protocol;
171  std::string rest;
172  Storage *ret = 0;
173  boost::shared_ptr<StorageAccount::Stamp> stats;
174  if (StorageMaker *maker = getMaker (url, protocol, rest))
175  {
176  maker->setDebugLevel(m_debugLevel);
177  if (m_accounting)
178  stats.reset(new StorageAccount::Stamp(StorageAccount::counter (protocol, "open")));
179  try
180  {
181  if (Storage *storage = maker->open (protocol, rest, mode))
182  {
183  if (dynamic_cast<LocalCacheFile *>(storage))
184  protocol = "local-cache";
185 
186  if (m_accounting)
187  ret = new StorageAccountProxy(protocol, storage);
188  else
189  ret = storage;
190 
191  if (stats)
192  stats->tick();
193  }
194  }
195  catch (cms::Exception &err)
196  {
197  err.addContext("Calling StorageFactory::open()");
198  err.addAdditionalInfo(err.message());
199  err.clearMessage();
200  err << "Failed to open the file '" << url << "'";
201  throw;
202  }
203  }
204  return ret;
205 }
206 
207 void
209 {
210  std::string protocol;
211  std::string rest;
212 
213  boost::shared_ptr<StorageAccount::Stamp> stats;
214  if (StorageMaker *maker = getMaker (url, protocol, rest))
215  {
216  if (m_accounting)
217  stats.reset(new StorageAccount::Stamp(StorageAccount::counter (protocol, "stagein")));
218  try
219  {
220  maker->stagein (protocol, rest);
221  if (stats) stats->tick();
222  }
223  catch (cms::Exception &err)
224  {
225  edm::LogWarning("StorageFactory::stagein()")
226  << "Failed to stage in file '" << url << "' because:\n"
227  << err.explainSelf();
228  }
229  }
230 }
231 
232 bool
234 {
235  std::string protocol;
236  std::string rest;
237 
238  bool ret = false;
239  boost::shared_ptr<StorageAccount::Stamp> stats;
240  if (StorageMaker *maker = getMaker (url, protocol, rest))
241  {
242  if (m_accounting)
243  stats.reset(new StorageAccount::Stamp(StorageAccount::counter (protocol, "check")));
244  try
245  {
246  ret = maker->check (protocol, rest, size);
247  if (stats) stats->tick();
248  }
249  catch (cms::Exception &err)
250  {
251  edm::LogWarning("StorageFactory::check()")
252  << "Existence or size check for the file '" << url << "' failed because:\n"
253  << err.explainSelf();
254  }
255  }
256 
257  return ret;
258 }
259 
260 Storage *
262  const std::string &proto,
263  const std::string &path,
264  int mode)
265 {
268  {
269  if (mode & IOFlags::OpenWrite)
270  {
271  // For now, issue no warning - otherwise, we'd always warn on output files.
272  }
273  else if (m_tempdir.empty())
274  {
276  }
277  else if (path.empty() || m_lfs.isLocalPath(path))
278  {
279  // For now, issue no warning - otherwise, we'd always warn on local input files.
280  }
281  else
282  {
283  if (accounting()) {s = new StorageAccountProxy(proto, s);}
284  s = new LocalCacheFile(s, m_tempdir);
285  }
286  }
287 
288  return s;
289 }
290 
291 void
293 {
294  std::string protocol;
295  std::string rest;
296 
297  if (StorageMaker *maker = getMaker (url, protocol, rest))
298  {
299  maker->setTimeout (m_timeout);
300  }
301 }
302 
303 
CacheHint cacheHint(void) const
void stagein(const std::string &url)
bool enableAccounting(bool enabled)
static PluginManager & configure(const Config &)
std::string tempPath(void) const
void setTimeout(unsigned int timeout)
static PFTauRenderPlugin instance
std::string m_tempdir
virtual std::string explainSelf() const
Definition: Exception.cc:146
void setReadHint(ReadHint value)
Storage * open(const std::string &url, int mode=IOFlags::OpenRead)
bool check(const std::string &url, IOOffset *size=0)
ReadHint m_readHint
std::string message() const
Definition: Exception.cc:187
unsigned int m_debugLevel
std::string findCachePath(const std::vector< std::string > &paths, double minFreeSpace)
StorageMaker * getMaker(const std::string &proto)
double tempMinFree(void) const
Storage * wrapNonLocalFile(Storage *s, const std::string &proto, const std::string &path, int mode)
bool isLocalPath(const std::string &path)
static StorageFactory * get(void)
tuple path
else: Piece not in the list, fine.
PluginManager::Config config()
Definition: standard.cc:21
std::string tempDir(void) const
unsigned int timeout(void) const
void addAdditionalInfo(std::string const &info)
Definition: Exception.cc:235
#define end
Definition: vmac.h:37
void setDebugLevel(unsigned int level)
Container::value_type value_type
CacheHint m_cacheHint
void clearMessage()
Definition: Exception.cc:215
std::string m_temppath
static Counter & counter(const std::string &storageClass, const std::string &operation)
ReadHint readHint(void) const
void addContext(std::string const &context)
Definition: Exception.cc:227
int64_t IOOffset
Definition: IOTypes.h:19
bool accounting(void) const
void setTempDir(const std::string &s, double minFreeSpace)
static StorageFactory s_instance
void setCacheHint(CacheHint value)
unsigned int m_timeout
#define begin
Definition: vmac.h:30
void activateTimeout(const std::string &url)
tuple level
Definition: testEve_cfg.py:34
volatile std::atomic< bool > shutdown_flag false
MakerTable m_makers
LocalFileSystem m_lfs
tuple size
Write out results.
T get(const Candidate &c)
Definition: component.h:55
unsigned int debugLevel(void) const