commit
5bdf5aaeb6
|
@ -52,25 +52,6 @@ struct FDBLibTLSVerifyTest {
|
|||
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) {
|
||||
std::string s;
|
||||
for (auto &pair: criteria) {
|
||||
|
|
|
@ -258,8 +258,6 @@ namespace FDB {
|
|||
|
||||
typedef Standalone<KeyRangeRef> KeyRange;
|
||||
|
||||
std::string printable( const StringRef& val );
|
||||
|
||||
template <class T>
|
||||
static std::string describe(T const& item) {
|
||||
return item.toString();
|
||||
|
|
|
@ -422,16 +422,4 @@ namespace FDB {
|
|||
void TransactionImpl::reset() {
|
||||
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));
|
||||
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)));
|
||||
return Void();
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ struct DirectoryCreateLayerFunc : InstructionFunc {
|
|||
else {
|
||||
Subspace* nodeSubspace = data->directoryData.directoryList[index1].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)));
|
||||
}
|
||||
|
||||
|
@ -158,7 +158,7 @@ struct DirectoryChangeFunc : InstructionFunc {
|
|||
|
||||
if(LOG_DIRS) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -192,7 +192,7 @@ struct DirectoryCreateOrOpenFunc : InstructionFunc {
|
|||
Standalone<StringRef> layer = layerTuple.getType(0) == Tuple::NULL_TYPE ? StringRef() : layerTuple.getString(0);
|
||||
|
||||
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] () {
|
||||
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);
|
||||
|
||||
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] () {
|
||||
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);
|
||||
|
||||
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));
|
||||
data->directoryData.push(dirSubspace);
|
||||
|
||||
|
@ -433,7 +433,7 @@ struct DirectoryUnpackKeyFunc : InstructionFunc {
|
|||
ACTOR static Future<Void> call(Reference<FlowTesterData> data, Reference<InstructionData> instruction) {
|
||||
Tuple key = wait(data->stack.waitAndPop());
|
||||
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));
|
||||
for(int i = 0; i < tuple.size(); ++i) {
|
||||
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) {
|
||||
Tuple tuple = wait(popTuple(data));
|
||||
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));
|
||||
data->directoryData.push(child);
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ std::string tupleToString(Tuple const& tuple) {
|
|||
if(type == Tuple::UTF8) {
|
||||
str += "u";
|
||||
}
|
||||
str += "\'" + printable(tuple.getString(i)) + "\'";
|
||||
str += "\'" + tuple.getString(i).printable() + "\'";
|
||||
}
|
||||
else if(type == Tuple::INT) {
|
||||
str += format("%ld", tuple.getInt(i));
|
||||
|
@ -220,9 +220,9 @@ ACTOR static Future<Void> debugPrintRange(Reference<Transaction> tr, std::string
|
|||
|
||||
Standalone<RangeResultRef> results = wait(getRange(tr, KeyRange(KeyRangeRef(subspace + '\x00', subspace + '\xff'))));
|
||||
printf("==================================================DB:%s:%s, count:%d\n", msg.c_str(),
|
||||
printable(subspace).c_str(), results.size());
|
||||
StringRef(subspace).printable().c_str(), results.size());
|
||||
for (auto & s : results) {
|
||||
printf("=====key:%s, value:%s\n", printable(StringRef(s.key)).c_str(), printable(StringRef(s.value)).c_str());
|
||||
printf("=====key:%s, value:%s\n", StringRef(s.key).printable().c_str(), StringRef(s.value).printable().c_str());
|
||||
}
|
||||
|
||||
return Void();
|
||||
|
@ -1791,7 +1791,7 @@ ACTOR void _test_versionstamp() {
|
|||
|
||||
ASSERT(trVersion.compare(dbVersion) == 0);
|
||||
|
||||
fprintf(stderr, "%s\n", printable(trVersion).c_str());
|
||||
fprintf(stderr, "%s\n", trVersion.printable().c_str());
|
||||
|
||||
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.
|
||||
|
||||
* `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
|
||||
------
|
||||
|
||||
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-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-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.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
|
||||
---------------
|
||||
|
||||
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-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-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.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
|
||||
---------------
|
||||
|
||||
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-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-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.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
|
||||
-------
|
||||
|
||||
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
|
||||
=====================
|
||||
|
@ -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:
|
||||
|
||||
* `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+
|
||||
-----------------
|
||||
|
||||
* `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+
|
||||
-------
|
||||
|
||||
* `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.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.jar <https://www.foundationdb.org/downloads/6.1.9/bindings/java/fdb-java-6.1.9.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+
|
||||
--------
|
||||
|
|
|
@ -42,6 +42,15 @@ struct ClusterInterface {
|
|||
UID id() const { return openDatabase.getEndpoint().token; }
|
||||
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() {
|
||||
openDatabase.getEndpoint( TaskClusterController );
|
||||
failureMonitoring.getEndpoint( TaskFailureMonitor );
|
||||
|
|
|
@ -392,17 +392,17 @@ namespace HTTP {
|
|||
responseID = iid->second;
|
||||
}
|
||||
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();
|
||||
|
||||
// Log a non-debug a error
|
||||
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")
|
||||
TraceEvent(SevError, "HTTPRequestFailedIDMismatch")
|
||||
.detail("DebugID", conn->getDebugID())
|
||||
.detail("RemoteAddress", conn->getPeerAddress())
|
||||
.detail("Verb", verb)
|
||||
|
@ -433,6 +433,7 @@ namespace HTTP {
|
|||
return r;
|
||||
} catch(Error &e) {
|
||||
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) {
|
||||
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);
|
||||
|
|
|
@ -2745,7 +2745,8 @@ Future<Void> Transaction::commitMutations() {
|
|||
.detail("Size", transactionSize)
|
||||
.detail("NumMutations", tr.transaction.mutations.size())
|
||||
.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)) {
|
||||
|
@ -2898,15 +2899,15 @@ void Transaction::setOption( FDBTransactionOptions::Option option, Optional<Stri
|
|||
|
||||
if (trLogInfo) {
|
||||
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());
|
||||
throw client_invalid_operation();
|
||||
}
|
||||
}
|
||||
else {
|
||||
trLogInfo = Reference<TransactionLogInfo>(new TransactionLogInfo(printable(value.get()), TransactionLogInfo::DONT_LOG));
|
||||
trLogInfo = Reference<TransactionLogInfo>(new TransactionLogInfo(value.get().printable(), TransactionLogInfo::DONT_LOG));
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -404,6 +404,7 @@ struct Peer : NonCopyable {
|
|||
state ReplyPromise<Void> reply;
|
||||
FlowTransport::transport().sendUnreliable( SerializeSource<ReplyPromise<Void>>(reply), remotePing.getEndpoint() );
|
||||
state int64_t startingBytes = peer->bytesReceived;
|
||||
state int timeouts = 0;
|
||||
loop {
|
||||
choose {
|
||||
when (wait( delay( FLOW_KNOBS->CONNECTION_MONITOR_TIMEOUT ) )) {
|
||||
|
@ -411,7 +412,11 @@ struct Peer : NonCopyable {
|
|||
TraceEvent("ConnectionTimeout").suppressFor(1.0).detail("WithAddr", peer->destination);
|
||||
throw connection_failed();
|
||||
}
|
||||
if(timeouts > 1) {
|
||||
TraceEvent(SevWarnAlways, "ConnectionSlowPing").suppressFor(1.0).detail("WithAddr", peer->destination).detail("Timeouts", timeouts);
|
||||
}
|
||||
startingBytes = peer->bytesReceived;
|
||||
timeouts++;
|
||||
}
|
||||
when (wait( reply.getFuture() )) {
|
||||
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 ) {
|
||||
loop {
|
||||
state ClusterControllerFullInterface cci;
|
||||
|
@ -2713,19 +2723,23 @@ ACTOR Future<Void> clusterController( ServerCoordinators coordinators, Reference
|
|||
try {
|
||||
//Register as a possible leader; wait to be elected
|
||||
state Future<Void> leaderFail = tryBecomeLeader( coordinators, cci, currentCC, hasConnected, asyncPriorityInfo );
|
||||
state Future<Void> shouldReplace = replaceInterface( cci );
|
||||
|
||||
while (!currentCC->get().present() || currentCC->get().get() != cci) {
|
||||
choose {
|
||||
when( wait(currentCC->onChange()) ) {}
|
||||
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;
|
||||
startRole(Role::CLUSTER_CONTROLLER, cci.id(), UID());
|
||||
inRole = true;
|
||||
|
||||
wait( clusterControllerCore( cci, leaderFail, coordinators, locality ) );
|
||||
wait( clusterControllerCore( cci, leaderFail, coordinators, locality ) );
|
||||
}
|
||||
} catch(Error& e) {
|
||||
if (inRole)
|
||||
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 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() {
|
||||
clientInterface.initEndpoints();
|
||||
recruitFromConfiguration.getEndpoint( TaskClusterController );
|
||||
|
|
|
@ -355,17 +355,6 @@ struct CompactPreOrderTree {
|
|||
#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 = "") {
|
||||
double t1, t2;
|
||||
int r = 0;
|
||||
|
|
|
@ -271,38 +271,22 @@ ACTOR Future<Void> leaderRegister(LeaderElectionRegInterface interf, Key key) {
|
|||
return Void();
|
||||
} else {
|
||||
Optional<LeaderInfo> nextNominee;
|
||||
if (availableLeaders.size() && availableCandidates.size()) {
|
||||
nextNominee = ( *availableLeaders.begin() < *availableCandidates.begin() ) ? *availableLeaders.begin() : *availableCandidates.begin();
|
||||
} else if (availableLeaders.size()) {
|
||||
nextNominee = *availableLeaders.begin();
|
||||
} else if (availableCandidates.size()) {
|
||||
if( availableCandidates.size() && (!availableLeaders.size() || availableLeaders.begin()->leaderChangeRequired(*availableCandidates.begin())) ) {
|
||||
nextNominee = *availableCandidates.begin();
|
||||
} else {
|
||||
nextNominee = Optional<LeaderInfo>();
|
||||
} else if( availableLeaders.size() ) {
|
||||
nextNominee = *availableLeaders.begin();
|
||||
}
|
||||
|
||||
bool foundCurrentNominee = false;
|
||||
if(currentNominee.present()) {
|
||||
for(auto& it : availableLeaders) {
|
||||
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);
|
||||
if( !currentNominee.present() || !nextNominee.present() || !currentNominee.get().equalInternalId(nextNominee.get()) || nextNominee.get() > currentNominee.get() ) {
|
||||
TraceEvent("NominatingLeader").detail("NextNominee", nextNominee.present() ? nextNominee.get().changeID : UID())
|
||||
.detail("CurrentNominee", currentNominee.present() ? currentNominee.get().changeID : UID()).detail("Key", printable(key));
|
||||
for(unsigned int i=0; i<notify.size(); i++)
|
||||
notify[i].send( nextNominee );
|
||||
notify.clear();
|
||||
currentNominee = nextNominee;
|
||||
} else if (currentNominee.get().equalInternalId(nextNominee.get())) {
|
||||
// leader becomes better
|
||||
currentNominee = nextNominee;
|
||||
}
|
||||
|
||||
currentNominee = nextNominee;
|
||||
|
||||
if( availableLeaders.size() ) {
|
||||
nextInterval = delay( SERVER_KNOBS->POLLING_FREQUENCY );
|
||||
if(leaderIntervalCount++ > 5) {
|
||||
|
|
|
@ -327,6 +327,8 @@ ServerKnobs::ServerKnobs(bool randomize, ClientKnobs* clientKnobs) {
|
|||
init( MAX_VERSION_DIFFERENCE, 20 * VERSIONS_PER_SECOND );
|
||||
init( FORCE_RECOVERY_CHECK_DELAY, 5.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( EXPECTED_MASTER_FITNESS, ProcessClass::UnsetFit );
|
||||
|
|
|
@ -269,6 +269,8 @@ public:
|
|||
int64_t MAX_VERSION_DIFFERENCE;
|
||||
double FORCE_RECOVERY_CHECK_DELAY;
|
||||
double RATEKEEPER_FAILURE_TIME;
|
||||
double REPLACE_INTERFACE_DELAY;
|
||||
double REPLACE_INTERFACE_CHECK_DELAY;
|
||||
|
||||
// Knobs used to select the best policy (via monte carlo)
|
||||
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'>
|
||||
<Product Name='$(var.Title)'
|
||||
Id='{311BF306-11DD-487C-B2BC-D2A1D85DFCA3}'
|
||||
Id='{03A2BD79-EF30-41BA-A6D3-8563B7D46810}'
|
||||
UpgradeCode='{A95EA002-686E-4164-8356-C715B7F8B1C8}'
|
||||
Version='$(var.Version)'
|
||||
Manufacturer='$(var.Manufacturer)'
|
||||
|
|
Loading…
Reference in New Issue