Added `transaction_option_setter<DB>` to determine if a DB-like thing has a `->setOptions(tr)` method. This method is called in `runTransaction()` templates at the top of the retry loop and in the manual retry loops in KeyBackedTypes. Added `if constexpr(` support to the ActorCompiler to support this.
This commit is contained in:
parent
893faf7d5a
commit
dd334f1b02
|
@ -1684,6 +1684,9 @@ struct transaction_creator_traits : std::false_type {};
|
|||
template <typename T>
|
||||
struct transaction_creator_traits<T, std::void_t<typename T::TransactionT>> : std::true_type {};
|
||||
|
||||
template <typename T>
|
||||
struct transaction_creator_traits<Reference<T>> : transaction_creator_traits<T> {};
|
||||
|
||||
template <typename T>
|
||||
constexpr bool is_transaction_creator = transaction_creator_traits<T>::value;
|
||||
|
||||
|
|
|
@ -26,14 +26,13 @@
|
|||
#elif !defined(FDBCLIENT_KEYBACKEDTYPES_ACTOR_H)
|
||||
#define FDBCLIENT_KEYBACKEDTYPES_ACTOR_H
|
||||
|
||||
#include "fdbclient/KeyBackedTypes.actor.h"
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <ranges>
|
||||
|
||||
#include "fdbclient/ClientBooleanParams.h"
|
||||
#include "fdbclient/CommitTransaction.h"
|
||||
#include "fdbclient/RunTransaction.actor.h"
|
||||
#include "fdbclient/FDBOptions.g.h"
|
||||
#include "fdbclient/FDBTypes.h"
|
||||
#include "fdbclient/GenericTransactionHelper.h"
|
||||
|
@ -282,11 +281,10 @@ Future<Version> WatchableTrigger::onChangeActor(WatchableTrigger self,
|
|||
state Reference<typename DB::TransactionT> tr = db->createTransaction();
|
||||
|
||||
loop {
|
||||
if constexpr (can_set_transaction_options<DB>) {
|
||||
db->setOptions(tr);
|
||||
}
|
||||
try {
|
||||
tr->setOption(FDBTransactionOptions::PRIORITY_SYSTEM_IMMEDIATE);
|
||||
tr->setOption(FDBTransactionOptions::ACCESS_SYSTEM_KEYS);
|
||||
tr->setOption(FDBTransactionOptions::LOCK_AWARE);
|
||||
|
||||
// If the initialVersion is not set yet, then initialize it with the read version
|
||||
if (!initialVersion.present()) {
|
||||
wait(store(initialVersion, safeThreadFutureToFuture(tr->getReadVersion())));
|
||||
|
|
|
@ -34,12 +34,25 @@
|
|||
#include "fdbclient/FDBOptions.g.h"
|
||||
#include "flow/actorcompiler.h" // This must be the last #include.
|
||||
|
||||
template <typename, typename = void>
|
||||
struct transaction_option_setter : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct transaction_option_setter<Reference<T>> : transaction_option_setter<T> {};
|
||||
|
||||
template <typename T>
|
||||
constexpr bool can_set_transaction_options = transaction_option_setter<T>::value;
|
||||
|
||||
ACTOR template <class Function, class DB>
|
||||
Future<decltype(std::declval<Function>()(Reference<typename DB::TransactionT>()).getValue())> runTransaction(
|
||||
Reference<DB> db,
|
||||
Function func) {
|
||||
state Reference<typename DB::TransactionT> tr = db->createTransaction();
|
||||
loop {
|
||||
if constexpr (can_set_transaction_options<DB>) {
|
||||
db->setOptions(tr);
|
||||
}
|
||||
|
||||
try {
|
||||
// func should be idempotent; otherwise, retry will get undefined result
|
||||
state decltype(std::declval<Function>()(Reference<typename DB::TransactionT>()).getValue()) result =
|
||||
|
@ -56,6 +69,9 @@ ACTOR template <class Function, class DB>
|
|||
Future<Void> runTransactionVoid(Reference<DB> db, Function func) {
|
||||
state Reference<typename DB::TransactionT> tr = db->createTransaction();
|
||||
loop {
|
||||
if constexpr (can_set_transaction_options<DB>) {
|
||||
db->setOptions(tr);
|
||||
}
|
||||
try {
|
||||
// func should be idempotent; otherwise, retry will get undefined result
|
||||
wait(func(tr));
|
||||
|
@ -77,9 +93,9 @@ struct SystemTransactionGenerator : ReferenceCounted<SystemTransactionGenerator<
|
|||
SystemTransactionGenerator(Reference<DB> db, bool write, bool lockAware, bool immediate)
|
||||
: db(db), write(write), lockAware(lockAware), immediate(immediate) {}
|
||||
|
||||
Reference<TransactionT> createTransaction() const {
|
||||
Reference<TransactionT> tr = db->createTransaction();
|
||||
Reference<TransactionT> createTransaction() const { return db->createTransaction(); }
|
||||
|
||||
void setOptions(Reference<TransactionT> tr) const {
|
||||
if (write) {
|
||||
tr->setOption(FDBTransactionOptions::ACCESS_SYSTEM_KEYS);
|
||||
} else {
|
||||
|
@ -93,7 +109,6 @@ struct SystemTransactionGenerator : ReferenceCounted<SystemTransactionGenerator<
|
|||
if (lockAware) {
|
||||
tr->setOption(FDBTransactionOptions::LOCK_AWARE);
|
||||
}
|
||||
return tr;
|
||||
}
|
||||
|
||||
Reference<DB> db;
|
||||
|
@ -102,6 +117,9 @@ struct SystemTransactionGenerator : ReferenceCounted<SystemTransactionGenerator<
|
|||
bool immediate;
|
||||
};
|
||||
|
||||
template <typename DB>
|
||||
struct transaction_option_setter<SystemTransactionGenerator<DB>> : std::true_type {};
|
||||
|
||||
// Convenient wrapper for creating SystemTransactionGenerators.
|
||||
template <typename DB>
|
||||
auto SystemDB(Reference<DB> db, bool write = false, bool lockAware = false, bool immediate = false) {
|
||||
|
|
|
@ -1047,7 +1047,7 @@ namespace actorcompiler
|
|||
bool useContinuation = WillContinue(stmt.ifBody) || WillContinue(stmt.elseBody);
|
||||
|
||||
LineNumber(cx.target, stmt.FirstSourceLine);
|
||||
cx.target.WriteLine("if ({0})", stmt.expression);
|
||||
cx.target.WriteLine("if {1}({0})", stmt.expression, stmt.constexpr ? "constexpr " : "");
|
||||
cx.target.WriteLine("{");
|
||||
cx.target.Indent(+1);
|
||||
Function ifTarget = Compile(AsCodeBlock(stmt.ifBody), cx, useContinuation).target;
|
||||
|
|
|
@ -836,12 +836,19 @@ namespace actorcompiler
|
|||
|
||||
Statement ParseIfStatement(TokenRange toks)
|
||||
{
|
||||
var expr = toks.Consume("if")
|
||||
.First(NonWhitespace)
|
||||
toks = toks.Consume("if");
|
||||
toks = toks.SkipWhile(Whitespace);
|
||||
bool constexpr = toks.First().Value == "constexpr";
|
||||
if(constexpr) {
|
||||
toks = toks.Consume("constexpr").SkipWhile(Whitespace);
|
||||
}
|
||||
|
||||
var expr = toks.First(NonWhitespace)
|
||||
.Assert("Expected (", t => t.Value == "(")
|
||||
.GetMatchingRangeIn(toks);
|
||||
return new IfStatement {
|
||||
expression = str(NormalizeWhitespace(expr)),
|
||||
constexpr = constexpr,
|
||||
ifBody = ParseCompoundStatement(range(expr.End+1, toks.End))
|
||||
// elseBody will be filled in later if necessary by ParseElseStatement
|
||||
};
|
||||
|
|
|
@ -112,6 +112,7 @@ namespace actorcompiler
|
|||
class IfStatement : Statement
|
||||
{
|
||||
public string expression;
|
||||
public bool constexpr;
|
||||
public Statement ifBody;
|
||||
public Statement elseBody; // might be null
|
||||
public override bool containsWait()
|
||||
|
|
Loading…
Reference in New Issue