ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
PhysicsAnalysis
D3PDTools
SampleHandler
Root
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
12
#include <
SampleHandler/DiskWriterXRD.h
>
13
14
#include <
RootCoreUtils/Assert.h
>
15
#include <
RootCoreUtils/ShellExec.h
>
16
#include <TFile.h>
17
#include <TSystem.h>
18
#include <format>
19
#include <boost/functional/hash.hpp>
20
#include <chrono>
21
#include <iostream>
22
#include <random>
23
#include <sstream>
24
#include <stdexcept>
25
#include <sys/types.h>
26
#include <thread>
27
#include <unistd.h>
28
29
//
30
// method implementations
31
//
32
33
namespace
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
{
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
113
TFile *DiskWriterXRD ::
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
123
void
DiskWriterXRD ::
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
throw
std::runtime_error (
"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.
149
RCU::Shell::exec
(
"xrdcp -f "
+
RCU::Shell::quote
(
m_tmp
) +
" "
+
RCU::Shell::quote
(
m_path
));
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
}
171
RCU::Shell::exec
(
"rm "
+
RCU::Shell::quote
(
m_tmp
));
172
m_file
.reset ();
173
}
174
}
Assert.h
RCU_DESTROY_INVARIANT
#define RCU_DESTROY_INVARIANT(x)
Definition
Assert.h:223
RCU_CHANGE_INVARIANT
#define RCU_CHANGE_INVARIANT(x)
Definition
Assert.h:219
RCU_REQUIRE2_SOFT
#define RCU_REQUIRE2_SOFT(x, y)
Definition
Assert.h:143
RCU_NEW_INVARIANT
#define RCU_NEW_INVARIANT(x)
Definition
Assert.h:221
RCU_REQUIRE
#define RCU_REQUIRE(x)
Definition
Assert.h:196
RCU_READ_INVARIANT
#define RCU_READ_INVARIANT(x)
Definition
Assert.h:217
DiskWriterXRD.h
ShellExec.h
SH::DiskWriterXRD::m_tmp
std::string m_tmp
the temporary path being used
Definition
DiskWriterXRD.h:78
SH::DiskWriterXRD::m_path
std::string m_path
the path being used
Definition
DiskWriterXRD.h:82
SH::DiskWriterXRD::m_file
std::unique_ptr< TFile > m_file
the actual file object
Definition
DiskWriterXRD.h:86
SH::DiskWriter::close
void close()
closes the file we are writing to
Definition
DiskWriter.cxx:67
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:27
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:65
SH
This module provides a lot of global definitions, forward declarations and includes that are used by ...
Definition
PrunDriver.h:15
str
Definition
BTagTrackIpAccessor.cxx:11
Generated on
for ATLAS Offline Software by
1.17.0