mirror of
https://github.com/apple/foundationdb.git
synced 2025-05-14 18:02:31 +08:00
Merge branch 'release-6.1'
# Conflicts: # documentation/sphinx/source/release-notes.rst # fdbclient/NativeAPI.actor.cpp # fdbserver/Coordination.actor.cpp # flow/Arena.h # versions.target
This commit is contained in:
commit
29b96414e2
@ -52,25 +52,6 @@ struct FDBLibTLSVerifyTest {
|
|||||||
std::map<int, Criteria> root_criteria;
|
std::map<int, Criteria> root_criteria;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::string printable( std::string const& val ) {
|
|
||||||
static char const digits[] = "0123456789ABCDEF";
|
|
||||||
std::string s;
|
|
||||||
|
|
||||||
for ( int i = 0; i < val.size(); i++ ) {
|
|
||||||
uint8_t b = val[i];
|
|
||||||
if (b >= 32 && b < 127 && b != '\\')
|
|
||||||
s += (char)b;
|
|
||||||
else if (b == '\\')
|
|
||||||
s += "\\\\";
|
|
||||||
else {
|
|
||||||
s += "\\x";
|
|
||||||
s += digits[(b >> 4) & 15];
|
|
||||||
s += digits[b & 15];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string criteriaToString(std::map<int, Criteria> const& criteria) {
|
static std::string criteriaToString(std::map<int, Criteria> const& criteria) {
|
||||||
std::string s;
|
std::string s;
|
||||||
for (auto &pair: criteria) {
|
for (auto &pair: criteria) {
|
||||||
|
@ -258,8 +258,6 @@ namespace FDB {
|
|||||||
|
|
||||||
typedef Standalone<KeyRangeRef> KeyRange;
|
typedef Standalone<KeyRangeRef> KeyRange;
|
||||||
|
|
||||||
std::string printable( const StringRef& val );
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
static std::string describe(T const& item) {
|
static std::string describe(T const& item) {
|
||||||
return item.toString();
|
return item.toString();
|
||||||
|
@ -426,16 +426,4 @@ namespace FDB {
|
|||||||
void TransactionImpl::reset() {
|
void TransactionImpl::reset() {
|
||||||
fdb_transaction_reset( tr );
|
fdb_transaction_reset( tr );
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string printable( const StringRef& val ) {
|
|
||||||
std::string s;
|
|
||||||
for(int i=0; i<val.size(); i++) {
|
|
||||||
uint8_t b = val[i];
|
|
||||||
if (b >= 32 && b < 127 && b != '\\') s += (char)b;
|
|
||||||
else if (b == '\\') s += "\\\\";
|
|
||||||
else s += format("\\x%02x", b);
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ struct DirectoryCreateSubspaceFunc : InstructionFunc {
|
|||||||
state Tuple path = wait(popTuple(data));
|
state Tuple path = wait(popTuple(data));
|
||||||
Tuple rawPrefix = wait(data->stack.waitAndPop());
|
Tuple rawPrefix = wait(data->stack.waitAndPop());
|
||||||
|
|
||||||
logOp(format("Created subspace at %s: %s", tupleToString(path).c_str(), printable(rawPrefix.getString(0)).c_str()));
|
logOp(format("Created subspace at %s: %s", tupleToString(path).c_str(), rawPrefix.getString(0).printable().c_str()));
|
||||||
data->directoryData.push(new Subspace(path, rawPrefix.getString(0)));
|
data->directoryData.push(new Subspace(path, rawPrefix.getString(0)));
|
||||||
return Void();
|
return Void();
|
||||||
}
|
}
|
||||||
@ -133,7 +133,7 @@ struct DirectoryCreateLayerFunc : InstructionFunc {
|
|||||||
else {
|
else {
|
||||||
Subspace* nodeSubspace = data->directoryData.directoryList[index1].subspace.get();
|
Subspace* nodeSubspace = data->directoryData.directoryList[index1].subspace.get();
|
||||||
Subspace* contentSubspace = data->directoryData.directoryList[index2].subspace.get();
|
Subspace* contentSubspace = data->directoryData.directoryList[index2].subspace.get();
|
||||||
logOp(format("Create directory layer: node_subspace (%d) = %s, content_subspace (%d) = %s, allow_manual_prefixes = %d", index1, printable(nodeSubspace->key()).c_str(), index2, printable(nodeSubspace->key()).c_str(), allowManualPrefixes));
|
logOp(format("Create directory layer: node_subspace (%d) = %s, content_subspace (%d) = %s, allow_manual_prefixes = %d", index1, nodeSubspace->key().printable().c_str(), index2, nodeSubspace->key().printable().c_str(), allowManualPrefixes));
|
||||||
data->directoryData.push(Reference<IDirectory>(new DirectoryLayer(*nodeSubspace, *contentSubspace, allowManualPrefixes)));
|
data->directoryData.push(Reference<IDirectory>(new DirectoryLayer(*nodeSubspace, *contentSubspace, allowManualPrefixes)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,7 +158,7 @@ struct DirectoryChangeFunc : InstructionFunc {
|
|||||||
|
|
||||||
if(LOG_DIRS) {
|
if(LOG_DIRS) {
|
||||||
DirectoryOrSubspace d = data->directoryData.directoryList[data->directoryData.directoryListIndex];
|
DirectoryOrSubspace d = data->directoryData.directoryList[data->directoryData.directoryListIndex];
|
||||||
printf("Changed directory to %d (%s @\'%s\')\n", data->directoryData.directoryListIndex, d.typeString().c_str(), d.directory.present() ? pathToString(d.directory.get()->getPath()).c_str() : printable(d.subspace.get()->key()).c_str());
|
printf("Changed directory to %d (%s @\'%s\')\n", data->directoryData.directoryListIndex, d.typeString().c_str(), d.directory.present() ? pathToString(d.directory.get()->getPath()).c_str() : d.subspace.get()->key().printable().c_str());
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +192,7 @@ struct DirectoryCreateOrOpenFunc : InstructionFunc {
|
|||||||
Standalone<StringRef> layer = layerTuple.getType(0) == Tuple::NULL_TYPE ? StringRef() : layerTuple.getString(0);
|
Standalone<StringRef> layer = layerTuple.getType(0) == Tuple::NULL_TYPE ? StringRef() : layerTuple.getString(0);
|
||||||
|
|
||||||
Reference<IDirectory> directory = data->directoryData.directory();
|
Reference<IDirectory> directory = data->directoryData.directory();
|
||||||
logOp(format("create_or_open %s: layer=%s", pathToString(combinePaths(directory->getPath(), path)).c_str(), printable(layer).c_str()));
|
logOp(format("create_or_open %s: layer=%s", pathToString(combinePaths(directory->getPath(), path)).c_str(), layer.printable().c_str()));
|
||||||
|
|
||||||
Reference<DirectorySubspace> dirSubspace = wait(executeMutation(instruction, [this, directory, layer] () {
|
Reference<DirectorySubspace> dirSubspace = wait(executeMutation(instruction, [this, directory, layer] () {
|
||||||
return directory->createOrOpen(instruction->tr, path, layer);
|
return directory->createOrOpen(instruction->tr, path, layer);
|
||||||
@ -217,7 +217,7 @@ struct DirectoryCreateFunc : InstructionFunc {
|
|||||||
Optional<Standalone<StringRef>> prefix = args[1].getType(0) == Tuple::NULL_TYPE ? Optional<Standalone<StringRef>>() : args[1].getString(0);
|
Optional<Standalone<StringRef>> prefix = args[1].getType(0) == Tuple::NULL_TYPE ? Optional<Standalone<StringRef>>() : args[1].getString(0);
|
||||||
|
|
||||||
Reference<IDirectory> directory = data->directoryData.directory();
|
Reference<IDirectory> directory = data->directoryData.directory();
|
||||||
logOp(format("create %s: layer=%s, prefix=%s", pathToString(combinePaths(directory->getPath(), path)).c_str(), printable(layer).c_str(), prefix.present() ? printable(prefix.get()).c_str() : "<not present>"));
|
logOp(format("create %s: layer=%s, prefix=%s", pathToString(combinePaths(directory->getPath(), path)).c_str(), layer.printable().c_str(), prefix.present() ? prefix.get().printable().c_str() : "<not present>"));
|
||||||
|
|
||||||
Reference<DirectorySubspace> dirSubspace = wait(executeMutation(instruction, [this, directory, layer, prefix] () {
|
Reference<DirectorySubspace> dirSubspace = wait(executeMutation(instruction, [this, directory, layer, prefix] () {
|
||||||
return directory->create(instruction->tr, path, layer, prefix);
|
return directory->create(instruction->tr, path, layer, prefix);
|
||||||
@ -241,7 +241,7 @@ struct DirectoryOpenFunc : InstructionFunc {
|
|||||||
Standalone<StringRef> layer = layerTuple.getType(0) == Tuple::NULL_TYPE ? StringRef() : layerTuple.getString(0);
|
Standalone<StringRef> layer = layerTuple.getType(0) == Tuple::NULL_TYPE ? StringRef() : layerTuple.getString(0);
|
||||||
|
|
||||||
Reference<IDirectory> directory = data->directoryData.directory();
|
Reference<IDirectory> directory = data->directoryData.directory();
|
||||||
logOp(format("open %s: layer=%s", pathToString(combinePaths(directory->getPath(), path)).c_str(), printable(layer).c_str()));
|
logOp(format("open %s: layer=%s", pathToString(combinePaths(directory->getPath(), path)).c_str(), layer.printable().c_str()));
|
||||||
Reference<DirectorySubspace> dirSubspace = wait(directory->open(instruction->tr, path, layer));
|
Reference<DirectorySubspace> dirSubspace = wait(directory->open(instruction->tr, path, layer));
|
||||||
data->directoryData.push(dirSubspace);
|
data->directoryData.push(dirSubspace);
|
||||||
|
|
||||||
@ -433,7 +433,7 @@ struct DirectoryUnpackKeyFunc : InstructionFunc {
|
|||||||
ACTOR static Future<Void> call(Reference<FlowTesterData> data, Reference<InstructionData> instruction) {
|
ACTOR static Future<Void> call(Reference<FlowTesterData> data, Reference<InstructionData> instruction) {
|
||||||
Tuple key = wait(data->stack.waitAndPop());
|
Tuple key = wait(data->stack.waitAndPop());
|
||||||
Subspace *subspace = data->directoryData.subspace();
|
Subspace *subspace = data->directoryData.subspace();
|
||||||
logOp(format("Unpack %s in subspace with prefix %s", printable(key.getString(0)).c_str(), printable(subspace->key()).c_str()));
|
logOp(format("Unpack %s in subspace with prefix %s", key.getString(0).printable().c_str(), subspace->key().printable().c_str()));
|
||||||
Tuple tuple = subspace->unpack(key.getString(0));
|
Tuple tuple = subspace->unpack(key.getString(0));
|
||||||
for(int i = 0; i < tuple.size(); ++i) {
|
for(int i = 0; i < tuple.size(); ++i) {
|
||||||
data->stack.push(tuple.subTuple(i, i+1).pack());
|
data->stack.push(tuple.subTuple(i, i+1).pack());
|
||||||
@ -483,7 +483,7 @@ struct DirectoryOpenSubspaceFunc : InstructionFunc {
|
|||||||
ACTOR static Future<Void> call(Reference<FlowTesterData> data, Reference<InstructionData> instruction) {
|
ACTOR static Future<Void> call(Reference<FlowTesterData> data, Reference<InstructionData> instruction) {
|
||||||
Tuple tuple = wait(popTuple(data));
|
Tuple tuple = wait(popTuple(data));
|
||||||
Subspace *subspace = data->directoryData.subspace();
|
Subspace *subspace = data->directoryData.subspace();
|
||||||
logOp(format("open_subspace %s (at %s)", tupleToString(tuple).c_str(), printable(subspace->key()).c_str()));
|
logOp(format("open_subspace %s (at %s)", tupleToString(tuple).c_str(), subspace->key().printable().c_str()));
|
||||||
Subspace *child = new Subspace(subspace->subspace(tuple));
|
Subspace *child = new Subspace(subspace->subspace(tuple));
|
||||||
data->directoryData.push(child);
|
data->directoryData.push(child);
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ std::string tupleToString(Tuple const& tuple) {
|
|||||||
if(type == Tuple::UTF8) {
|
if(type == Tuple::UTF8) {
|
||||||
str += "u";
|
str += "u";
|
||||||
}
|
}
|
||||||
str += "\'" + printable(tuple.getString(i)) + "\'";
|
str += "\'" + tuple.getString(i).printable() + "\'";
|
||||||
}
|
}
|
||||||
else if(type == Tuple::INT) {
|
else if(type == Tuple::INT) {
|
||||||
str += format("%ld", tuple.getInt(i));
|
str += format("%ld", tuple.getInt(i));
|
||||||
@ -1791,7 +1791,7 @@ ACTOR void _test_versionstamp() {
|
|||||||
|
|
||||||
ASSERT(trVersion.compare(dbVersion) == 0);
|
ASSERT(trVersion.compare(dbVersion) == 0);
|
||||||
|
|
||||||
fprintf(stderr, "%s\n", printable(trVersion).c_str());
|
fprintf(stderr, "%s\n", trVersion.printable().c_str());
|
||||||
|
|
||||||
g_network->stop();
|
g_network->stop();
|
||||||
}
|
}
|
||||||
|
@ -10,38 +10,38 @@ macOS
|
|||||||
|
|
||||||
The macOS installation package is supported on macOS 10.7+. It includes the client and (optionally) the server.
|
The macOS installation package is supported on macOS 10.7+. It includes the client and (optionally) the server.
|
||||||
|
|
||||||
* `FoundationDB-6.1.8.pkg <https://www.foundationdb.org/downloads/6.1.8/macOS/installers/FoundationDB-6.1.8.pkg>`_
|
* `FoundationDB-6.1.9.pkg <https://www.foundationdb.org/downloads/6.1.9/macOS/installers/FoundationDB-6.1.9.pkg>`_
|
||||||
|
|
||||||
Ubuntu
|
Ubuntu
|
||||||
------
|
------
|
||||||
|
|
||||||
The Ubuntu packages are supported on 64-bit Ubuntu 12.04+, but beware of the Linux kernel bug in Ubuntu 12.x.
|
The Ubuntu packages are supported on 64-bit Ubuntu 12.04+, but beware of the Linux kernel bug in Ubuntu 12.x.
|
||||||
|
|
||||||
* `foundationdb-clients-6.1.8-1_amd64.deb <https://www.foundationdb.org/downloads/6.1.8/ubuntu/installers/foundationdb-clients_6.1.7-1_amd64.deb>`_
|
* `foundationdb-clients-6.1.9-1_amd64.deb <https://www.foundationdb.org/downloads/6.1.9/ubuntu/installers/foundationdb-clients_6.1.9-1_amd64.deb>`_
|
||||||
* `foundationdb-server-6.1.8-1_amd64.deb <https://www.foundationdb.org/downloads/6.1.8/ubuntu/installers/foundationdb-server_6.1.7-1_amd64.deb>`_ (depends on the clients package)
|
* `foundationdb-server-6.1.9-1_amd64.deb <https://www.foundationdb.org/downloads/6.1.9/ubuntu/installers/foundationdb-server_6.1.9-1_amd64.deb>`_ (depends on the clients package)
|
||||||
|
|
||||||
RHEL/CentOS EL6
|
RHEL/CentOS EL6
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
The RHEL/CentOS EL6 packages are supported on 64-bit RHEL/CentOS 6.x.
|
The RHEL/CentOS EL6 packages are supported on 64-bit RHEL/CentOS 6.x.
|
||||||
|
|
||||||
* `foundationdb-clients-6.1.8-1.el6.x86_64.rpm <https://www.foundationdb.org/downloads/6.1.8/rhel6/installers/foundationdb-clients-6.1.8-1.el6.x86_64.rpm>`_
|
* `foundationdb-clients-6.1.9-1.el6.x86_64.rpm <https://www.foundationdb.org/downloads/6.1.9/rhel6/installers/foundationdb-clients-6.1.9-1.el6.x86_64.rpm>`_
|
||||||
* `foundationdb-server-6.1.8-1.el6.x86_64.rpm <https://www.foundationdb.org/downloads/6.1.8/rhel6/installers/foundationdb-server-6.1.8-1.el6.x86_64.rpm>`_ (depends on the clients package)
|
* `foundationdb-server-6.1.9-1.el6.x86_64.rpm <https://www.foundationdb.org/downloads/6.1.9/rhel6/installers/foundationdb-server-6.1.9-1.el6.x86_64.rpm>`_ (depends on the clients package)
|
||||||
|
|
||||||
RHEL/CentOS EL7
|
RHEL/CentOS EL7
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
The RHEL/CentOS EL7 packages are supported on 64-bit RHEL/CentOS 7.x.
|
The RHEL/CentOS EL7 packages are supported on 64-bit RHEL/CentOS 7.x.
|
||||||
|
|
||||||
* `foundationdb-clients-6.1.8-1.el7.x86_64.rpm <https://www.foundationdb.org/downloads/6.1.8/rhel7/installers/foundationdb-clients-6.1.8-1.el7.x86_64.rpm>`_
|
* `foundationdb-clients-6.1.9-1.el7.x86_64.rpm <https://www.foundationdb.org/downloads/6.1.9/rhel7/installers/foundationdb-clients-6.1.9-1.el7.x86_64.rpm>`_
|
||||||
* `foundationdb-server-6.1.8-1.el7.x86_64.rpm <https://www.foundationdb.org/downloads/6.1.8/rhel7/installers/foundationdb-server-6.1.8-1.el7.x86_64.rpm>`_ (depends on the clients package)
|
* `foundationdb-server-6.1.9-1.el7.x86_64.rpm <https://www.foundationdb.org/downloads/6.1.9/rhel7/installers/foundationdb-server-6.1.9-1.el7.x86_64.rpm>`_ (depends on the clients package)
|
||||||
|
|
||||||
Windows
|
Windows
|
||||||
-------
|
-------
|
||||||
|
|
||||||
The Windows installer is supported on 64-bit Windows XP and later. It includes the client and (optionally) the server.
|
The Windows installer is supported on 64-bit Windows XP and later. It includes the client and (optionally) the server.
|
||||||
|
|
||||||
* `foundationdb-6.1.8-x64.msi <https://www.foundationdb.org/downloads/6.1.8/windows/installers/foundationdb-6.1.8-x64.msi>`_
|
* `foundationdb-6.1.9-x64.msi <https://www.foundationdb.org/downloads/6.1.9/windows/installers/foundationdb-6.1.9-x64.msi>`_
|
||||||
|
|
||||||
API Language Bindings
|
API Language Bindings
|
||||||
=====================
|
=====================
|
||||||
@ -58,18 +58,18 @@ On macOS and Windows, the FoundationDB Python API bindings are installed as part
|
|||||||
|
|
||||||
If you need to use the FoundationDB Python API from other Python installations or paths, download the Python package:
|
If you need to use the FoundationDB Python API from other Python installations or paths, download the Python package:
|
||||||
|
|
||||||
* `foundationdb-6.1.8.tar.gz <https://www.foundationdb.org/downloads/6.1.8/bindings/python/foundationdb-6.1.8.tar.gz>`_
|
* `foundationdb-6.1.9.tar.gz <https://www.foundationdb.org/downloads/6.1.9/bindings/python/foundationdb-6.1.9.tar.gz>`_
|
||||||
|
|
||||||
Ruby 1.9.3/2.0.0+
|
Ruby 1.9.3/2.0.0+
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
* `fdb-6.1.8.gem <https://www.foundationdb.org/downloads/6.1.8/bindings/ruby/fdb-6.1.8.gem>`_
|
* `fdb-6.1.9.gem <https://www.foundationdb.org/downloads/6.1.9/bindings/ruby/fdb-6.1.9.gem>`_
|
||||||
|
|
||||||
Java 8+
|
Java 8+
|
||||||
-------
|
-------
|
||||||
|
|
||||||
* `fdb-java-6.1.8.jar <https://www.foundationdb.org/downloads/6.1.8/bindings/java/fdb-java-6.1.8.jar>`_
|
* `fdb-java-6.1.9.jar <https://www.foundationdb.org/downloads/6.1.9/bindings/java/fdb-java-6.1.9.jar>`_
|
||||||
* `fdb-java-6.1.8-javadoc.jar <https://www.foundationdb.org/downloads/6.1.8/bindings/java/fdb-java-6.1.8-javadoc.jar>`_
|
* `fdb-java-6.1.9-javadoc.jar <https://www.foundationdb.org/downloads/6.1.9/bindings/java/fdb-java-6.1.9-javadoc.jar>`_
|
||||||
|
|
||||||
Go 1.11+
|
Go 1.11+
|
||||||
--------
|
--------
|
||||||
|
@ -42,6 +42,15 @@ struct ClusterInterface {
|
|||||||
UID id() const { return openDatabase.getEndpoint().token; }
|
UID id() const { return openDatabase.getEndpoint().token; }
|
||||||
NetworkAddress address() const { return openDatabase.getEndpoint().getPrimaryAddress(); }
|
NetworkAddress address() const { return openDatabase.getEndpoint().getPrimaryAddress(); }
|
||||||
|
|
||||||
|
bool hasMessage() {
|
||||||
|
return openDatabase.getFuture().isReady() ||
|
||||||
|
failureMonitoring.getFuture().isReady() ||
|
||||||
|
databaseStatus.getFuture().isReady() ||
|
||||||
|
ping.getFuture().isReady() ||
|
||||||
|
getClientWorkers.getFuture().isReady() ||
|
||||||
|
forceRecovery.getFuture().isReady();
|
||||||
|
}
|
||||||
|
|
||||||
void initEndpoints() {
|
void initEndpoints() {
|
||||||
openDatabase.getEndpoint( TaskClusterController );
|
openDatabase.getEndpoint( TaskClusterController );
|
||||||
failureMonitoring.getEndpoint( TaskFailureMonitor );
|
failureMonitoring.getEndpoint( TaskFailureMonitor );
|
||||||
|
@ -392,17 +392,17 @@ namespace HTTP {
|
|||||||
responseID = iid->second;
|
responseID = iid->second;
|
||||||
}
|
}
|
||||||
event.detail("RequestIDReceived", responseID);
|
event.detail("RequestIDReceived", responseID);
|
||||||
if(requestID != responseID) {
|
|
||||||
|
// If the response code is 5xx (server error) then a response ID is not expected
|
||||||
|
// so a missing id will be ignored but a mismatching id will still be an error.
|
||||||
|
bool serverError = r->code >= 500 && r->code < 600;
|
||||||
|
|
||||||
|
// If request/response IDs do not match and either this is not a server error
|
||||||
|
// or it is but the response ID is not empty then log an error.
|
||||||
|
if(requestID != responseID && (!serverError || !responseID.empty()) ) {
|
||||||
err = http_bad_request_id();
|
err = http_bad_request_id();
|
||||||
|
|
||||||
// Log a non-debug a error
|
TraceEvent(SevError, "HTTPRequestFailedIDMismatch")
|
||||||
Severity sev = SevError;
|
|
||||||
// If the response code is 5xx (server error) and the responseID is empty then just warn
|
|
||||||
if(responseID.empty() && r->code >= 500 && r->code < 600) {
|
|
||||||
sev = SevWarnAlways;
|
|
||||||
}
|
|
||||||
|
|
||||||
TraceEvent(sev, "HTTPRequestFailedIDMismatch")
|
|
||||||
.detail("DebugID", conn->getDebugID())
|
.detail("DebugID", conn->getDebugID())
|
||||||
.detail("RemoteAddress", conn->getPeerAddress())
|
.detail("RemoteAddress", conn->getPeerAddress())
|
||||||
.detail("Verb", verb)
|
.detail("Verb", verb)
|
||||||
@ -433,6 +433,7 @@ namespace HTTP {
|
|||||||
return r;
|
return r;
|
||||||
} catch(Error &e) {
|
} catch(Error &e) {
|
||||||
double elapsed = timer() - send_start;
|
double elapsed = timer() - send_start;
|
||||||
|
// A bad_request_id error would have already been logged in verbose mode before err is thrown above.
|
||||||
if(CLIENT_KNOBS->HTTP_VERBOSE_LEVEL > 0 && e.code() != error_code_http_bad_request_id) {
|
if(CLIENT_KNOBS->HTTP_VERBOSE_LEVEL > 0 && e.code() != error_code_http_bad_request_id) {
|
||||||
printf("[%s] HTTP *ERROR*=%s early=%d, time=%fs %s %s contentLen=%d [%d out]\n",
|
printf("[%s] HTTP *ERROR*=%s early=%d, time=%fs %s %s contentLen=%d [%d out]\n",
|
||||||
conn->getDebugID().toString().c_str(), e.name(), earlyResponse, elapsed, verb.c_str(), resource.c_str(), contentLen, total_sent);
|
conn->getDebugID().toString().c_str(), e.name(), earlyResponse, elapsed, verb.c_str(), resource.c_str(), contentLen, total_sent);
|
||||||
|
@ -2747,7 +2747,8 @@ Future<Void> Transaction::commitMutations() {
|
|||||||
.detail("Size", transactionSize)
|
.detail("Size", transactionSize)
|
||||||
.detail("NumMutations", tr.transaction.mutations.size())
|
.detail("NumMutations", tr.transaction.mutations.size())
|
||||||
.detail("ReadConflictSize", tr.transaction.read_conflict_ranges.expectedSize())
|
.detail("ReadConflictSize", tr.transaction.read_conflict_ranges.expectedSize())
|
||||||
.detail("WriteConflictSize", tr.transaction.write_conflict_ranges.expectedSize());
|
.detail("WriteConflictSize", tr.transaction.write_conflict_ranges.expectedSize())
|
||||||
|
.detail("DebugIdentifier", trLogInfo ? trLogInfo->identifier : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!apiVersionAtLeast(300)) {
|
if(!apiVersionAtLeast(300)) {
|
||||||
@ -2900,15 +2901,15 @@ void Transaction::setOption( FDBTransactionOptions::Option option, Optional<Stri
|
|||||||
|
|
||||||
if (trLogInfo) {
|
if (trLogInfo) {
|
||||||
if (trLogInfo->identifier.empty()) {
|
if (trLogInfo->identifier.empty()) {
|
||||||
trLogInfo->identifier = printable(value.get());
|
trLogInfo->identifier = value.get().printable();
|
||||||
}
|
}
|
||||||
else if (trLogInfo->identifier != printable(value.get())) {
|
else if (trLogInfo->identifier != value.get().printable()) {
|
||||||
TraceEvent(SevWarn, "CannotChangeDebugTransactionIdentifier").detail("PreviousIdentifier", trLogInfo->identifier).detail("NewIdentifier", value.get());
|
TraceEvent(SevWarn, "CannotChangeDebugTransactionIdentifier").detail("PreviousIdentifier", trLogInfo->identifier).detail("NewIdentifier", value.get());
|
||||||
throw client_invalid_operation();
|
throw client_invalid_operation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
trLogInfo = Reference<TransactionLogInfo>(new TransactionLogInfo(printable(value.get()), TransactionLogInfo::DONT_LOG));
|
trLogInfo = Reference<TransactionLogInfo>(new TransactionLogInfo(value.get().printable(), TransactionLogInfo::DONT_LOG));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -404,6 +404,7 @@ struct Peer : NonCopyable {
|
|||||||
state ReplyPromise<Void> reply;
|
state ReplyPromise<Void> reply;
|
||||||
FlowTransport::transport().sendUnreliable( SerializeSource<ReplyPromise<Void>>(reply), remotePing.getEndpoint() );
|
FlowTransport::transport().sendUnreliable( SerializeSource<ReplyPromise<Void>>(reply), remotePing.getEndpoint() );
|
||||||
state int64_t startingBytes = peer->bytesReceived;
|
state int64_t startingBytes = peer->bytesReceived;
|
||||||
|
state int timeouts = 0;
|
||||||
loop {
|
loop {
|
||||||
choose {
|
choose {
|
||||||
when (wait( delay( FLOW_KNOBS->CONNECTION_MONITOR_TIMEOUT ) )) {
|
when (wait( delay( FLOW_KNOBS->CONNECTION_MONITOR_TIMEOUT ) )) {
|
||||||
@ -411,7 +412,11 @@ struct Peer : NonCopyable {
|
|||||||
TraceEvent("ConnectionTimeout").suppressFor(1.0).detail("WithAddr", peer->destination);
|
TraceEvent("ConnectionTimeout").suppressFor(1.0).detail("WithAddr", peer->destination);
|
||||||
throw connection_failed();
|
throw connection_failed();
|
||||||
}
|
}
|
||||||
|
if(timeouts > 1) {
|
||||||
|
TraceEvent(SevWarnAlways, "ConnectionSlowPing").suppressFor(1.0).detail("WithAddr", peer->destination).detail("Timeouts", timeouts);
|
||||||
|
}
|
||||||
startingBytes = peer->bytesReceived;
|
startingBytes = peer->bytesReceived;
|
||||||
|
timeouts++;
|
||||||
}
|
}
|
||||||
when (wait( reply.getFuture() )) {
|
when (wait( reply.getFuture() )) {
|
||||||
break;
|
break;
|
||||||
|
@ -2705,6 +2705,16 @@ ACTOR Future<Void> clusterControllerCore( ClusterControllerFullInterface interf,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ACTOR Future<Void> replaceInterface( ClusterControllerFullInterface interf ) {
|
||||||
|
loop {
|
||||||
|
if( interf.hasMessage() ) {
|
||||||
|
wait(delay(SERVER_KNOBS->REPLACE_INTERFACE_DELAY));
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
wait(delay(SERVER_KNOBS->REPLACE_INTERFACE_CHECK_DELAY));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ACTOR Future<Void> clusterController( ServerCoordinators coordinators, Reference<AsyncVar<Optional<ClusterControllerFullInterface>>> currentCC, bool hasConnected, Reference<AsyncVar<ClusterControllerPriorityInfo>> asyncPriorityInfo, LocalityData locality ) {
|
ACTOR Future<Void> clusterController( ServerCoordinators coordinators, Reference<AsyncVar<Optional<ClusterControllerFullInterface>>> currentCC, bool hasConnected, Reference<AsyncVar<ClusterControllerPriorityInfo>> asyncPriorityInfo, LocalityData locality ) {
|
||||||
loop {
|
loop {
|
||||||
state ClusterControllerFullInterface cci;
|
state ClusterControllerFullInterface cci;
|
||||||
@ -2713,19 +2723,23 @@ ACTOR Future<Void> clusterController( ServerCoordinators coordinators, Reference
|
|||||||
try {
|
try {
|
||||||
//Register as a possible leader; wait to be elected
|
//Register as a possible leader; wait to be elected
|
||||||
state Future<Void> leaderFail = tryBecomeLeader( coordinators, cci, currentCC, hasConnected, asyncPriorityInfo );
|
state Future<Void> leaderFail = tryBecomeLeader( coordinators, cci, currentCC, hasConnected, asyncPriorityInfo );
|
||||||
|
state Future<Void> shouldReplace = replaceInterface( cci );
|
||||||
|
|
||||||
while (!currentCC->get().present() || currentCC->get().get() != cci) {
|
while (!currentCC->get().present() || currentCC->get().get() != cci) {
|
||||||
choose {
|
choose {
|
||||||
when( wait(currentCC->onChange()) ) {}
|
when( wait(currentCC->onChange()) ) {}
|
||||||
when( wait(leaderFail) ) { ASSERT(false); throw internal_error(); }
|
when( wait(leaderFail) ) { ASSERT(false); throw internal_error(); }
|
||||||
|
when( wait(shouldReplace) ) { break; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(!shouldReplace.isReady()) {
|
||||||
|
shouldReplace = Future<Void>();
|
||||||
|
hasConnected = true;
|
||||||
|
startRole(Role::CLUSTER_CONTROLLER, cci.id(), UID());
|
||||||
|
inRole = true;
|
||||||
|
|
||||||
hasConnected = true;
|
wait( clusterControllerCore( cci, leaderFail, coordinators, locality ) );
|
||||||
startRole(Role::CLUSTER_CONTROLLER, cci.id(), UID());
|
}
|
||||||
inRole = true;
|
|
||||||
|
|
||||||
wait( clusterControllerCore( cci, leaderFail, coordinators, locality ) );
|
|
||||||
} catch(Error& e) {
|
} catch(Error& e) {
|
||||||
if (inRole)
|
if (inRole)
|
||||||
endRole(Role::CLUSTER_CONTROLLER, cci.id(), "Error", e.code() == error_code_actor_cancelled || e.code() == error_code_coordinators_changed, e);
|
endRole(Role::CLUSTER_CONTROLLER, cci.id(), "Error", e.code() == error_code_actor_cancelled || e.code() == error_code_coordinators_changed, e);
|
||||||
|
@ -50,6 +50,17 @@ struct ClusterControllerFullInterface {
|
|||||||
bool operator == (ClusterControllerFullInterface const& r) const { return id() == r.id(); }
|
bool operator == (ClusterControllerFullInterface const& r) const { return id() == r.id(); }
|
||||||
bool operator != (ClusterControllerFullInterface const& r) const { return id() != r.id(); }
|
bool operator != (ClusterControllerFullInterface const& r) const { return id() != r.id(); }
|
||||||
|
|
||||||
|
bool hasMessage() {
|
||||||
|
return clientInterface.hasMessage() ||
|
||||||
|
recruitFromConfiguration.getFuture().isReady() ||
|
||||||
|
recruitRemoteFromConfiguration.getFuture().isReady() ||
|
||||||
|
recruitStorage.getFuture().isReady() ||
|
||||||
|
registerWorker.getFuture().isReady() ||
|
||||||
|
getWorkers.getFuture().isReady() ||
|
||||||
|
registerMaster.getFuture().isReady() ||
|
||||||
|
getServerDBInfo.getFuture().isReady();
|
||||||
|
}
|
||||||
|
|
||||||
void initEndpoints() {
|
void initEndpoints() {
|
||||||
clientInterface.initEndpoints();
|
clientInterface.initEndpoints();
|
||||||
recruitFromConfiguration.getEndpoint( TaskClusterController );
|
recruitFromConfiguration.getEndpoint( TaskClusterController );
|
||||||
|
@ -355,17 +355,6 @@ struct CompactPreOrderTree {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string printable(const StringRef& val) {
|
|
||||||
std::string s;
|
|
||||||
for (int i = 0; i<val.size(); i++) {
|
|
||||||
uint8_t b = val[i];
|
|
||||||
if (b >= 32 && b < 127 && b != '\\') s += (char)b;
|
|
||||||
else if (b == '\\') s += "\\\\";
|
|
||||||
else s += format("\\x%02x", b);
|
|
||||||
}
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
void compactMapTests(std::vector<std::string> testData, std::vector<std::string> sampleQueries, std::string prefixTreeDOTFile = "") {
|
void compactMapTests(std::vector<std::string> testData, std::vector<std::string> sampleQueries, std::string prefixTreeDOTFile = "") {
|
||||||
double t1, t2;
|
double t1, t2;
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
@ -271,38 +271,22 @@ ACTOR Future<Void> leaderRegister(LeaderElectionRegInterface interf, Key key) {
|
|||||||
return Void();
|
return Void();
|
||||||
} else {
|
} else {
|
||||||
Optional<LeaderInfo> nextNominee;
|
Optional<LeaderInfo> nextNominee;
|
||||||
if (availableLeaders.size() && availableCandidates.size()) {
|
if( availableCandidates.size() && (!availableLeaders.size() || availableLeaders.begin()->leaderChangeRequired(*availableCandidates.begin())) ) {
|
||||||
nextNominee = ( *availableLeaders.begin() < *availableCandidates.begin() ) ? *availableLeaders.begin() : *availableCandidates.begin();
|
|
||||||
} else if (availableLeaders.size()) {
|
|
||||||
nextNominee = *availableLeaders.begin();
|
|
||||||
} else if (availableCandidates.size()) {
|
|
||||||
nextNominee = *availableCandidates.begin();
|
nextNominee = *availableCandidates.begin();
|
||||||
} else {
|
} else if( availableLeaders.size() ) {
|
||||||
nextNominee = Optional<LeaderInfo>();
|
nextNominee = *availableLeaders.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool foundCurrentNominee = false;
|
if( !currentNominee.present() || !nextNominee.present() || !currentNominee.get().equalInternalId(nextNominee.get()) || nextNominee.get() > currentNominee.get() ) {
|
||||||
if(currentNominee.present()) {
|
TraceEvent("NominatingLeader").detail("NextNominee", nextNominee.present() ? nextNominee.get().changeID : UID())
|
||||||
for(auto& it : availableLeaders) {
|
.detail("CurrentNominee", currentNominee.present() ? currentNominee.get().changeID : UID()).detail("Key", printable(key));
|
||||||
if(currentNominee.get().equalInternalId(it)) {
|
|
||||||
foundCurrentNominee = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !nextNominee.present() || !foundCurrentNominee || currentNominee.get().leaderChangeRequired(nextNominee.get()) ) {
|
|
||||||
TraceEvent("NominatingLeader").detail("Nominee", nextNominee.present() ? nextNominee.get().changeID : UID())
|
|
||||||
.detail("Changed", nextNominee != currentNominee).detail("Key", key);
|
|
||||||
for(unsigned int i=0; i<notify.size(); i++)
|
for(unsigned int i=0; i<notify.size(); i++)
|
||||||
notify[i].send( nextNominee );
|
notify[i].send( nextNominee );
|
||||||
notify.clear();
|
notify.clear();
|
||||||
currentNominee = nextNominee;
|
|
||||||
} else if (currentNominee.get().equalInternalId(nextNominee.get())) {
|
|
||||||
// leader becomes better
|
|
||||||
currentNominee = nextNominee;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currentNominee = nextNominee;
|
||||||
|
|
||||||
if( availableLeaders.size() ) {
|
if( availableLeaders.size() ) {
|
||||||
nextInterval = delay( SERVER_KNOBS->POLLING_FREQUENCY );
|
nextInterval = delay( SERVER_KNOBS->POLLING_FREQUENCY );
|
||||||
if(leaderIntervalCount++ > 5) {
|
if(leaderIntervalCount++ > 5) {
|
||||||
|
@ -327,6 +327,8 @@ ServerKnobs::ServerKnobs(bool randomize, ClientKnobs* clientKnobs) {
|
|||||||
init( MAX_VERSION_DIFFERENCE, 20 * VERSIONS_PER_SECOND );
|
init( MAX_VERSION_DIFFERENCE, 20 * VERSIONS_PER_SECOND );
|
||||||
init( FORCE_RECOVERY_CHECK_DELAY, 5.0 );
|
init( FORCE_RECOVERY_CHECK_DELAY, 5.0 );
|
||||||
init( RATEKEEPER_FAILURE_TIME, 1.0 );
|
init( RATEKEEPER_FAILURE_TIME, 1.0 );
|
||||||
|
init( REPLACE_INTERFACE_DELAY, 60.0 );
|
||||||
|
init( REPLACE_INTERFACE_CHECK_DELAY, 5.0 );
|
||||||
|
|
||||||
init( INCOMPATIBLE_PEERS_LOGGING_INTERVAL, 600 ); if( randomize && BUGGIFY ) INCOMPATIBLE_PEERS_LOGGING_INTERVAL = 60.0;
|
init( INCOMPATIBLE_PEERS_LOGGING_INTERVAL, 600 ); if( randomize && BUGGIFY ) INCOMPATIBLE_PEERS_LOGGING_INTERVAL = 60.0;
|
||||||
init( EXPECTED_MASTER_FITNESS, ProcessClass::UnsetFit );
|
init( EXPECTED_MASTER_FITNESS, ProcessClass::UnsetFit );
|
||||||
|
@ -269,6 +269,8 @@ public:
|
|||||||
int64_t MAX_VERSION_DIFFERENCE;
|
int64_t MAX_VERSION_DIFFERENCE;
|
||||||
double FORCE_RECOVERY_CHECK_DELAY;
|
double FORCE_RECOVERY_CHECK_DELAY;
|
||||||
double RATEKEEPER_FAILURE_TIME;
|
double RATEKEEPER_FAILURE_TIME;
|
||||||
|
double REPLACE_INTERFACE_DELAY;
|
||||||
|
double REPLACE_INTERFACE_CHECK_DELAY;
|
||||||
|
|
||||||
// Knobs used to select the best policy (via monte carlo)
|
// Knobs used to select the best policy (via monte carlo)
|
||||||
int POLICY_RATING_TESTS; // number of tests per policy (in order to compare)
|
int POLICY_RATING_TESTS; // number of tests per policy (in order to compare)
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
|
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
|
||||||
<Product Name='$(var.Title)'
|
<Product Name='$(var.Title)'
|
||||||
Id='{311BF306-11DD-487C-B2BC-D2A1D85DFCA3}'
|
Id='{03A2BD79-EF30-41BA-A6D3-8563B7D46810}'
|
||||||
UpgradeCode='{A95EA002-686E-4164-8356-C715B7F8B1C8}'
|
UpgradeCode='{A95EA002-686E-4164-8356-C715B7F8B1C8}'
|
||||||
Version='$(var.Version)'
|
Version='$(var.Version)'
|
||||||
Manufacturer='$(var.Manufacturer)'
|
Manufacturer='$(var.Manufacturer)'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user