ATLAS Offline Software
Loading...
Searching...
No Matches
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
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
33namespace SH
34{
35 void DiskWriterXRD ::
36 testInvariant () const
37 {
38 }
39
40
41
42 DiskWriterXRD ::
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
80 DiskWriterXRD ::
81 ~DiskWriterXRD ()
82 {
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
113 TFile *DiskWriterXRD ::
114 getFile ()
115 {
117 RCU_REQUIRE2_SOFT (m_file != nullptr, "file already closed");
118 return m_file.get();
119 }
120
121
122
123 void DiskWriterXRD ::
124 doClose ()
125 {
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}
#define RCU_DESTROY_INVARIANT(x)
Definition Assert.h:235
#define RCU_CHANGE_INVARIANT(x)
Definition Assert.h:231
#define RCU_REQUIRE2_SOFT(x, y)
Definition Assert.h:155
#define RCU_NEW_INVARIANT(x)
Definition Assert.h:233
#define RCU_REQUIRE(x)
Definition Assert.h:208
#define RCU_READ_INVARIANT(x)
Definition Assert.h:229
#define RCU_THROW_MSG(message)
Definition PrintMsg.h:58
std::string m_tmp
the temporary path being used
std::string m_path
the path being used
std::unique_ptr< TFile > m_file
the actual file object
void close()
closes the file we are writing to
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
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
This module provides a lot of global definitions, forward declarations and includes that are used by ...
Definition PrunDriver.h:15