Add a 1-hour expiration to all Objectify memcache uses

This protects us from the edge case of potentially stale
memcache data due to a DeadlineExceededExeption, or possibly
from MemcacheServiceException. If memcache gets stale and
misses a write that went to Datastore, it will catch up in
at most one hour.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=116174023
This commit is contained in:
Justine Tunney 2016-03-02 13:23:29 -08:00
parent 8a68acb84d
commit 689c673a7c
15 changed files with 40 additions and 17 deletions

View file

@ -16,6 +16,7 @@ package com.google.domain.registry.model.contact;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.domain.registry.model.EppResourceUtils.projectResourceOntoBuilderAtTime;
import static com.google.domain.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION;
import com.google.common.base.Predicates;
import com.google.common.collect.FluentIterable;
@ -60,7 +61,7 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
"lastTransferTime",
"authInfo",
"disclose" })
@Cache
@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION)
@Entity
@ExternalMessagingName("contact")
public class ContactResource extends EppResource implements ForeignKeyedEppResource {

View file

@ -14,6 +14,7 @@
package com.google.domain.registry.model.domain;
import static com.google.domain.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION;
import static com.google.domain.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
import com.google.common.collect.ImmutableList;
@ -50,7 +51,7 @@ import javax.xml.bind.annotation.XmlType;
"lastEppUpdateClientId",
"lastEppUpdateTime",
"authInfo"})
@Cache
@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION)
@EntitySubclass(index = true)
@ExternalMessagingName("application")
public class DomainApplication extends DomainBase {

View file

@ -17,6 +17,7 @@ package com.google.domain.registry.model.domain;
import static com.google.common.collect.Sets.intersection;
import static com.google.domain.registry.model.EppResourceUtils.projectResourceOntoBuilderAtTime;
import static com.google.domain.registry.model.EppResourceUtils.setAutomaticTransferSuccessProperties;
import static com.google.domain.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION;
import static com.google.domain.registry.util.CollectionUtils.difference;
import static com.google.domain.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
import static com.google.domain.registry.util.CollectionUtils.union;
@ -72,7 +73,7 @@ import javax.xml.bind.annotation.XmlType;
"registrationExpirationTime",
"lastTransferTime",
"authInfo"})
@Cache
@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION)
@EntitySubclass(index = true)
@ExternalMessagingName("domain")
public class DomainResource extends DomainBase implements ForeignKeyedEppResource {

View file

@ -17,6 +17,7 @@ package com.google.domain.registry.model.host;
import static com.google.common.collect.Sets.difference;
import static com.google.common.collect.Sets.union;
import static com.google.domain.registry.model.EppResourceUtils.projectResourceOntoBuilderAtTime;
import static com.google.domain.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION;
import static com.google.domain.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
import static com.google.domain.registry.util.DateTimeUtils.START_OF_TIME;
@ -65,7 +66,7 @@ import javax.xml.bind.annotation.XmlType;
"lastEppUpdateClientId",
"lastEppUpdateTime",
"lastTransferTime" })
@Cache
@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION)
@Entity
@ExternalMessagingName("host")
public class HostResource extends EppResource implements ForeignKeyedEppResource {

View file

@ -17,6 +17,7 @@ package com.google.domain.registry.model.index;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Strings.isNullOrEmpty;
import static com.google.domain.registry.model.ofy.ObjectifyService.ofy;
import static com.google.domain.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION;
import static com.google.domain.registry.util.CollectionUtils.isNullOrEmpty;
import static com.google.domain.registry.util.DateTimeUtils.latestOf;
@ -43,7 +44,7 @@ import javax.annotation.Nullable;
* necessary to query them explicitly from Datastore.
*/
@Entity
@Cache
@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION)
public class DomainApplicationIndex extends BackupGroupRoot {
@Id

View file

@ -16,6 +16,7 @@ package com.google.domain.registry.model.index;
import static com.google.common.collect.Maps.filterValues;
import static com.google.domain.registry.model.ofy.ObjectifyService.ofy;
import static com.google.domain.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION;
import static com.google.domain.registry.util.TypeUtils.instantiate;
import com.google.common.base.Predicate;
@ -46,17 +47,17 @@ import java.util.Map;
public abstract class ForeignKeyIndex<E extends EppResource> extends BackupGroupRoot {
/** The {@link ForeignKeyIndex} type for {@link ContactResource} entities. */
@Cache
@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION)
@Entity
public static class ForeignKeyContactIndex extends ForeignKeyIndex<ContactResource> {}
/** The {@link ForeignKeyIndex} type for {@link DomainResource} entities. */
@Cache
@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION)
@Entity
public static class ForeignKeyDomainIndex extends ForeignKeyIndex<DomainResource> {}
/** The {@link ForeignKeyIndex} type for {@link HostResource} entities. */
@Cache
@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION)
@Entity
public static class ForeignKeyHostIndex extends ForeignKeyIndex<HostResource> {}

