Load DatabaseMigrationStateSchedule in a more performant way (#1273)

This performs a direct load-by-key (the most efficient Datastore operation),
rather than attempting to load all entities by type using an ancestor query. The
existing implementation is possibly more error-prone as well, and might be
responsible for the "cross-group transaction need to be explicitly specified"
error we're seeing.
This commit is contained in:
Ben McIlwain 2021-08-10 14:47:59 -04:00 committed by GitHub
parent f82fe3b182
commit f9184a37d5
2 changed files with 19 additions and 8 deletions

View file

@ -15,6 +15,8 @@
package google.registry.model.common;
import static com.google.common.base.Preconditions.checkArgument;
import static google.registry.model.common.EntityGroupRoot.getCrossTldKey;
import static google.registry.model.ofy.ObjectifyService.auditedOfy;
import static google.registry.persistence.transaction.TransactionManagerFactory.ofyTm;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
@ -24,6 +26,7 @@ import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSortedMap;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.annotation.Embed;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Mapify;
@ -32,6 +35,7 @@ import google.registry.model.common.TimedTransitionProperty.TimeMapper;
import google.registry.model.common.TimedTransitionProperty.TimedTransition;
import google.registry.schema.replay.DatastoreOnlyEntity;
import java.time.Duration;
import java.util.Optional;
import org.joda.time.DateTime;
/**
@ -224,13 +228,20 @@ public class DatabaseMigrationStateSchedule extends CrossTldSingleton
/** Loads the currently-set migration schedule from Datastore, or the default if none exists. */
@VisibleForTesting
static TimedTransitionProperty<MigrationState, MigrationStateTransition> getUncached() {
return ofyTm()
.transactNew(
() ->
ofyTm()
.loadSingleton(DatabaseMigrationStateSchedule.class)
.map(s -> s.migrationTransitions)
.orElse(DEFAULT_TRANSITION_MAP));
return Optional.ofNullable(
auditedOfy()
.doTransactionless(
() ->
auditedOfy()
.load()
.key(
Key.create(
getCrossTldKey(),
DatabaseMigrationStateSchedule.class,
CrossTldSingleton.SINGLETON_ID))
.now()))
.map(s -> s.migrationTransitions)
.orElse(DEFAULT_TRANSITION_MAP);
}
/**

View file

@ -325,7 +325,7 @@ public class Ofy {
}
/** Execute some work in a transactionless context. */
<R> R doTransactionless(Supplier<R> work) {
public <R> R doTransactionless(Supplier<R> work) {
try {
com.googlecode.objectify.ObjectifyService.push(
com.googlecode.objectify.ObjectifyService.ofy().transactionless());