diff --git a/java/google/registry/flows/domain/DomainAllocateFlow.java b/java/google/registry/flows/domain/DomainAllocateFlow.java index 52898200c..c8f804c1f 100644 --- a/java/google/registry/flows/domain/DomainAllocateFlow.java +++ b/java/google/registry/flows/domain/DomainAllocateFlow.java @@ -20,7 +20,6 @@ import static google.registry.flows.FlowUtils.validateClientIsLoggedIn; import static google.registry.flows.ResourceFlowUtils.verifyResourceDoesNotExist; import static google.registry.flows.domain.DomainFlowUtils.cloneAndLinkReferences; import static google.registry.flows.domain.DomainFlowUtils.createFeeCreateResponse; -import static google.registry.flows.domain.DomainFlowUtils.failfastForCreate; import static google.registry.flows.domain.DomainFlowUtils.getReservationTypes; import static google.registry.flows.domain.DomainFlowUtils.prepareMarkedLrpTokenEntity; import static google.registry.flows.domain.DomainFlowUtils.validateCreateCommandContactsAndNameservers; @@ -139,7 +138,6 @@ public class DomainAllocateFlow implements TransactionalFlow { validateClientIsLoggedIn(clientId); verifyIsSuperuser(); DateTime now = ofy().getTransactionTime(); - failfastForCreate(targetId, now); Create command = cloneAndLinkReferences((Create) resourceCommand, now); verifyResourceDoesNotExist(DomainResource.class, targetId, now); InternetDomainName domainName = validateDomainName(command.getFullyQualifiedDomainName()); diff --git a/java/google/registry/flows/domain/DomainApplicationCreateFlow.java b/java/google/registry/flows/domain/DomainApplicationCreateFlow.java index d92cf551f..20d7e24ed 100644 --- a/java/google/registry/flows/domain/DomainApplicationCreateFlow.java +++ b/java/google/registry/flows/domain/DomainApplicationCreateFlow.java @@ -21,7 +21,6 @@ import static google.registry.flows.ResourceFlowUtils.verifyResourceDoesNotExist import static google.registry.flows.domain.DomainFlowUtils.checkAllowedAccessToTld; import static google.registry.flows.domain.DomainFlowUtils.cloneAndLinkReferences; import static google.registry.flows.domain.DomainFlowUtils.createFeeCreateResponse; -import static google.registry.flows.domain.DomainFlowUtils.failfastForCreate; import static google.registry.flows.domain.DomainFlowUtils.prepareMarkedLrpTokenEntity; import static google.registry.flows.domain.DomainFlowUtils.validateCreateCommandContactsAndNameservers; import static google.registry.flows.domain.DomainFlowUtils.validateDomainName; @@ -195,7 +194,6 @@ public final class DomainApplicationCreateFlow implements TransactionalFlow { extensionManager.validate(); validateClientIsLoggedIn(clientId); DateTime now = ofy().getTransactionTime(); - failfastForCreate(targetId, now); Create command = cloneAndLinkReferences((Create) resourceCommand, now); // Fail if the domain is already registered (e.g. this is a landrush application but the domain // was awarded at the end of sunrise). However, multiple domain applications can be created for diff --git a/java/google/registry/flows/domain/DomainApplicationInfoFlow.java b/java/google/registry/flows/domain/DomainApplicationInfoFlow.java index 89013141b..c81c6d288 100644 --- a/java/google/registry/flows/domain/DomainApplicationInfoFlow.java +++ b/java/google/registry/flows/domain/DomainApplicationInfoFlow.java @@ -89,7 +89,7 @@ public final class DomainApplicationInfoFlow implements Flow { throw new MissingApplicationIdException(); } DomainApplication application = - ofy().loadWithMemcache().key(Key.create(DomainApplication.class, applicationId)).now(); + ofy().load().key(Key.create(DomainApplication.class, applicationId)).now(); verifyExistence( DomainApplication.class, applicationId, @@ -106,7 +106,7 @@ public final class DomainApplicationInfoFlow implements Flow { verifyResourceOwnership(clientId, application); boolean showDelegatedHosts = ((Info) resourceCommand).getHostsRequest().requestDelegated(); // Prefetch all referenced resources. Calling values() blocks until loading is done. - ofy().loadWithMemcache() + ofy().load() .values(union(application.getNameservers(), application.getReferencedContacts())).values(); return responseBuilder .setResData(DomainInfoData.newBuilder() @@ -114,7 +114,7 @@ public final class DomainApplicationInfoFlow implements Flow { .setRepoId(application.getRepoId()) .setStatusValues(application.getStatusValues()) .setRegistrant( - ofy().loadWithMemcache().key(application.getRegistrant()).now().getContactId()) + ofy().load().key(application.getRegistrant()).now().getContactId()) .setContacts(loadForeignKeyedDesignatedContacts(application.getContacts())) .setNameservers(showDelegatedHosts ? application.loadNameserverFullyQualifiedHostNames() diff --git a/java/google/registry/flows/domain/DomainCreateFlow.java b/java/google/registry/flows/domain/DomainCreateFlow.java index b30271a48..7a53463e1 100644 --- a/java/google/registry/flows/domain/DomainCreateFlow.java +++ b/java/google/registry/flows/domain/DomainCreateFlow.java @@ -20,7 +20,6 @@ import static google.registry.flows.ResourceFlowUtils.verifyResourceDoesNotExist import static google.registry.flows.domain.DomainFlowUtils.checkAllowedAccessToTld; import static google.registry.flows.domain.DomainFlowUtils.cloneAndLinkReferences; import static google.registry.flows.domain.DomainFlowUtils.createFeeCreateResponse; -import static google.registry.flows.domain.DomainFlowUtils.failfastForCreate; import static google.registry.flows.domain.DomainFlowUtils.prepareMarkedLrpTokenEntity; import static google.registry.flows.domain.DomainFlowUtils.validateCreateCommandContactsAndNameservers; import static google.registry.flows.domain.DomainFlowUtils.validateDomainAllowedOnCreateRestrictedTld; @@ -193,7 +192,6 @@ public class DomainCreateFlow implements TransactionalFlow { extensionManager.validate(); validateClientIsLoggedIn(clientId); DateTime now = ofy().getTransactionTime(); - failfastForCreate(targetId, now); Create command = cloneAndLinkReferences((Create) resourceCommand, now); Period period = command.getPeriod(); verifyUnitIsYears(period); diff --git a/java/google/registry/flows/domain/DomainFlowUtils.java b/java/google/registry/flows/domain/DomainFlowUtils.java index b7c681733..b199f9582 100644 --- a/java/google/registry/flows/domain/DomainFlowUtils.java +++ b/java/google/registry/flows/domain/DomainFlowUtils.java @@ -22,7 +22,6 @@ import static com.google.common.collect.Sets.difference; import static com.google.common.collect.Sets.intersection; import static com.google.common.collect.Sets.union; import static google.registry.flows.domain.DomainPricingLogic.getMatchingLrpToken; -import static google.registry.model.EppResourceUtils.loadByForeignKeyWithMemcache; import static google.registry.model.domain.DomainResource.MAX_REGISTRATION_YEARS; import static google.registry.model.ofy.ObjectifyService.ofy; import static google.registry.model.registry.Registries.findTldForName; @@ -48,7 +47,6 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; import com.google.common.net.InternetDomainName; import com.googlecode.objectify.Key; -import com.googlecode.objectify.Work; import google.registry.flows.EppException; import google.registry.flows.EppException.AuthorizationErrorException; import google.registry.flows.EppException.CommandUseErrorException; @@ -60,7 +58,6 @@ import google.registry.flows.EppException.ParameterValueSyntaxErrorException; import google.registry.flows.EppException.RequiredParameterMissingException; import google.registry.flows.EppException.StatusProhibitsOperationException; import google.registry.flows.EppException.UnimplementedOptionException; -import google.registry.flows.exceptions.ResourceAlreadyExistsException; import google.registry.flows.exceptions.ResourceHasClientUpdateProhibitedException; import google.registry.model.EppResource; import google.registry.model.billing.BillingEvent; @@ -90,7 +87,6 @@ import google.registry.model.domain.launch.LaunchExtension; import google.registry.model.domain.launch.LaunchNotice; import google.registry.model.domain.launch.LaunchNotice.InvalidChecksumException; import google.registry.model.domain.launch.LaunchPhase; -import google.registry.model.domain.rgp.GracePeriodStatus; import google.registry.model.domain.secdns.DelegationSignerData; import google.registry.model.domain.secdns.SecDnsCreateExtension; import google.registry.model.domain.secdns.SecDnsInfoExtension; @@ -432,8 +428,6 @@ public class DomainFlowUtils { static void verifyPremiumNameIsNotBlocked( String domainName, DateTime priceTime, String clientId) throws EppException { if (isDomainPremium(domainName, priceTime)) { - // NB: The load of the Registar object is transactionless, which means that it should hit - // memcache most of the time. if (Registrar.loadByClientIdCached(clientId).getBlockPremiumNames()) { throw new PremiumNameBlockedException(); } @@ -783,36 +777,6 @@ public class DomainFlowUtils { validateNameserversAllowedOnDomain(domainName, fullyQualifiedHostNames); } - /** - * Fail a domain or application create very fast if the domain is already registered. - * - *

Try to load the domain non-transactionally, since this can hit memcache. If we succeed, and - * the domain is not in the add grace period (the only state that allows instantaneous transition - * to being deleted), we can assume that the domain will not be deleted (and therefore won't be - * creatable) until its deletion time. For repeated failed creates this means we can avoid the - * Datastore lookup, which is very expensive (and first-seen failed creates are no worse than they - * otherwise would be). This comes at the cost of the extra lookup for successful creates (or - * rather, those that don't fail due to the domain existing) and also for failed creates within - * the existing domain's add grace period. - */ - static void failfastForCreate(final String targetId, final DateTime now) throws EppException { - // Enter a transactionless context briefly. - DomainResource domain = ofy().doTransactionless(new Work() { - @Override - public DomainResource run() { - // We want to load the ForeignKeyIndex and DomainResource from memcache if possible so that - // repeated create attempts of the same domain will not put load on datastore. This is safe - // because this is only a failfast method, and if memcache is stale the worst case scenario - // is that we will fall through to the regular transactional flow and fail there. - return loadByForeignKeyWithMemcache(DomainResource.class, targetId, now); - }}); - // If the domain exists already and isn't in the add grace period then there is no way it will - // be suddenly deleted and therefore the create must fail. - if (domain != null && !domain.getGracePeriodStatuses().contains(GracePeriodStatus.ADD)) { - throw new ResourceAlreadyExistsException(targetId, true); - } - } - /** Validate the secDNS extension, if present. */ static SecDnsCreateExtension validateSecDnsExtension(SecDnsCreateExtension secDnsCreate) throws EppException { diff --git a/java/google/registry/flows/domain/DomainInfoFlow.java b/java/google/registry/flows/domain/DomainInfoFlow.java index a8953195e..a4134db3c 100644 --- a/java/google/registry/flows/domain/DomainInfoFlow.java +++ b/java/google/registry/flows/domain/DomainInfoFlow.java @@ -21,7 +21,7 @@ import static google.registry.flows.ResourceFlowUtils.verifyOptionalAuthInfo; import static google.registry.flows.domain.DomainFlowUtils.addSecDnsExtensionIfPresent; import static google.registry.flows.domain.DomainFlowUtils.handleFeeRequest; import static google.registry.flows.domain.DomainFlowUtils.loadForeignKeyedDesignatedContacts; -import static google.registry.model.EppResourceUtils.loadByForeignKeyWithMemcache; +import static google.registry.model.EppResourceUtils.loadByForeignKey; import static google.registry.model.ofy.ObjectifyService.ofy; import com.google.common.base.Optional; @@ -96,13 +96,11 @@ public final class DomainInfoFlow implements Flow { validateClientIsLoggedIn(clientId); DateTime now = clock.nowUtc(); DomainResource domain = verifyExistence( - DomainResource.class, - targetId, - loadByForeignKeyWithMemcache(DomainResource.class, targetId, now)); + DomainResource.class, targetId, loadByForeignKey(DomainResource.class, targetId, now)); verifyOptionalAuthInfo(authInfo, domain); customLogic.afterValidation(AfterValidationParameters.newBuilder().setDomain(domain).build()); // Prefetch all referenced resources. Calling values() blocks until loading is done. - ofy().loadWithMemcache() + ofy().load() .values(union(domain.getNameservers(), domain.getReferencedContacts())).values(); // Registrars can only see a few fields on unauthorized domains. // This is a policy decision that is left up to us by the rfcs. @@ -110,7 +108,7 @@ public final class DomainInfoFlow implements Flow { .setFullyQualifiedDomainName(domain.getFullyQualifiedDomainName()) .setRepoId(domain.getRepoId()) .setCurrentSponsorClientId(domain.getCurrentSponsorClientId()) - .setRegistrant(ofy().loadWithMemcache().key(domain.getRegistrant()).now().getContactId()); + .setRegistrant(ofy().load().key(domain.getRegistrant()).now().getContactId()); // If authInfo is non-null, then the caller is authorized to see the full information since we // will have already verified the authInfo is valid. if (clientId.equals(domain.getCurrentSponsorClientId()) || authInfo.isPresent()) { diff --git a/java/google/registry/flows/exceptions/ResourceAlreadyExistsException.java b/java/google/registry/flows/exceptions/ResourceAlreadyExistsException.java index 487f2380a..c06305174 100644 --- a/java/google/registry/flows/exceptions/ResourceAlreadyExistsException.java +++ b/java/google/registry/flows/exceptions/ResourceAlreadyExistsException.java @@ -14,26 +14,11 @@ package google.registry.flows.exceptions; -import com.google.common.annotations.VisibleForTesting; import google.registry.flows.EppException.ObjectAlreadyExistsException; /** Resource with this id already exists. */ public class ResourceAlreadyExistsException extends ObjectAlreadyExistsException { - - /** Whether this was thrown from a "failfast" context. Useful for testing. */ - final boolean failfast; - - public ResourceAlreadyExistsException(String resourceId, boolean failfast) { - super(String.format("Object with given ID (%s) already exists", resourceId)); - this.failfast = failfast; - } - public ResourceAlreadyExistsException(String resourceId) { - this(resourceId, false); - } - - @VisibleForTesting - public boolean isFailfast() { - return failfast; + super(String.format("Object with given ID (%s) already exists", resourceId)); } } diff --git a/java/google/registry/model/EppResourceUtils.java b/java/google/registry/model/EppResourceUtils.java index 2868f1052..50f515107 100644 --- a/java/google/registry/model/EppResourceUtils.java +++ b/java/google/registry/model/EppResourceUtils.java @@ -24,7 +24,6 @@ import static google.registry.util.DateTimeUtils.latestOf; import com.google.common.base.Function; import com.googlecode.objectify.Key; import com.googlecode.objectify.Result; -import com.googlecode.objectify.cmd.Loader; import com.googlecode.objectify.cmd.Query; import com.googlecode.objectify.util.ResultNow; import google.registry.model.EppResource.Builder; @@ -93,41 +92,16 @@ public final class EppResourceUtils { @Nullable public static T loadByForeignKey( Class clazz, String foreignKey, DateTime now) { - return loadByForeignKeyInternal(clazz, foreignKey, now, false); - } - - /** - * Loads the last created version of an {@link EppResource} from Datastore or memcache. - * - *

In general, prefer {@link #loadByForeignKey} over this method. Loading from memcache can, in - * rare instances, produce a stale result (when a memcache write fails and the previous result is - * not cleared out) and so using memcache should be avoided unless the caller can tolerate - * staleness until the memcache expiration time and there is a specific need for very low latency - * that is worth the extra complexity of reasoning about caching. - * - * @param clazz the resource type to load - * @param foreignKey id to match - * @param now the current logical time to project resources at - */ - @Nullable - public static T loadByForeignKeyWithMemcache( - Class clazz, String foreignKey, DateTime now) { - return loadByForeignKeyInternal(clazz, foreignKey, now, true); - } - - @Nullable - private static T loadByForeignKeyInternal( - Class clazz, String foreignKey, DateTime now, boolean useMemcache) { checkArgument( ForeignKeyedEppResource.class.isAssignableFrom(clazz), "loadByForeignKey may only be called for foreign keyed EPP resources"); - Loader loader = useMemcache ? ofy().loadWithMemcache() : ofy().load(); - ForeignKeyIndex fki = loader.type(ForeignKeyIndex.mapToFkiClass(clazz)).id(foreignKey).now(); + ForeignKeyIndex fki = + ofy().load().type(ForeignKeyIndex.mapToFkiClass(clazz)).id(foreignKey).now(); // The value of fki.getResourceKey() might be null for hard-deleted prober data. if (fki == null || isAtOrAfter(now, fki.getDeletionTime()) || fki.getResourceKey() == null) { return null; } - T resource = loader.key(fki.getResourceKey()).now(); + T resource = ofy().load().key(fki.getResourceKey()).now(); if (resource == null || isAtOrAfter(now, resource.getDeletionTime())) { return null; } diff --git a/java/google/registry/model/contact/ContactResource.java b/java/google/registry/model/contact/ContactResource.java index 7664a7b40..7885a4854 100644 --- a/java/google/registry/model/contact/ContactResource.java +++ b/java/google/registry/model/contact/ContactResource.java @@ -16,14 +16,12 @@ package google.registry.model.contact; import static com.google.common.base.Preconditions.checkArgument; import static google.registry.model.EppResourceUtils.projectResourceOntoBuilderAtTime; -import static google.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION; import com.google.common.base.Optional; import com.google.common.base.Predicates; import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; -import com.googlecode.objectify.annotation.Cache; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.IgnoreSave; import com.googlecode.objectify.annotation.Index; @@ -43,7 +41,6 @@ import org.joda.time.DateTime; * * @see RFC 5733 */ -@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION) @ReportedOn @Entity @ExternalMessagingName("contact") diff --git a/java/google/registry/model/domain/DomainApplication.java b/java/google/registry/model/domain/DomainApplication.java index 287c95695..76f3614a2 100644 --- a/java/google/registry/model/domain/DomainApplication.java +++ b/java/google/registry/model/domain/DomainApplication.java @@ -15,11 +15,9 @@ package google.registry.model.domain; import static google.registry.model.ofy.ObjectifyService.ofy; -import static google.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION; import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy; import com.google.common.collect.ImmutableList; -import com.googlecode.objectify.annotation.Cache; import com.googlecode.objectify.annotation.EntitySubclass; import com.googlecode.objectify.annotation.OnLoad; import google.registry.model.annotations.ExternalMessagingName; @@ -37,7 +35,6 @@ import org.joda.money.Money; import org.joda.time.DateTime; /** An application to create a domain. */ -@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION) @EntitySubclass(index = true) @ExternalMessagingName("application") public class DomainApplication extends DomainBase { diff --git a/java/google/registry/model/domain/DomainResource.java b/java/google/registry/model/domain/DomainResource.java index ac628b274..08e7fa181 100644 --- a/java/google/registry/model/domain/DomainResource.java +++ b/java/google/registry/model/domain/DomainResource.java @@ -17,7 +17,6 @@ import static com.google.common.collect.Sets.intersection; import static google.registry.model.EppResourceUtils.projectResourceOntoBuilderAtTime; import static google.registry.model.EppResourceUtils.setAutomaticTransferSuccessProperties; -import static google.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION; import static google.registry.util.CollectionUtils.difference; import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy; import static google.registry.util.CollectionUtils.union; @@ -28,7 +27,6 @@ import static google.registry.util.DateTimeUtils.leapSafeAddYears; import com.google.common.base.Optional; import com.google.common.collect.ImmutableSet; import com.googlecode.objectify.Key; -import com.googlecode.objectify.annotation.Cache; import com.googlecode.objectify.annotation.EntitySubclass; import com.googlecode.objectify.annotation.IgnoreSave; import com.googlecode.objectify.condition.IfNull; @@ -53,7 +51,6 @@ import org.joda.time.Interval; * * @see RFC 5731 */ -@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION) @EntitySubclass(index = true) @ExternalMessagingName("domain") public class DomainResource extends DomainBase diff --git a/java/google/registry/model/host/HostResource.java b/java/google/registry/model/host/HostResource.java index 9621af625..8837cad66 100644 --- a/java/google/registry/model/host/HostResource.java +++ b/java/google/registry/model/host/HostResource.java @@ -17,7 +17,6 @@ package google.registry.model.host; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.collect.Sets.difference; import static com.google.common.collect.Sets.union; -import static google.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION; import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy; import static google.registry.util.DateTimeUtils.START_OF_TIME; import static google.registry.util.DomainNameUtils.canonicalizeDomainName; @@ -25,7 +24,6 @@ import static google.registry.util.DomainNameUtils.canonicalizeDomainName; import com.google.common.base.Optional; import com.google.common.collect.ImmutableSet; import com.googlecode.objectify.Key; -import com.googlecode.objectify.annotation.Cache; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.IgnoreSave; import com.googlecode.objectify.annotation.Index; @@ -49,7 +47,6 @@ import org.joda.time.DateTime; * * @see RFC 5732 */ -@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION) @ReportedOn @Entity @ExternalMessagingName("host") diff --git a/java/google/registry/model/index/DomainApplicationIndex.java b/java/google/registry/model/index/DomainApplicationIndex.java index 11325664d..d70fdbdde 100644 --- a/java/google/registry/model/index/DomainApplicationIndex.java +++ b/java/google/registry/model/index/DomainApplicationIndex.java @@ -17,12 +17,10 @@ package google.registry.model.index; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Strings.isNullOrEmpty; import static google.registry.model.ofy.ObjectifyService.ofy; -import static google.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION; import static google.registry.util.CollectionUtils.isNullOrEmpty; import com.google.common.collect.ImmutableSet; import com.googlecode.objectify.Key; -import com.googlecode.objectify.annotation.Cache; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Id; import google.registry.model.BackupGroupRoot; @@ -40,7 +38,6 @@ import org.joda.time.DateTime; */ @ReportedOn @Entity -@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION) public class DomainApplicationIndex extends BackupGroupRoot { @Id diff --git a/java/google/registry/model/index/ForeignKeyIndex.java b/java/google/registry/model/index/ForeignKeyIndex.java index 515ea284e..89e340c3a 100644 --- a/java/google/registry/model/index/ForeignKeyIndex.java +++ b/java/google/registry/model/index/ForeignKeyIndex.java @@ -16,14 +16,12 @@ package google.registry.model.index; import static com.google.common.collect.Maps.filterValues; import static google.registry.model.ofy.ObjectifyService.ofy; -import static google.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION; import static google.registry.util.TypeUtils.instantiate; import com.google.common.base.Predicate; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.googlecode.objectify.Key; -import com.googlecode.objectify.annotation.Cache; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Id; import com.googlecode.objectify.annotation.Index; @@ -45,19 +43,16 @@ import org.joda.time.DateTime; public abstract class ForeignKeyIndex extends BackupGroupRoot { /** The {@link ForeignKeyIndex} type for {@link ContactResource} entities. */ - @Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION) @ReportedOn @Entity public static class ForeignKeyContactIndex extends ForeignKeyIndex {} /** The {@link ForeignKeyIndex} type for {@link DomainResource} entities. */ - @Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION) @ReportedOn @Entity public static class ForeignKeyDomainIndex extends ForeignKeyIndex {} /** The {@link ForeignKeyIndex} type for {@link HostResource} entities. */ - @Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION) @ReportedOn @Entity public static class ForeignKeyHostIndex extends ForeignKeyIndex {} diff --git a/java/google/registry/model/ofy/ObjectifyService.java b/java/google/registry/model/ofy/ObjectifyService.java index 05aa4097a..99022a9a9 100644 --- a/java/google/registry/model/ofy/ObjectifyService.java +++ b/java/google/registry/model/ofy/ObjectifyService.java @@ -14,7 +14,6 @@ package google.registry.model.ofy; -import static com.google.appengine.api.memcache.ErrorHandlers.getConsistentLogAndContinue; import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Predicates.not; import static com.googlecode.objectify.ObjectifyService.factory; @@ -46,7 +45,6 @@ import google.registry.model.translators.InetAddressTranslatorFactory; import google.registry.model.translators.ReadableInstantUtcTranslatorFactory; import google.registry.model.translators.UpdateAutoTimestampTranslatorFactory; import java.util.concurrent.atomic.AtomicLong; -import java.util.logging.Level; /** * An instance of Ofy, obtained via {@code #ofy()}, should be used to access all persistable @@ -114,9 +112,6 @@ public class ObjectifyService { // Translators must be registered before any entities can be registered. registerTranslators(); registerEntityClasses(EntityClasses.ALL_CLASSES); - - // Set the memcache error handler so that we don't see internally logged errors. - factory().setMemcacheErrorHandler(getConsistentLogAndContinue(Level.INFO)); } /** Register translators that allow less common types to be stored directly in Datastore. */ diff --git a/java/google/registry/model/ofy/Ofy.java b/java/google/registry/model/ofy/Ofy.java index ebe35513a..77ff577eb 100644 --- a/java/google/registry/model/ofy/Ofy.java +++ b/java/google/registry/model/ofy/Ofy.java @@ -63,15 +63,6 @@ public class Ofy { private static final FormattingLogger logger = FormattingLogger.getLoggerForCallerClass(); - /** - * Recommended memcache expiration time, which is one hour, specified in seconds. - * - *

This value should used as a cache expiration time for any entities annotated with an - * Objectify {@code @Cache} annotation, to put an upper bound on unlikely-but-possible divergence - * between memcache and Datastore when a memcache write fails. - */ - public static final int RECOMMENDED_MEMCACHE_EXPIRATION = 3600; - /** Default clock for transactions that don't provide one. */ @NonFinalForTesting static Clock clock = new SystemClock(); @@ -130,31 +121,9 @@ public class Ofy { checkState(inTransaction(), "Must be called in a transaction"); } - /** - * Load from Datastore, bypassing memcache even when the results might be there. - * - *

In general, this is the correct method to use for loads. Loading from memcache can, in rare - * instances, produce a stale result (when a memcache write fails and the previous result is not - * cleared out) and so using memcache should be avoided unless the caller can tolerate staleness - * until the memcache expiration time and there is a specific need for very low latency that is - * worth the extra complexity of reasoning about caching. - */ + /** Load from Datastore. */ public Loader load() { - return ofy().cache(false).load(); - } - - /** - * Load from Datastore, bypassing memcache even when the results might be there. - * - *

In general, prefer {@link #load} over this method. Loading from memcache can, in rare - * instances, produce a stale result (when a memcache write fails and the previous result is not - * cleared out) and so using memcache should be avoided unless the caller can tolerate staleness - * until the memcache expiration time and there is a specific need for very low latency that is - * worth the extra complexity of reasoning about caching. - */ - public Loader loadWithMemcache() { - // TODO(b/27424173): Remove this method if we determine we are ok with no memcache. - return ofy().cache(false).load(); + return ofy().load(); } /** diff --git a/java/google/registry/model/registrar/Registrar.java b/java/google/registry/model/registrar/Registrar.java index a4fe2f02b..e69d3b140 100644 --- a/java/google/registry/model/registrar/Registrar.java +++ b/java/google/registry/model/registrar/Registrar.java @@ -28,7 +28,6 @@ import static google.registry.config.RegistryConfig.getDefaultRegistrarWhoisServ import static google.registry.model.CacheUtils.memoizeWithShortExpiration; import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; import static google.registry.model.ofy.ObjectifyService.ofy; -import static google.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION; import static google.registry.model.registry.Registries.assertTldsExist; import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy; import static google.registry.util.CollectionUtils.nullToEmptyImmutableSortedCopy; @@ -50,7 +49,6 @@ import com.google.common.collect.Sets; import com.google.re2j.Pattern; import com.googlecode.objectify.Key; import com.googlecode.objectify.Work; -import com.googlecode.objectify.annotation.Cache; import com.googlecode.objectify.annotation.Embed; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Id; @@ -85,7 +83,6 @@ import org.joda.money.CurrencyUnit; import org.joda.time.DateTime; /** Information about a registrar. */ -@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION) @ReportedOn @Entity public class Registrar extends ImmutableObject implements Buildable, Jsonifiable { diff --git a/java/google/registry/model/registrar/RegistrarContact.java b/java/google/registry/model/registrar/RegistrarContact.java index acc6c437f..eac42299c 100644 --- a/java/google/registry/model/registrar/RegistrarContact.java +++ b/java/google/registry/model/registrar/RegistrarContact.java @@ -19,7 +19,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.Iterables.transform; import static com.google.common.collect.Sets.difference; import static google.registry.model.ofy.ObjectifyService.ofy; -import static google.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION; import static google.registry.util.CollectionUtils.nullToEmptyImmutableSortedCopy; import static google.registry.util.ObjectifyUtils.OBJECTS_TO_KEYS; @@ -30,7 +29,6 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedSet; import com.googlecode.objectify.Key; import com.googlecode.objectify.VoidWork; -import com.googlecode.objectify.annotation.Cache; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Id; import com.googlecode.objectify.annotation.Index; @@ -52,7 +50,6 @@ import java.util.Set; * *MUST* also modify the persisted Registrar entity with {@link Registrar#contactsRequireSyncing} * set to true. */ -@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION) @ReportedOn @Entity public class RegistrarContact extends ImmutableObject implements Jsonifiable { diff --git a/java/google/registry/model/registry/Registry.java b/java/google/registry/model/registry/Registry.java index b11603de6..19dbf2337 100644 --- a/java/google/registry/model/registry/Registry.java +++ b/java/google/registry/model/registry/Registry.java @@ -21,7 +21,6 @@ import static com.google.common.base.Predicates.not; import static google.registry.config.RegistryConfig.getSingletonCacheRefreshDuration; import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; import static google.registry.model.ofy.ObjectifyService.ofy; -import static google.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION; import static google.registry.util.CollectionUtils.nullToEmptyImmutableCopy; import static google.registry.util.DateTimeUtils.END_OF_TIME; import static google.registry.util.DateTimeUtils.START_OF_TIME; @@ -46,7 +45,6 @@ import com.google.common.collect.Range; import com.google.common.net.InternetDomainName; import com.googlecode.objectify.Key; import com.googlecode.objectify.Work; -import com.googlecode.objectify.annotation.Cache; import com.googlecode.objectify.annotation.Embed; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Id; @@ -78,7 +76,6 @@ import org.joda.time.Duration; import org.joda.time.Interval; /** Persisted per-TLD configuration data. */ -@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION) @ReportedOn @Entity public class Registry extends ImmutableObject implements Buildable { @@ -245,12 +242,12 @@ public class Registry extends ImmutableObject implements Buildable { @Override public Optional load(final String tld) { // Enter a transactionless context briefly; we don't want to enroll every TLD in a - // transaction that might be wrapping this call, and memcached results are fine here + // transaction that might be wrapping this call. return Optional.fromNullable(ofy().doTransactionless(new Work() { @Override public Registry run() { return ofy() - .loadWithMemcache() + .load() .key(Key.create(getCrossTldKey(), Registry.class, tld)) .now(); }})); diff --git a/java/google/registry/model/registry/label/PremiumList.java b/java/google/registry/model/registry/label/PremiumList.java index 632603335..b756ae7cf 100644 --- a/java/google/registry/model/registry/label/PremiumList.java +++ b/java/google/registry/model/registry/label/PremiumList.java @@ -21,7 +21,6 @@ import static google.registry.config.RegistryConfig.getStaticPremiumListMaxCache import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; import static google.registry.model.ofy.ObjectifyService.allocateId; import static google.registry.model.ofy.ObjectifyService.ofy; -import static google.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION; import static java.util.concurrent.TimeUnit.MILLISECONDS; import com.google.common.annotations.VisibleForTesting; @@ -35,7 +34,6 @@ import com.google.common.hash.BloomFilter; import com.google.common.util.concurrent.UncheckedExecutionException; import com.googlecode.objectify.Key; import com.googlecode.objectify.Work; -import com.googlecode.objectify.annotation.Cache; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Id; import com.googlecode.objectify.annotation.Parent; @@ -59,7 +57,6 @@ import org.joda.time.Duration; */ @ReportedOn @Entity -@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION) public final class PremiumList extends BaseDomainLabelList { /** Stores the revision key for the set of currently used premium list entry entities. */ @@ -68,7 +65,6 @@ public final class PremiumList extends BaseDomainLabelList implements Buildable { diff --git a/java/google/registry/model/registry/label/ReservedList.java b/java/google/registry/model/registry/label/ReservedList.java index 29e9b43a4..fc7843d32 100644 --- a/java/google/registry/model/registry/label/ReservedList.java +++ b/java/google/registry/model/registry/label/ReservedList.java @@ -21,7 +21,6 @@ import static com.google.common.collect.Iterables.getOnlyElement; import static google.registry.config.RegistryConfig.getDomainLabelListCacheDuration; import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; import static google.registry.model.ofy.ObjectifyService.ofy; -import static google.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION; import static google.registry.model.registry.label.ReservationType.FULLY_BLOCKED; import static google.registry.model.registry.label.ReservationType.NAMESERVER_RESTRICTED; import static google.registry.model.registry.label.ReservationType.RESERVED_FOR_ANCHOR_TENANT; @@ -42,7 +41,6 @@ import com.google.common.collect.ImmutableSet; import com.google.common.net.InternetDomainName; import com.google.common.util.concurrent.UncheckedExecutionException; import com.googlecode.objectify.Key; -import com.googlecode.objectify.annotation.Cache; import com.googlecode.objectify.annotation.Embed; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Mapify; @@ -61,7 +59,6 @@ import org.joda.time.DateTime; * A reserved list entity, persisted to Datastore, that is used to check domain label reservations. */ @Entity -@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION) public final class ReservedList extends BaseDomainLabelList { diff --git a/java/google/registry/model/server/KmsSecret.java b/java/google/registry/model/server/KmsSecret.java index 7bdaf0f69..62dbe6cf4 100644 --- a/java/google/registry/model/server/KmsSecret.java +++ b/java/google/registry/model/server/KmsSecret.java @@ -15,10 +15,8 @@ package google.registry.model.server; import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; -import static google.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION; import com.googlecode.objectify.Key; -import com.googlecode.objectify.annotation.Cache; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Id; import com.googlecode.objectify.annotation.Parent; @@ -29,7 +27,6 @@ import google.registry.model.common.EntityGroupRoot; /** Pointer to the latest {@link KmsSecretRevision}. */ @Entity @ReportedOn -@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION) public class KmsSecret extends ImmutableObject { /** The unique name of this {@link KmsSecret}. */ diff --git a/java/google/registry/model/server/KmsSecretRevision.java b/java/google/registry/model/server/KmsSecretRevision.java index a0b4b3b14..a5da28cba 100644 --- a/java/google/registry/model/server/KmsSecretRevision.java +++ b/java/google/registry/model/server/KmsSecretRevision.java @@ -16,10 +16,8 @@ package google.registry.model.server; import static com.google.common.base.Preconditions.checkArgument; import static google.registry.model.common.EntityGroupRoot.getCrossTldKey; -import static google.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION; import com.googlecode.objectify.Key; -import com.googlecode.objectify.annotation.Cache; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Id; import com.googlecode.objectify.annotation.Parent; @@ -43,7 +41,6 @@ import google.registry.model.annotations.ReportedOn; */ @Entity @ReportedOn -@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION) public class KmsSecretRevision extends ImmutableObject { /** diff --git a/java/google/registry/model/server/ServerSecret.java b/java/google/registry/model/server/ServerSecret.java index 88f90cad3..847acf86f 100644 --- a/java/google/registry/model/server/ServerSecret.java +++ b/java/google/registry/model/server/ServerSecret.java @@ -15,7 +15,6 @@ package google.registry.model.server; import static google.registry.model.ofy.ObjectifyService.ofy; -import static google.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION; import com.google.common.annotations.VisibleForTesting; import com.google.common.cache.CacheBuilder; @@ -23,7 +22,6 @@ import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.primitives.Longs; import com.googlecode.objectify.Work; -import com.googlecode.objectify.annotation.Cache; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Unindex; import google.registry.model.annotations.NotBackedUp; @@ -35,7 +33,6 @@ import java.util.concurrent.ExecutionException; /** A secret number used for generating tokens (such as XSRF tokens). */ @Entity -@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION) @Unindex @NotBackedUp(reason = Reason.AUTO_GENERATED) public class ServerSecret extends CrossTldSingleton { diff --git a/java/google/registry/model/tmch/ClaimsListShard.java b/java/google/registry/model/tmch/ClaimsListShard.java index 529b1c6d6..62fbf7fba 100644 --- a/java/google/registry/model/tmch/ClaimsListShard.java +++ b/java/google/registry/model/tmch/ClaimsListShard.java @@ -20,7 +20,6 @@ import static com.google.common.base.Verify.verify; import static google.registry.model.CacheUtils.memoizeWithShortExpiration; import static google.registry.model.ofy.ObjectifyService.allocateId; import static google.registry.model.ofy.ObjectifyService.ofy; -import static google.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION; import static google.registry.util.DateTimeUtils.START_OF_TIME; import com.google.common.annotations.VisibleForTesting; @@ -30,7 +29,6 @@ import com.google.common.collect.ImmutableMap; import com.googlecode.objectify.Key; import com.googlecode.objectify.VoidWork; import com.googlecode.objectify.Work; -import com.googlecode.objectify.annotation.Cache; import com.googlecode.objectify.annotation.EmbedMap; import com.googlecode.objectify.annotation.Entity; import com.googlecode.objectify.annotation.Id; @@ -246,7 +244,6 @@ public class ClaimsListShard extends ImmutableObject { * that is live. */ @Entity - @Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION) @NotBackedUp(reason = Reason.EXTERNALLY_SOURCED) public static class ClaimsListSingleton extends CrossTldSingleton { Key activeRevision; diff --git a/java/google/registry/model/tmch/TmchCrl.java b/java/google/registry/model/tmch/TmchCrl.java index 4930c892f..65af297de 100644 --- a/java/google/registry/model/tmch/TmchCrl.java +++ b/java/google/registry/model/tmch/TmchCrl.java @@ -16,10 +16,8 @@ package google.registry.model.tmch; import static com.google.common.base.Preconditions.checkNotNull; import static google.registry.model.ofy.ObjectifyService.ofy; -import static google.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION; import com.googlecode.objectify.VoidWork; -import com.googlecode.objectify.annotation.Cache; import com.googlecode.objectify.annotation.Entity; import google.registry.model.annotations.NotBackedUp; import google.registry.model.annotations.NotBackedUp.Reason; @@ -30,7 +28,6 @@ import org.joda.time.DateTime; /** Datastore singleton for ICANN's TMCH CA certificate revocation list (CRL). */ @Entity -@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION) @Immutable @NotBackedUp(reason = Reason.EXTERNALLY_SOURCED) public final class TmchCrl extends CrossTldSingleton { diff --git a/java/google/registry/tools/server/KillAllEppResourcesAction.java b/java/google/registry/tools/server/KillAllEppResourcesAction.java index 01240c25e..36a08f0c7 100644 --- a/java/google/registry/tools/server/KillAllEppResourcesAction.java +++ b/java/google/registry/tools/server/KillAllEppResourcesAction.java @@ -22,7 +22,6 @@ import static google.registry.util.PipelineUtils.createJobPath; import com.google.appengine.tools.mapreduce.Mapper; import com.google.common.collect.ImmutableList; import com.googlecode.objectify.Key; -import com.googlecode.objectify.Work; import google.registry.config.RegistryEnvironment; import google.registry.mapreduce.MapreduceRunner; import google.registry.mapreduce.inputs.EppResourceInputs; @@ -92,14 +91,7 @@ public class KillAllEppResourcesAction implements Runnable { for (Key key : ofy().load().ancestor(resourceKey).keys()) { emitAndIncrementCounter(resourceKey, key); } - // Load in a transaction to make sure we don't get stale data (in case of host renames). - // TODO(b/27424173): A transaction is overkill. When we have memcache-skipping, use that. - EppResource resource = ofy().transactNewReadOnly( - new Work() { - @Override - public EppResource run() { - return ofy().load().key(eri.getKey()).now(); - }}); + EppResource resource = ofy().load().key(eri.getKey()).now(); // TODO(b/28247733): What about FKI's for renamed hosts? Key indexKey = resource instanceof DomainApplication ? DomainApplicationIndex.createKey((DomainApplication) resource) diff --git a/java/google/registry/ui/server/registrar/SessionUtils.java b/java/google/registry/ui/server/registrar/SessionUtils.java index 3052fb3b0..fc60bcbb7 100644 --- a/java/google/registry/ui/server/registrar/SessionUtils.java +++ b/java/google/registry/ui/server/registrar/SessionUtils.java @@ -61,7 +61,7 @@ public class SessionUtils { * user's GAIA ID is associated. The {@code clientId} of the first matching {@code Registrar} will * then be stored to the HTTP session. *
  • If it does exist, then we'll fetch the Registrar from Datastore to make sure access - * wasn't revoked. This should only cost one memcache read. + * wasn't revoked. * * *

    Note: You must ensure the user has logged in before calling this method, for example diff --git a/javatests/google/registry/flows/FlowTestCase.java b/javatests/google/registry/flows/FlowTestCase.java index e48a73f9c..0dea8af89 100644 --- a/javatests/google/registry/flows/FlowTestCase.java +++ b/javatests/google/registry/flows/FlowTestCase.java @@ -85,7 +85,6 @@ public abstract class FlowTestCase extends ShardableTestCase { @Rule public final AppEngineRule appEngine = AppEngineRule.builder() .withDatastore() - .withMemcache() .withTaskQueue() .build(); diff --git a/javatests/google/registry/flows/ResourceFlowTestCase.java b/javatests/google/registry/flows/ResourceFlowTestCase.java index 5fd659795..ca0424a46 100644 --- a/javatests/google/registry/flows/ResourceFlowTestCase.java +++ b/javatests/google/registry/flows/ResourceFlowTestCase.java @@ -69,8 +69,8 @@ public abstract class ResourceFlowTestCase exception) throws Exception { setEppInput("domain_create_sunrise_signed_mark_uppercase.xml"); diff --git a/javatests/google/registry/flows/domain/DomainApplicationInfoFlowTest.java b/javatests/google/registry/flows/domain/DomainApplicationInfoFlowTest.java index ca41a6ba7..90d13a039 100644 --- a/javatests/google/registry/flows/domain/DomainApplicationInfoFlowTest.java +++ b/javatests/google/registry/flows/domain/DomainApplicationInfoFlowTest.java @@ -23,7 +23,6 @@ import static google.registry.testing.DatastoreHelper.createTld; import static google.registry.testing.DatastoreHelper.persistActiveContact; import static google.registry.testing.DatastoreHelper.persistActiveHost; import static google.registry.testing.DatastoreHelper.persistResource; -import static google.registry.testing.MemcacheHelper.clearMemcache; import static google.registry.testing.TestDataHelper.loadFileWithSubstitutions; import static google.registry.util.DatastoreServiceUtils.KEY_TO_KIND_FUNCTION; @@ -332,9 +331,8 @@ public class DomainApplicationInfoFlowTest @Test public void testBatchLoadingOfReferences() throws Exception { persistTestEntities(HostsState.HOSTS_EXIST, MarksState.NO_MARKS_EXIST); - // Clear out memcache and session cache so that we count actual Datastore calls. + // Clear out the session cache so that we count actual Datastore calls. ofy().clearSessionCache(); - clearMemcache(); int numPreviousReads = RequestCapturingAsyncDatastoreService.getReads().size(); doSuccessfulTest("domain_info_sunrise_response.xml", HostsState.HOSTS_EXIST); // Get all of the keys loaded in the flow, with each distinct load() call as a list of keys. diff --git a/javatests/google/registry/flows/domain/DomainCreateFlowTest.java b/javatests/google/registry/flows/domain/DomainCreateFlowTest.java index 01d0f924d..7dec0406a 100644 --- a/javatests/google/registry/flows/domain/DomainCreateFlowTest.java +++ b/javatests/google/registry/flows/domain/DomainCreateFlowTest.java @@ -30,7 +30,6 @@ import static google.registry.testing.DatastoreHelper.deleteTld; import static google.registry.testing.DatastoreHelper.getHistoryEntries; import static google.registry.testing.DatastoreHelper.newContactResource; import static google.registry.testing.DatastoreHelper.newDomainApplication; -import static google.registry.testing.DatastoreHelper.newDomainResource; import static google.registry.testing.DatastoreHelper.newHostResource; import static google.registry.testing.DatastoreHelper.persistActiveContact; import static google.registry.testing.DatastoreHelper.persistActiveDomain; @@ -892,7 +891,7 @@ public class DomainCreateFlowTest extends ResourceFlowTestCase... keys) { - // Clear out the session cache. This is needed so that the calls to loadWithMemcache() below - // actually go to datastore and write to memcache instead of bottoming out at the session cache. - ofy().clearSessionCache(); - clearMemcache(); - // Load the entities we want to be in memcache. If an entity's type is not marked with @Cache it - // will be ignored. - ofy().loadWithMemcache().keys(keys).values(); - // Clear out the session cache again, since it now contains the newly loaded types. - ofy().clearSessionCache(); - } -}