preCICE v3.3.0
Loading...
Searching...
No Matches
ConnectionInfoPublisher.cpp
Go to the documentation of this file.
1#include <algorithm>
2#include <boost/algorithm/string/trim.hpp>
3#include <chrono>
4#include <filesystem>
5#include <fstream>
6#include <stdexcept>
7#include <thread>
8
10#include "logging/LogMacros.hpp"
12#include "utils/Hash.hpp"
13#include "utils/assertion.hpp"
14
15namespace fs = std::filesystem;
16namespace precice::com {
17
19{
20 constexpr int firstLevelLen = 2;
21 std::string const s = std::string(acceptorName).append(tag).append(requesterName).append(std::to_string(rank));
23
24 auto p = fs::path(hash.substr(0, firstLevelLen)) / hash.substr(firstLevelLen);
25
26 return p.string();
27}
28
30{
31 std::string directional = std::string(acceptorName).append("-").append(requesterName);
32
33 auto p = fs::path(addressDirectory.begin(), addressDirectory.end()) / "precice-run" / directional;
34
35 return p.string();
36}
37
42
44{
45 auto local = getLocalDirectory();
47 auto p = fs::path(getLocalDirectory()) / hashed;
48
49 return p.string();
50}
51
53{
54 auto path = getFilename();
55
56 PRECICE_DEBUG("Waiting for connection file \"{}\"", path);
57 const auto waitdelay = std::chrono::milliseconds(1);
58 while (!fs::exists(path)) {
60 }
62 PRECICE_DEBUG("Found connection file \"{}\"", path);
63
64 std::ifstream ifs(path);
65
66 if (!ifs) {
67 PRECICE_DEBUG("Opening connection file \"{}\" failed. Retrying", path);
69 ifs.clear();
70 ifs.open(path);
71 }
72
73 PRECICE_CHECK(ifs,
74 "Unable to establish connection as the connection file \"{}\" couldn't be opened.",
75 path);
76 std::string addressData;
77 std::getline(ifs, addressData);
78 PRECICE_CHECK(!addressData.empty(),
79 "Unable to establish connection as the connection file \"{}\" is empty. "
80 "Please report this bug to the preCICE developers.",
81 path);
82 boost::algorithm::trim_right(addressData);
83 return addressData;
84}
85
87{
88 fs::path path(getFilename());
89 if (!fs::exists(path)) {
90 PRECICE_WARN("Cannot clean-up the connection file \"{}\" as it doesn't exist. "
91 "In case of connection problems, please report this to the preCICE developers.",
92 path.generic_string());
93 return;
94 }
95 PRECICE_DEBUG("Deleting connection file \"{}\"", path.generic_string());
96 try {
97 fs::remove(path);
99 fs::exists(path),
100 "The connection file \"{}\" wasn't properly removed. "
101 "Make sure to delete the \"precice-run\" directory before restarting the simulation.",
102 path.generic_string());
103 } catch (const fs::filesystem_error &e) {
104 PRECICE_WARN("Unable to clean-up connection file due to error: {}. "
105 "Make sure to delete the \"precice-run\" directory before restarting the simulation.",
106 e.what());
107 }
108}
109
111{
112 auto path = getFilename();
113 auto tmp = fs::path(path + "~");
114
115 {
116 auto message = "Unable to establish connection as a {}connection file already exists at \"{}\". "
117 "This is likely a leftover of a previous crash or stop during communication build-up. "
118 "Please remove the \"precice-run\" directory and restart the simulation.";
119 PRECICE_CHECK(!fs::exists(path), message, "", path);
120 PRECICE_CHECK(!fs::exists(tmp), message, "temporary ");
121 }
122
123 PRECICE_DEBUG("Writing temporary connection file \"{}\"", tmp.generic_string());
124 fs::create_directories(tmp.parent_path());
125 {
126 std::ofstream ofs(tmp);
127
128 if (!ofs) {
129 PRECICE_DEBUG("Opening temporary connection file \"{}\" failed. Retrying", tmp.generic_string());
131 ofs.clear();
132 ofs.open(tmp);
133 }
134
135 PRECICE_CHECK(ofs, "Unable to establish connection as the temporary connection file \"{}\" couldn't be opened.", tmp.generic_string());
136 fmt::print(ofs,
137 "{}\nAcceptor: {}, Requester: {}, Tag: {}, Rank: {}",
139 }
141 "Unable to establish connection as the temporary connection file \"{}\" was written, but doesn't exist on disk. "
142 "Please report this bug to the preCICE developers.",
143 tmp.generic_string());
144
145 PRECICE_DEBUG("Publishing connection file \"{}\"", path);
146 fs::rename(tmp, path);
148 fs::exists(tmp),
149 "The temporary connection file \"{}\" wasn't properly removed. "
150 "Make sure to delete the \"precice-run\" directory before restarting the simulation.",
151 tmp.generic_string());
153 "Unable to establish connection as the connection file \"{}\" doesn't exist on disk. "
154 "Please report this bug to the preCICE developers.",
155 path);
156}
157
158} // namespace precice::com
#define PRECICE_WARN_IF(condition,...)
Definition LogMacros.hpp:18
#define PRECICE_WARN(...)
Definition LogMacros.hpp:12
#define PRECICE_DEBUG(...)
Definition LogMacros.hpp:61
#define PRECICE_CHECK(check,...)
Definition LogMacros.hpp:32
T append(T... args)
#define PRECICE_ASSERT(...)
Definition assertion.hpp:85
T begin(T... args)
std::string getLocalDirectory() const
Returns the local directory which is used to store the hashed part.
std::string getFilename() const
Returns the full path to the hashed filename.
std::string read() const
Reads the info from the connection info file. Will block, if the the file is not present.
void write(std::string_view info) const
Write the string info, e.g. IP:port to the connection info file.
~ConnectionInfoWriter()
Removes the connection info file and the directories ./precice-run/[hash], is empty.
T clear(T... args)
T create_directories(T... args)
T empty(T... args)
T end(T... args)
T exists(T... args)
T generic_string(T... args)
T getline(T... args)
std::string hashedFilePath(std::string_view acceptorName, std::string_view requesterName, std::string_view meshName, Rank rank)
Returns the file name for the connection information.
std::string localDirectory(std::string_view acceptorName, std::string_view requesterName, std::string_view addressDirectory)
contains the data communication abstraction layer.
std::string preciceHash(std::string_view s)
creates a portable hash of the given input
Definition Hash.cpp:10
int Rank
Definition Types.hpp:37
T open(T... args)
T remove(T... args)
T rename(T... args)
T sleep_for(T... args)
T substr(T... args)
T to_string(T... args)