JobInfo.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2017-2021 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 Note
28  Included by global/globals.C
29 
30 \*---------------------------------------------------------------------------*/
31 
32 #include "JobInfo.H"
33 #include "clock.H"
34 #include "OFstream.H"
35 #include "OSspecific.H"
36 #include "Pstream.H"
37 #include "foamVersion.H"
38 
39 // Fallback for job-control directory is in the user-directory
40 // ~/.OpenFOAM/jobControl
41 
42 #ifndef FOAM_RESOURCE_USER_CONFIG_DIRNAME
43 #define FOAM_RESOURCE_USER_CONFIG_DIRNAME ".OpenFOAM"
44 #ifdef FULLDEBUG
45  #warning FOAM_RESOURCE_USER_CONFIG_DIRNAME was undefined (now ".OpenFOAM")
46 #endif
47 #endif
48 
49 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
50 
53 
54 // Foam::JobInfo::constructed defined in globals.C
55 
56 
57 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
58 
59 namespace Foam
60 {
61 
62 // Ensure given directory exists (called on master only)
63 static inline bool ensureJobDirExists(const fileName& dir)
64 {
65  if (!Foam::isDir(dir) && !Foam::mkDir(dir))
66  {
67  std::cerr
68  << "WARNING: no JobInfo directory: " << dir << nl
69  << " disabling JobInfo" << nl;
70 
71  return false;
72  }
73 
74  return true;
75 }
76 
77 
78 // Write dictionary entries (called on master only)
79 static inline bool writeJobDict(Ostream& os, const dictionary& dict)
80 {
81  if (os.good())
82  {
83  dict.writeEntries(os, true); // With extraNewLine=true
84  return true;
85  }
86 
87  return false;
88 }
89 
90 } // End namespace Foam
91 
92 
93 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
94 
96 {
97  writeJobInfo = false;
98 }
99 
102 {
103  jobInfo.jobEnding();
104 }
105 
106 
107 void Foam::JobInfo::shutdown(bool isAbort)
108 {
109  if (isAbort)
110  {
111  jobInfo.jobEnding("abort");
112  }
113  else
114  {
115  jobInfo.jobEnding("exit");
116  }
117 }
118 
119 
120 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
121 
122 void Foam::JobInfo::jobEnding()
123 {
124  if (!running_.empty())
125  {
126  if (!Foam::mv(running_, finished_))
127  {
128  Foam::rm(running_);
129  }
130  }
131 
132  running_.clear();
133  finished_.clear();
134  constructed = false;
135 }
136 
137 
138 void Foam::JobInfo::jobEnding(const word& terminationType)
139 {
140  if (writeJobInfo && !finished_.empty())
141  {
142  add("cpuTime", cpuTime_.elapsedCpuTime());
143  add("endDate", clock::date());
144  add("endTime", clock::clockTime());
145 
146  if (!terminationType.empty() && !found("termination"))
147  {
148  add("termination", terminationType);
149  }
150 
151  Foam::rm(running_);
152  OFstream os(finished_);
153  if (!writeJobDict(os, *this))
154  {
155  std::cerr
156  << "WARNING: could not write JobInfo file: "
157  << finished_ << nl;
158  }
159  }
160 
161  running_.clear();
162  finished_.clear();
163  constructed = false;
164 }
165 
166 
167 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
168 
170 {
171  if (constructed)
172  {
173  std::cerr
174  << "WARNING: JobInfo was already constructed. "
175  "Should be a singleton!!" << nl;
176  }
177 
178  // Only populate on master process, and when enabled
179  if (writeJobInfo && Pstream::master())
180  {
181  string jobDir = Foam::getEnv("FOAM_JOB_DIR");
182  if (jobDir.empty())
183  {
184  jobDir = home()/FOAM_RESOURCE_USER_CONFIG_DIRNAME/"jobControl";
185  }
186  string jobFile = hostName() + '.' + Foam::name(pid());
187  running_ = jobDir/"runningJobs"/jobFile;
188  finished_ = jobDir/"finishedJobs"/jobFile;
189 
190  if
191  (
192  !ensureJobDirExists(jobDir)
193  || !ensureJobDirExists(running_.path())
194  || !ensureJobDirExists(finished_.path())
195  )
196  {
197  running_.clear();
198  finished_.clear();
199  }
200  }
201 
202  dictionary::name() = "JobInfo";
203  constructed = true;
204 }
205 
206 
207 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
208 
210 {
211  jobEnding();
212 }
213 
214 
215 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
216 
217 void Foam::JobInfo::write() const
218 {
219  if (writeJobInfo && !running_.empty())
220  {
221  OFstream os(running_);
222  if (!writeJobDict(os, *this))
223  {
224  std::cerr
225  << "WARNING: could not write JobInfo file: "
226  << running_ << nl;
227 
228  // Normally does not happen
229  const_cast<fileName&>(running_).clear();
230  }
231  }
232 }
233 
235 void Foam::JobInfo::stop() { jobEnding("normal"); }
236 
237 void Foam::JobInfo::exit() { jobEnding("exit"); }
238 
239 void Foam::JobInfo::abort() { jobEnding("abort"); }
240 
241 void Foam::JobInfo::signalEnd() { jobEnding(); }
242 
243 
244 // ************************************************************************* //
JobInfo()
Default construct.
Definition: JobInfo.C:162
dictionary dict
static bool writeJobDict(Ostream &os, const dictionary &dict)
Definition: JobInfo.C:72
bool mv(const fileName &src, const fileName &dst, const bool followLink=false)
Rename src to dst.
Definition: POSIX.C:1324
A class for handling file names.
Definition: fileName.H:72
Helper class for recording information about run/finished jobs, acts like global singleton.
Definition: JobInfo.H:60
~JobInfo()
Destructor, relocates the job file from running to finished.
Definition: JobInfo.C:202
Output to file stream, using an OSstream.
Definition: OFstream.H:49
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
static void shutdown()
Simple shutdown (finalize) of JobInfo.
Definition: JobInfo.C:94
string getEnv(const std::string &envName)
Get environment value for given envName.
Definition: POSIX.C:339
fileName home()
Return home directory path name for the current user.
Definition: POSIX.C:440
int infoSwitch(const char *name, const int deflt=0)
Lookup info switch or add default value.
Definition: debug.C:228
const fileName & name() const noexcept
The dictionary name.
Definition: dictionaryI.H:41
static std::string date()
The current wall-clock date as a string formatted as (MON dd yyyy), where MON is Jan, Feb, etc.
Definition: clock.C:73
void signalEnd()
Relocate job file from "running" to "finished" directory.
Definition: JobInfo.C:234
static void disable() noexcept
Disallow JobInfo by forcing writeJobInfo (InfoSwitch) off.
Definition: JobInfo.C:88
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition: POSIX.C:860
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
bool mkDir(const fileName &pathName, mode_t mode=0777)
Make a directory and return an error if it could not be created.
Definition: POSIX.C:614
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
void write() const
Write job info to its file in the "running" jobs directory.
Definition: JobInfo.C:210
#define FOAM_RESOURCE_USER_CONFIG_DIRNAME
Definition: JobInfo.C:36
static std::string clockTime()
The current wall-clock (in local time) as a string formatted as as (hh:mm:ss).
Definition: clock.C:88
patchWriters clear()
string hostName()
Return the system&#39;s host name, as per hostname(1)
Definition: POSIX.C:371
pid_t pid()
Return the PID of this process.
Definition: POSIX.C:314
const direction noexcept
Definition: Scalar.H:258
void add(FieldField< Field1, typename typeOfSum< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
OBJstream os(runTime.globalPath()/outputName)
void stop()
Job end with "normal" termination.
Definition: JobInfo.C:228
bool good() const noexcept
True if next operation might succeed.
Definition: IOstream.H:281
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition: UPstream.H:1082
JobInfo jobInfo
Definition: JobInfo.C:45
static bool writeJobInfo
Global value for writeJobInfo enabled.
Definition: JobInfo.H:120
static bool ensureJobDirExists(const fileName &dir)
Definition: JobInfo.C:56
void abort()
Job end with "abort" termination.
Definition: JobInfo.C:232
bool found
void writeEntries(Ostream &os, const bool extraNewLine=false) const
Write dictionary entries.
Definition: dictionaryIO.C:173
Namespace for OpenFOAM.
void exit()
Job end with "exit" termination.
Definition: JobInfo.C:230
bool rm(const fileName &file)
Remove a file (or its gz equivalent), returning true if successful.
Definition: POSIX.C:1404