View file

@ -68,6 +68,15 @@ public class Ofy {
private static final FormattingLogger logger = FormattingLogger.getLoggerForCallerClass();
/**
* Recommended memcache expiration time, which is one hour, specified in seconds.
* <p>
* 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();

View file

@ -26,6 +26,7 @@ import static com.google.common.base.Strings.nullToEmpty;
import static com.google.common.io.BaseEncoding.base64;
import static com.google.domain.registry.model.common.EntityGroupRoot.getCrossTldKey;
import static com.google.domain.registry.model.ofy.ObjectifyService.ofy;
import static com.google.domain.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION;
import static com.google.domain.registry.model.registry.Registries.assertTldExists;
import static com.google.domain.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
import static com.google.domain.registry.util.CollectionUtils.nullToEmptyImmutableSortedCopy;
@ -77,7 +78,7 @@ import java.util.Set;
import java.util.regex.Pattern;
/** Information about a registrar. */
@Cache
@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION)
@Entity
public class Registrar extends ImmutableObject implements Buildable, Jsonifiable {

View file

@ -19,6 +19,7 @@ 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 com.google.domain.registry.model.ofy.ObjectifyService.ofy;
import static com.google.domain.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION;
import static com.google.domain.registry.util.CollectionUtils.nullToEmptyImmutableSortedCopy;
import static com.google.domain.registry.util.ObjectifyUtils.OBJECTS_TO_KEYS;
@ -52,7 +53,7 @@ import java.util.Set;
* *MUST* also modify the persisted Registrar entity with {@link Registrar#contactsRequireSyncing}
* set to true.
*/
@Cache
@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION)
@Entity
public class RegistrarContact extends ImmutableObject implements Jsonifiable {

View file

@ -20,6 +20,7 @@ import static com.google.common.base.Predicates.equalTo;
import static com.google.common.base.Predicates.not;
import static com.google.domain.registry.model.common.EntityGroupRoot.getCrossTldKey;
import static com.google.domain.registry.model.ofy.ObjectifyService.ofy;
import static com.google.domain.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION;
import static com.google.domain.registry.model.registry.label.PremiumList.getPremiumPrice;
import static com.google.domain.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
import static com.google.domain.registry.util.DateTimeUtils.END_OF_TIME;
@ -68,7 +69,7 @@ import org.joda.time.Duration;
import java.util.Set;
/** Persisted per-TLD configuration data. */
@Cache
@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION)
@Entity
public class Registry extends BackupGroupRoot implements Buildable {

View file

@ -22,6 +22,7 @@ import static com.google.common.collect.Iterables.partition;
import static com.google.domain.registry.model.common.EntityGroupRoot.getCrossTldKey;
import static com.google.domain.registry.model.ofy.ObjectifyService.allocateId;
import static com.google.domain.registry.model.ofy.ObjectifyService.ofy;
import static com.google.domain.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION;
import static com.google.domain.registry.util.CollectionUtils.nullToEmpty;
import static com.google.domain.registry.util.CollectionUtils.nullToEmptyImmutableCopy;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
@ -68,7 +69,7 @@ import javax.annotation.Nullable;
* A premium list entity, persisted to Datastore, that is used to check domain label prices.
*/
@Entity
@Cache
@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION)
public final class PremiumList extends BaseDomainLabelList<Money, PremiumList.PremiumListEntry> {
/** The number of premium list entry entities that are created and deleted per batch. */
@ -196,7 +197,7 @@ public final class PremiumList extends BaseDomainLabelList<Money, PremiumList.Pr
* single label on a given TLD.
*/
@Entity
@Cache
@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION)
public static class PremiumListEntry extends DomainLabelEntry<Money, PremiumListEntry>
implements Buildable {

View file

@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.domain.registry.model.common.EntityGroupRoot.getCrossTldKey;
import static com.google.domain.registry.model.ofy.ObjectifyService.ofy;
import static com.google.domain.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION;
import static com.google.domain.registry.model.registry.label.ReservationType.FULLY_BLOCKED;
import static com.google.domain.registry.model.registry.label.ReservationType.RESERVED_FOR_ANCHOR_TENANT;
import static com.google.domain.registry.model.registry.label.ReservationType.UNRESERVED;
@ -55,7 +56,7 @@ import javax.annotation.Nullable;
* A reserved list entity, persisted to Datastore, that is used to check domain label reservations.
*/
@Entity
@Cache
@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION)
public final class ReservedList
extends BaseDomainLabelList<ReservationType, ReservedList.ReservedListEntry> {

View file

@ -15,6 +15,7 @@
package com.google.domain.registry.model.server;
import static com.google.domain.registry.model.ofy.ObjectifyService.ofy;
import static com.google.domain.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION;
import com.google.domain.registry.model.annotations.NotBackedUp;
import com.google.domain.registry.model.annotations.NotBackedUp.Reason;
@ -29,7 +30,7 @@ import java.util.UUID;
/** A secret number used for generating tokens (such as XSRF tokens). */
@Entity
@Cache
@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION)
@Unindex
@NotBackedUp(reason = Reason.AUTO_GENERATED)
public class ServerSecret extends CrossTldSingleton {

View file

@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Verify.verify;
import static com.google.domain.registry.model.ofy.ObjectifyService.allocateId;
import static com.google.domain.registry.model.ofy.ObjectifyService.ofy;
import static com.google.domain.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION;
import static com.google.domain.registry.util.CacheUtils.memoizeWithShortExpiration;
import static com.google.domain.registry.util.DateTimeUtils.START_OF_TIME;
@ -245,7 +246,7 @@ public class ClaimsListShard extends ImmutableObject {
* that is live.
*/
@Entity
@Cache
@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION)
@NotBackedUp(reason = Reason.EXTERNALLY_SOURCED)
public static class ClaimsListSingleton extends CrossTldSingleton {
Key<ClaimsListRevision> activeRevision;

View file

@ -16,6 +16,7 @@ package com.google.domain.registry.model.tmch;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.domain.registry.model.ofy.ObjectifyService.ofy;
import static com.google.domain.registry.model.ofy.Ofy.RECOMMENDED_MEMCACHE_EXPIRATION;
import com.google.domain.registry.model.annotations.NotBackedUp;
import com.google.domain.registry.model.annotations.NotBackedUp.Reason;
@ -32,7 +33,7 @@ import javax.annotation.concurrent.Immutable;
/** Datastore singleton for ICANN's TMCH CA certificate revocation list (CRL). */
@Entity
@Cache
@Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION)
@Immutable
@NotBackedUp(reason = Reason.EXTERNALLY_SOURCED)
public final class TmchCrl extends CrossTldSingleton {