Add resolveHostnamesBlocking() in ConnectionString and IClusterConnectionRecord.

Also, combine IClusterConnectionRecord::getConnectionString() and IClusterConnectionRecord::getMutableConnectionString() to IClusterConnectionRecord::getConnectionString(), and rename setConnectionString() to setAndPersistConnectionString().
This commit is contained in:
Renxuan Wang 2022-01-27 17:43:56 -08:00
parent 2ea4146e1f
commit f9f3735f73
13 changed files with 49 additions and 23 deletions

View File

@ -28,7 +28,7 @@
#include "fdbclient/CoordinationInterface.h" #include "fdbclient/CoordinationInterface.h"
IPAddress determinePublicIPAutomatically(ClusterConnectionString const& ccs) { IPAddress determinePublicIPAutomatically(ClusterConnectionString& ccs) {
try { try {
using namespace boost::asio; using namespace boost::asio;

View File

@ -41,7 +41,7 @@ ClusterConnectionFile::ClusterConnectionFile(std::string const& filename, Cluste
} }
// Sets the connections string held by this object and persists it. // Sets the connections string held by this object and persists it.
Future<Void> ClusterConnectionFile::setConnectionString(ClusterConnectionString const& conn) { Future<Void> ClusterConnectionFile::setAndPersistConnectionString(ClusterConnectionString const& conn) {
ASSERT(filename.size()); ASSERT(filename.size());
cs = conn; cs = conn;
return success(persist()); return success(persist());

View File

@ -35,7 +35,7 @@ public:
explicit ClusterConnectionFile(std::string const& filename, ClusterConnectionString const& contents); explicit ClusterConnectionFile(std::string const& filename, ClusterConnectionString const& contents);
// Sets the connections string held by this object and persists it. // Sets the connections string held by this object and persists it.
Future<Void> setConnectionString(ClusterConnectionString const&) override; Future<Void> setAndPersistConnectionString(ClusterConnectionString const&) override;
// Get the connection string stored in the file. // Get the connection string stored in the file.
Future<ClusterConnectionString> getStoredConnectionString() override; Future<ClusterConnectionString> getStoredConnectionString() override;

View File

@ -57,7 +57,7 @@ ACTOR Future<Reference<ClusterConnectionKey>> ClusterConnectionKey::loadClusterC
} }
// Sets the connections string held by this object and persists it. // Sets the connections string held by this object and persists it.
Future<Void> ClusterConnectionKey::setConnectionString(ClusterConnectionString const& connectionString) { Future<Void> ClusterConnectionKey::setAndPersistConnectionString(ClusterConnectionString const& connectionString) {
cs = connectionString; cs = connectionString;
return success(persist()); return success(persist());
} }

View File

@ -48,7 +48,7 @@ public:
ACTOR static Future<Reference<ClusterConnectionKey>> loadClusterConnectionKey(Database db, Key connectionStringKey); ACTOR static Future<Reference<ClusterConnectionKey>> loadClusterConnectionKey(Database db, Key connectionStringKey);
// Sets the connections string held by this object and persists it. // Sets the connections string held by this object and persists it.
Future<Void> setConnectionString(ClusterConnectionString const&) override; Future<Void> setAndPersistConnectionString(ClusterConnectionString const&) override;
// Get the connection string stored in the database. // Get the connection string stored in the database.
Future<ClusterConnectionString> getStoredConnectionString() override; Future<ClusterConnectionString> getStoredConnectionString() override;

View File

@ -23,7 +23,7 @@
#include "flow/actorcompiler.h" // has to be last include #include "flow/actorcompiler.h" // has to be last include
// Sets the connections string held by this object. // Sets the connections string held by this object.
Future<Void> ClusterConnectionMemoryRecord::setConnectionString(ClusterConnectionString const& conn) { Future<Void> ClusterConnectionMemoryRecord::setAndPersistConnectionString(ClusterConnectionString const& conn) {
cs = conn; cs = conn;
return Void(); return Void();
} }

View File

@ -36,7 +36,7 @@ public:
} }
// Sets the connections string held by this object. // Sets the connections string held by this object.
Future<Void> setConnectionString(ClusterConnectionString const&) override; Future<Void> setAndPersistConnectionString(ClusterConnectionString const&) override;
// Returns the connection string currently held in this object (there is no persistent storage). // Returns the connection string currently held in this object (there is no persistent storage).
Future<ClusterConnectionString> getStoredConnectionString() override; Future<ClusterConnectionString> getStoredConnectionString() override;

View File

@ -75,6 +75,9 @@ public:
std::string toString() const; std::string toString() const;
static std::string getErrorString(std::string const& source, Error const& e); static std::string getErrorString(std::string const& source, Error const& e);
Future<Void> resolveHostnames(); Future<Void> resolveHostnames();
// This one should only be used when resolving asynchronously is impossible. For all other cases, resolveHostnames()
// should be preferred.
void resolveHostnamesBlocking();
void resetToUnresolved(); void resetToUnresolved();
bool hasUnresolvedHostnames = false; bool hasUnresolvedHostnames = false;
@ -105,12 +108,10 @@ public:
// Returns the connection string currently held in this object. This may not match the stored record if it hasn't // Returns the connection string currently held in this object. This may not match the stored record if it hasn't
// been persisted or if the persistent storage for the record has been modified externally. // been persisted or if the persistent storage for the record has been modified externally.
ClusterConnectionString const& getConnectionString() const; ClusterConnectionString& getConnectionString();
ClusterConnectionString* getMutableConnectionString();
// Sets the connections string held by this object and persists it. // Sets the connections string held by this object and persists it.
virtual Future<Void> setConnectionString(ClusterConnectionString const&) = 0; virtual Future<Void> setAndPersistConnectionString(ClusterConnectionString const&) = 0;
// If this record is backed by persistent storage, get the connection string from that storage. Otherwise, return // If this record is backed by persistent storage, get the connection string from that storage. Otherwise, return
// the connection string stored in memory. // the connection string stored in memory.
@ -140,6 +141,9 @@ public:
bool hasUnresolvedHostnames() const; bool hasUnresolvedHostnames() const;
Future<Void> resolveHostnames(); Future<Void> resolveHostnames();
// This one should only be used when resolving asynchronously is impossible. For all other cases, resolveHostnames()
// should be preferred.
void resolveHostnamesBlocking();
virtual void addref() = 0; virtual void addref() = 0;
virtual void delref() = 0; virtual void delref() = 0;

View File

@ -54,14 +54,10 @@ FDB_DEFINE_BOOLEAN_PARAM(ConnectionStringNeedsPersisted);
// Returns the connection string currently held in this object. This may not match the stored record if it hasn't // Returns the connection string currently held in this object. This may not match the stored record if it hasn't
// been persisted or if the persistent storage for the record has been modified externally. // been persisted or if the persistent storage for the record has been modified externally.
ClusterConnectionString const& IClusterConnectionRecord::getConnectionString() const { ClusterConnectionString& IClusterConnectionRecord::getConnectionString() {
return cs; return cs;
} }
ClusterConnectionString* IClusterConnectionRecord::getMutableConnectionString() {
return &cs;
}
Future<bool> IClusterConnectionRecord::upToDate() { Future<bool> IClusterConnectionRecord::upToDate() {
ClusterConnectionString temp; ClusterConnectionString temp;
return upToDate(temp); return upToDate(temp);
@ -89,6 +85,10 @@ Future<Void> IClusterConnectionRecord::resolveHostnames() {
return cs.resolveHostnames(); return cs.resolveHostnames();
} }
void IClusterConnectionRecord::resolveHostnamesBlocking() {
cs.resolveHostnamesBlocking();
}
std::string ClusterConnectionString::getErrorString(std::string const& source, Error const& e) { std::string ClusterConnectionString::getErrorString(std::string const& source, Error const& e) {
if (e.code() == error_code_connection_string_invalid) { if (e.code() == error_code_connection_string_invalid) {
return format("Invalid connection string `%s: %d %s", source.c_str(), e.code(), e.what()); return format("Invalid connection string `%s: %d %s", source.c_str(), e.code(), e.what());
@ -129,6 +129,28 @@ Future<Void> ClusterConnectionString::resolveHostnames() {
} }
} }
void ClusterConnectionString::resolveHostnamesBlocking() {
if (hasUnresolvedHostnames) {
for (auto const& hostname : hostnames) {
std::vector<NetworkAddress> addresses =
INetworkConnections::net()->resolveTCPEndpointBlocking(hostname.host, hostname.service);
NetworkAddress address = addresses[deterministicRandom()->randomInt(0, addresses.size())];
address.flags = 0; // Reset the parsed address to public
address.fromHostname = NetworkAddressFromHostname::True;
if (hostname.isTLS) {
address.flags |= NetworkAddress::FLAG_TLS;
}
coords.push_back(address);
networkAddressToHostname.emplace(address, hostname);
}
std::sort(coords.begin(), coords.end());
if (std::unique(coords.begin(), coords.end()) != coords.end()) {
throw connection_string_invalid();
}
hasUnresolvedHostnames = false;
}
}
void ClusterConnectionString::resetToUnresolved() { void ClusterConnectionString::resetToUnresolved() {
if (hostnames.size() > 0) { if (hostnames.size() > 0) {
coords.clear(); coords.clear();
@ -623,7 +645,7 @@ ACTOR Future<MonitorLeaderInfo> monitorLeaderOneGeneration(Reference<IClusterCon
.detail("CurrentConnectionString", .detail("CurrentConnectionString",
info.intermediateConnRecord->getConnectionString().toString()); info.intermediateConnRecord->getConnectionString().toString());
} }
connRecord->setConnectionString(info.intermediateConnRecord->getConnectionString()); connRecord->setAndPersistConnectionString(info.intermediateConnRecord->getConnectionString());
info.intermediateConnRecord = connRecord; info.intermediateConnRecord = connRecord;
} }
@ -929,7 +951,7 @@ ACTOR Future<MonitorLeaderInfo> monitorProxiesOneGeneration(
.detail("CurrentConnectionString", .detail("CurrentConnectionString",
info.intermediateConnRecord->getConnectionString().toString()); info.intermediateConnRecord->getConnectionString().toString());
} }
connRecord->setConnectionString(info.intermediateConnRecord->getConnectionString()); connRecord->setAndPersistConnectionString(info.intermediateConnRecord->getConnectionString());
info.intermediateConnRecord = connRecord; info.intermediateConnRecord = connRecord;
} }

View File

@ -1791,7 +1791,7 @@ void DatabaseContext::expireThrottles() {
} }
} }
extern IPAddress determinePublicIPAutomatically(ClusterConnectionString const& ccs); extern IPAddress determinePublicIPAutomatically(ClusterConnectionString& ccs);
// Creates a database object that represents a connection to a cluster // Creates a database object that represents a connection to a cluster
// This constructor uses a preallocated DatabaseContext that may have been created // This constructor uses a preallocated DatabaseContext that may have been created

