2021-04-15 13:06:37 +08:00
|
|
|
/*
|
2021-04-17 08:58:00 +08:00
|
|
|
* SimpleConfigTransaction.actor.cpp
|
2021-04-15 13:06:37 +08:00
|
|
|
*
|
|
|
|
* This source file is part of the FoundationDB open source project
|
|
|
|
*
|
|
|
|
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
2021-05-01 00:34:36 +08:00
|
|
|
#include "fdbclient/SimpleConfigTransaction.h"
|
2021-04-15 13:06:37 +08:00
|
|
|
#include "fdbclient/CommitTransaction.h"
|
|
|
|
#include "flow/Arena.h"
|
|
|
|
#include "flow/actorcompiler.h" // This must be the last #include.
|
|
|
|
|
2021-04-17 08:58:00 +08:00
|
|
|
class SimpleConfigTransactionImpl {
|
2021-04-16 03:44:45 +08:00
|
|
|
Standalone<VectorRef<MutationRef>> mutations;
|
2021-04-15 13:06:37 +08:00
|
|
|
Future<Version> version;
|
2021-04-17 08:58:00 +08:00
|
|
|
ConfigTransactionInterface cti;
|
2021-04-23 11:43:23 +08:00
|
|
|
int numRetries{ 0 };
|
2021-05-01 00:34:36 +08:00
|
|
|
Error deferredError{ success() };
|
2021-05-01 00:43:18 +08:00
|
|
|
bool committed{ false };
|
2021-04-15 13:06:37 +08:00
|
|
|
|
2021-05-01 00:34:36 +08:00
|
|
|
ACTOR static Future<Version> getReadVersion(SimpleConfigTransactionImpl* self) {
|
2021-04-17 08:58:00 +08:00
|
|
|
ConfigTransactionGetVersionRequest req;
|
|
|
|
ConfigTransactionGetVersionReply reply =
|
|
|
|
wait(self->cti.getVersion.getReply(ConfigTransactionGetVersionRequest{}));
|
2021-04-15 13:06:37 +08:00
|
|
|
return reply.version;
|
|
|
|
}
|
|
|
|
|
2021-04-17 08:58:00 +08:00
|
|
|
ACTOR static Future<Optional<Value>> get(SimpleConfigTransactionImpl* self, KeyRef key) {
|
2021-04-15 13:06:37 +08:00
|
|
|
if (!self->version.isValid()) {
|
2021-05-01 00:34:36 +08:00
|
|
|
self->version = getReadVersion(self);
|
2021-04-15 13:06:37 +08:00
|
|
|
}
|
|
|
|
Version version = wait(self->version);
|
2021-04-17 08:58:00 +08:00
|
|
|
ConfigTransactionGetReply result = wait(self->cti.get.getReply(ConfigTransactionGetRequest(version, key)));
|
2021-04-15 13:06:37 +08:00
|
|
|
return result.value;
|
|
|
|
}
|
|
|
|
|
2021-04-24 02:39:26 +08:00
|
|
|
ACTOR static Future<Standalone<RangeResultRef>> getRange(SimpleConfigTransactionImpl* self, KeyRangeRef keys) {
|
|
|
|
if (!self->version.isValid()) {
|
2021-05-01 00:34:36 +08:00
|
|
|
self->version = getReadVersion(self);
|
2021-04-24 02:39:26 +08:00
|
|
|
}
|
|
|
|
Version version = wait(self->version);
|
|
|
|
ConfigTransactionGetRangeReply result =
|
|
|
|
wait(self->cti.getRange.getReply(ConfigTransactionGetRangeRequest(version, keys)));
|
|
|
|
return result.range;
|
|
|
|
}
|
|
|
|
|
2021-04-17 08:58:00 +08:00
|
|
|
ACTOR static Future<Void> commit(SimpleConfigTransactionImpl* self) {
|
2021-04-15 13:06:37 +08:00
|
|
|
if (!self->version.isValid()) {
|
2021-05-01 00:34:36 +08:00
|
|
|
self->version = getReadVersion(self);
|
2021-04-15 13:06:37 +08:00
|
|
|
}
|
|
|
|
Version version = wait(self->version);
|
2021-04-17 08:58:00 +08:00
|
|
|
wait(self->cti.commit.getReply(ConfigTransactionCommitRequest(version, self->mutations)));
|
2021-05-01 00:43:18 +08:00
|
|
|
self->committed = true;
|
2021-04-15 13:06:37 +08:00
|
|
|
return Void();
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2021-04-17 08:58:00 +08:00
|
|
|
SimpleConfigTransactionImpl(ClusterConnectionString const& ccs) {
|
2021-04-15 13:06:37 +08:00
|
|
|
auto coordinators = ccs.coordinators();
|
|
|
|
std::sort(coordinators.begin(), coordinators.end());
|
2021-04-17 08:58:00 +08:00
|
|
|
cti = ConfigTransactionInterface(coordinators[0]);
|
2021-04-15 13:06:37 +08:00
|
|
|
}
|
|
|
|
|
2021-04-16 03:44:45 +08:00
|
|
|
void set(KeyRef key, ValueRef value) {
|
|
|
|
mutations.emplace_back_deep(mutations.arena(), MutationRef::Type::SetValue, key, value);
|
|
|
|
}
|
2021-04-15 13:06:37 +08:00
|
|
|
|
2021-04-25 04:37:15 +08:00
|
|
|
void clear(KeyRef key) {
|
|
|
|
mutations.emplace_back_deep(mutations.arena(), MutationRef::Type::ClearRange, key, keyAfter(key));
|
|
|
|
ASSERT(keyAfter(key) > key);
|
|
|
|
}
|
|
|
|
|
2021-04-15 13:06:37 +08:00
|
|
|
void clearRange(KeyRef begin, KeyRef end) {
|
2021-04-16 03:44:45 +08:00
|
|
|
mutations.emplace_back_deep(mutations.arena(), MutationRef::Type::ClearRange, begin, end);
|
2021-04-15 13:06:37 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Future<Optional<Value>> get(KeyRef key) { return get(this, key); }
|
|
|
|
|
2021-04-24 02:39:26 +08:00
|
|
|
Future<Standalone<RangeResultRef>> getRange(KeyRangeRef keys) { return getRange(this, keys); }
|
|
|
|
|
2021-04-15 13:06:37 +08:00
|
|
|
Future<Void> commit() { return commit(this); }
|
|
|
|
|
2021-04-23 11:43:23 +08:00
|
|
|
Future<Void> onError(Error const& e) {
|
|
|
|
// TODO: Improve this:
|
|
|
|
if (e.code() == error_code_transaction_too_old) {
|
|
|
|
reset();
|
|
|
|
return delay((1 << numRetries++) * 0.01 * deterministicRandom()->random01());
|
|
|
|
}
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
|
2021-05-01 00:34:36 +08:00
|
|
|
Future<Version> getReadVersion() {
|
2021-04-23 11:43:23 +08:00
|
|
|
if (!version.isValid())
|
2021-05-01 00:34:36 +08:00
|
|
|
version = getReadVersion(this);
|
2021-04-23 11:43:23 +08:00
|
|
|
return version;
|
|
|
|
}
|
2021-04-16 03:44:45 +08:00
|
|
|
|
2021-05-01 00:43:18 +08:00
|
|
|
Version getCommittedVersion() const { return committed ? version.get() : ::invalidVersion; }
|
|
|
|
|
2021-04-16 03:44:45 +08:00
|
|
|
void reset() {
|
2021-04-23 11:43:23 +08:00
|
|
|
version = Future<Version>{};
|
2021-04-16 03:44:45 +08:00
|
|
|
mutations = Standalone<VectorRef<MutationRef>>{};
|
|
|
|
}
|
2021-04-23 11:43:23 +08:00
|
|
|
|
|
|
|
void fullReset() {
|
|
|
|
numRetries = 0;
|
|
|
|
reset();
|
|
|
|
}
|
2021-04-15 13:06:37 +08:00
|
|
|
|
2021-05-01 00:34:36 +08:00
|
|
|
Error& getMutableDeferredError() { return deferredError; }
|
|
|
|
|
|
|
|
}; // SimpleConfigTransactionImpl
|
|
|
|
|
|
|
|
void SimpleConfigTransaction::setVersion(Version) {
|
|
|
|
throw client_invalid_operation();
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<Version> SimpleConfigTransaction::getReadVersion() {
|
|
|
|
return impl->getReadVersion();
|
|
|
|
}
|
|
|
|
|
|
|
|
Optional<Version> SimpleConfigTransaction::getCachedReadVersion() {
|
|
|
|
// TODO: Implement?
|
|
|
|
throw client_invalid_operation();
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<Optional<Value>> SimpleConfigTransaction::get(Key const& key, bool snapshot) {
|
|
|
|
return impl->get(key);
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<Standalone<VectorRef<const char*>>> SimpleConfigTransaction::getAddressesForKey(Key const& key) {
|
|
|
|
throw client_invalid_operation();
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<Standalone<VectorRef<KeyRef>>> SimpleConfigTransaction::getRangeSplitPoints(KeyRange const& range,
|
|
|
|
int64_t chunkSize) {
|
|
|
|
throw client_invalid_operation();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleConfigTransaction::addReadConflictRange(KeyRangeRef const& keys) {
|
|
|
|
throw client_invalid_operation();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleConfigTransaction::makeSelfConflicting() {
|
|
|
|
throw client_invalid_operation();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleConfigTransaction::atomicOp(KeyRef const& key, ValueRef const& operand, uint32_t operationType) {
|
|
|
|
throw client_invalid_operation();
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<int64_t> SimpleConfigTransaction::getEstimatedRangeSizeBytes(KeyRange const& keys) {
|
|
|
|
throw client_invalid_operation();
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<Key> SimpleConfigTransaction::getKey(KeySelector const& key, bool snapshot) {
|
|
|
|
throw client_invalid_operation();
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<Standalone<RangeResultRef>> SimpleConfigTransaction::getRange(KeySelector const& begin,
|
|
|
|
KeySelector const& end,
|
|
|
|
int limit,
|
|
|
|
bool snapshot,
|
|
|
|
bool reverse) {
|
|
|
|
return impl->getRange(KeyRangeRef(begin.getKey(), end.getKey()));
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<Standalone<RangeResultRef>> SimpleConfigTransaction::getRange(KeySelector begin,
|
|
|
|
KeySelector end,
|
|
|
|
GetRangeLimits limits,
|
|
|
|
bool snapshot,
|
|
|
|
bool reverse) {
|
|
|
|
return impl->getRange(KeyRangeRef(begin.getKey(), end.getKey()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleConfigTransaction::set(KeyRef const& key, ValueRef const& value) {
|
2021-04-15 13:06:37 +08:00
|
|
|
impl->set(key, value);
|
|
|
|
}
|
|
|
|
|
2021-05-01 00:34:36 +08:00
|
|
|
void SimpleConfigTransaction::clear(KeyRef const& key) {
|
2021-04-25 04:37:15 +08:00
|
|
|
impl->clear(key);
|
|
|
|
}
|
|
|
|
|
2021-05-01 00:34:36 +08:00
|
|
|
void SimpleConfigTransaction::clear(KeyRangeRef const& range) {
|
|
|
|
impl->clearRange(range.begin, range.end);
|
2021-04-15 13:06:37 +08:00
|
|
|
}
|
|
|
|
|
2021-05-01 00:34:36 +08:00
|
|
|
Future<Void> SimpleConfigTransaction::watch(Key const& key) {
|
|
|
|
throw client_invalid_operation();
|
2021-04-15 13:06:37 +08:00
|
|
|
}
|
|
|
|
|
2021-05-01 00:34:36 +08:00
|
|
|
void SimpleConfigTransaction::addWriteConflictRange(KeyRangeRef const& keys) {
|
|
|
|
throw client_invalid_operation();
|
2021-04-24 02:39:26 +08:00
|
|
|
}
|
|
|
|
|
2021-04-17 08:58:00 +08:00
|
|
|
Future<Void> SimpleConfigTransaction::commit() {
|
2021-04-15 13:06:37 +08:00
|
|
|
return impl->commit();
|
|
|
|
}
|
|
|
|
|
2021-05-01 00:34:36 +08:00
|
|
|
Version SimpleConfigTransaction::getCommittedVersion() {
|
2021-05-01 00:43:18 +08:00
|
|
|
return impl->getCommittedVersion();
|
2021-05-01 00:34:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int64_t SimpleConfigTransaction::getApproximateSize() {
|
|
|
|
// TODO: Implement
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Future<Standalone<StringRef>> SimpleConfigTransaction::getVersionstamp() {
|
|
|
|
throw client_invalid_operation();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleConfigTransaction::setOption(FDBTransactionOptions::Option option, Optional<StringRef> value) {
|
|
|
|
// TODO: Support using this option to determine atomicity
|
|
|
|
}
|
|
|
|
|
2021-04-17 08:58:00 +08:00
|
|
|
Future<Void> SimpleConfigTransaction::onError(Error const& e) {
|
2021-04-15 13:06:37 +08:00
|
|
|
return impl->onError(e);
|
|
|
|
}
|
|
|
|
|
2021-05-01 00:34:36 +08:00
|
|
|
void SimpleConfigTransaction::cancel() {
|
|
|
|
// TODO: Implement
|
|
|
|
throw client_invalid_operation();
|
2021-04-23 11:43:23 +08:00
|
|
|
}
|
|
|
|
|
2021-04-17 08:58:00 +08:00
|
|
|
void SimpleConfigTransaction::reset() {
|
2021-04-16 03:44:45 +08:00
|
|
|
return impl->reset();
|
|
|
|
}
|
|
|
|
|
2021-04-23 11:43:23 +08:00
|
|
|
void SimpleConfigTransaction::fullReset() {
|
|
|
|
return impl->reset();
|
|
|
|
}
|
|
|
|
|
2021-05-01 00:34:36 +08:00
|
|
|
void SimpleConfigTransaction::debugTransaction(UID dID) {
|
|
|
|
// TODO: Implement
|
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleConfigTransaction::checkDeferredError() {
|
|
|
|
// TODO: Implement
|
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleConfigTransaction::getWriteConflicts(KeyRangeMap<bool>* result) {}
|
|
|
|
|
|
|
|
Error& SimpleConfigTransaction::getMutableDeferredError() {
|
|
|
|
return impl->getMutableDeferredError();
|
|
|
|
}
|
|
|
|
|
2021-04-17 08:58:00 +08:00
|
|
|
SimpleConfigTransaction::SimpleConfigTransaction(ClusterConnectionString const& ccs)
|
|
|
|
: impl(std::make_unique<SimpleConfigTransactionImpl>(ccs)) {}
|
2021-04-15 13:06:37 +08:00
|
|
|
|
2021-04-17 08:58:00 +08:00
|
|
|
SimpleConfigTransaction::~SimpleConfigTransaction() = default;
|