View File

@ -141,7 +141,7 @@ ACTOR Future<Void> tryBecomeLeaderInternal(ServerCoordinators coordinators,
.detail("StoredConnectionString", coordinators.ccr->getConnectionString().toString()) .detail("StoredConnectionString", coordinators.ccr->getConnectionString().toString())
.detail("CurrentConnectionString", leader.get().first.serializedInfo.toString()); .detail("CurrentConnectionString", leader.get().first.serializedInfo.toString());
} }
coordinators.ccr->setConnectionString( coordinators.ccr->setAndPersistConnectionString(
ClusterConnectionString(leader.get().first.serializedInfo.toString())); ClusterConnectionString(leader.get().first.serializedInfo.toString()));
TraceEvent("LeaderForwarding") TraceEvent("LeaderForwarding")
.detail("ConnStr", coordinators.ccr->getConnectionString().toString()) .detail("ConnStr", coordinators.ccr->getConnectionString().toString())

View File

@ -205,7 +205,7 @@ extern void copyTest();
extern void versionedMapTest(); extern void versionedMapTest();
extern void createTemplateDatabase(); extern void createTemplateDatabase();
// FIXME: this really belongs in a header somewhere since it is actually used. // FIXME: this really belongs in a header somewhere since it is actually used.
extern IPAddress determinePublicIPAutomatically(ClusterConnectionString const& ccs); extern IPAddress determinePublicIPAutomatically(ClusterConnectionString& ccs);
extern const char* getSourceVersion(); extern const char* getSourceVersion();
@ -815,7 +815,7 @@ Optional<bool> checkBuggifyOverride(const char* testFile) {
// Takes a vector of public and listen address strings given via command line, and returns vector of NetworkAddress // Takes a vector of public and listen address strings given via command line, and returns vector of NetworkAddress
// objects. // objects.
std::pair<NetworkAddressList, NetworkAddressList> buildNetworkAddresses( std::pair<NetworkAddressList, NetworkAddressList> buildNetworkAddresses(
const IClusterConnectionRecord& connectionRecord, IClusterConnectionRecord& connectionRecord,
const std::vector<std::string>& publicAddressStrs, const std::vector<std::string>& publicAddressStrs,
std::vector<std::string>& listenAddressStrs) { std::vector<std::string>& listenAddressStrs) {
if (listenAddressStrs.size() > 0 && publicAddressStrs.size() != listenAddressStrs.size()) { if (listenAddressStrs.size() > 0 && publicAddressStrs.size() != listenAddressStrs.size()) {

View File

@ -2476,7 +2476,7 @@ ACTOR Future<MonitorLeaderInfo> monitorLeaderWithDelayedCandidacyImplOneGenerati
.detail("CurrentConnectionString", .detail("CurrentConnectionString",
info.intermediateConnRecord->getConnectionString().toString()); info.intermediateConnRecord->getConnectionString().toString());
} }
connRecord->setConnectionString(info.intermediateConnRecord->getConnectionString()); connRecord->setAndPersistConnectionString(info.intermediateConnRecord->getConnectionString());
info.intermediateConnRecord = connRecord; info.intermediateConnRecord = connRecord;
} }