diff --git a/java/com/google/domain/registry/model/contact/ContactResource.java b/java/com/google/domain/registry/model/contact/ContactResource.java index 36337d09d..830af2a0d 100644 --- a/java/com/google/domain/registry/model/contact/ContactResource.java +++ b/java/com/google/domain/registry/model/contact/ContactResource.java @@ -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 { diff --git a/java/com/google/domain/registry/model/domain/DomainApplication.java b/java/com/google/domain/registry/model/domain/DomainApplication.java index a39704a44..03a58d2a1 100644 --- a/java/com/google/domain/registry/model/domain/DomainApplication.java +++ b/java/com/google/domain/registry/model/domain/DomainApplication.java @@ -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 { diff --git a/java/com/google/domain/registry/model/domain/DomainResource.java b/java/com/google/domain/registry/model/domain/DomainResource.java index d325b83f0..e47867821 100644 --- a/java/com/google/domain/registry/model/domain/DomainResource.java +++ b/java/com/google/domain/registry/model/domain/DomainResource.java @@ -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 { diff --git a/java/com/google/domain/registry/model/host/HostResource.java b/java/com/google/domain/registry/model/host/HostResource.java index 7b59efcd3..f2d4c8539 100644 --- a/java/com/google/domain/registry/model/host/HostResource.java +++ b/java/com/google/domain/registry/model/host/HostResource.java @@ -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 { diff --git a/java/com/google/domain/registry/model/index/DomainApplicationIndex.java b/java/com/google/domain/registry/model/index/DomainApplicationIndex.java index 4ea83c2a9..fecffbc80 100644 --- a/java/com/google/domain/registry/model/index/DomainApplicationIndex.java +++ b/java/com/google/domain/registry/model/index/DomainApplicationIndex.java @@ -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 diff --git a/java/com/google/domain/registry/model/index/ForeignKeyIndex.java b/java/com/google/domain/registry/model/index/ForeignKeyIndex.java index 6ba1fe1f6..2c67e2e3c 100644 --- a/java/com/google/domain/registry/model/index/ForeignKeyIndex.java +++ b/java/com/google/domain/registry/model/index/ForeignKeyIndex.java @@ -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 extends BackupGroupRoot { /** The {@link ForeignKeyIndex} type for {@link ContactResource} entities. */ - @Cache + @Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION) @Entity public static class ForeignKeyContactIndex extends ForeignKeyIndex {} /** The {@link ForeignKeyIndex} type for {@link DomainResource} entities. */ - @Cache + @Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION) @Entity public static class ForeignKeyDomainIndex extends ForeignKeyIndex {} /** The {@link ForeignKeyIndex} type for {@link HostResource} entities. */ - @Cache + @Cache(expirationSeconds = RECOMMENDED_MEMCACHE_EXPIRATION) @Entity public static class ForeignKeyHostIndex extends ForeignKeyIndex {} diff --git a/java/com/google/domain/registry/model/ofy/Ofy.java b/java/com/google/domain/registry/model/ofy/Ofy.java index 4253d5af1..34c8b095b 100644 --- a/java/com/google/domain/registry/model/ofy/Ofy.java +++ b/java/com/google/domain/registry/model/ofy/Ofy.java @@ -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. + *

+ * 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(); diff --git a/java/com/google/domain/registry/model/registrar/Registrar.java b/java/com/google/domain/registry/model/registrar/Registrar.java index 5b3b218a7..8809c2191 100644 --- a/java/com/google/domain/registry/model/registrar/Registrar.java +++ b/java/com/google/domain/registry/model/registrar/Registrar.java @@ -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 { diff --git a/java/com/google/domain/registry/model/registrar/RegistrarContact.java b/java/com/google/domain/registry/model/registrar/RegistrarContact.java index 829a8ce9b..e8056a0c9 100644 --- a/java/com/google/domain/registry/model/registrar/RegistrarContact.java +++ b/java/com/google/domain/registry/model/registrar/RegistrarContact.java @@ -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 { diff --git a/java/com/google/domain/registry/model/registry/Registry.java b/java/com/google/domain/registry/model/registry/Registry.java index bfcd937d5..a63f39ba7 100644 --- a/java/com/google/domain/registry/model/registry/Registry.java +++ b/java/com/google/domain/registry/model/registry/Registry.java @@ -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 { diff --git a/java/com/google/domain/registry/model/registry/label/PremiumList.java b/java/com/google/domain/registry/model/registry/label/PremiumList.java index 312a269aa..6cadb17ed 100644 --- a/java/com/google/domain/registry/model/registry/label/PremiumList.java +++ b/java/com/google/domain/registry/model/registry/label/PremiumList.java @@ -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 { /** The number of premium list entry entities that are created and deleted per batch. */ @@ -196,7 +197,7 @@ public final class PremiumList extends BaseDomainLabelList implements Buildable { diff --git a/java/com/google/domain/registry/model/registry/label/ReservedList.java b/java/com/google/domain/registry/model/registry/label/ReservedList.java index af60e4789..50c7bf78d 100644 --- a/java/com/google/domain/registry/model/registry/label/ReservedList.java +++ b/java/com/google/domain/registry/model/registry/label/ReservedList.java @@ -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 { diff --git a/java/com/google/domain/registry/model/server/ServerSecret.java b/java/com/google/domain/registry/model/server/ServerSecret.java index d76a21f96..c8b271bb4 100644 --- a/java/com/google/domain/registry/model/server/ServerSecret.java +++ b/java/com/google/domain/registry/model/server/ServerSecret.java @@ -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 { diff --git a/java/com/google/domain/registry/model/tmch/ClaimsListShard.java b/java/com/google/domain/registry/model/tmch/ClaimsListShard.java index 903313646..83db49e55 100644 --- a/java/com/google/domain/registry/model/tmch/ClaimsListShard.java +++ b/java/com/google/domain/registry/model/tmch/ClaimsListShard.java @@ -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 activeRevision; diff --git a/java/com/google/domain/registry/model/tmch/TmchCrl.java b/java/com/google/domain/registry/model/tmch/TmchCrl.java index 054059eb8..4784dcfb0 100644 --- a/java/com/google/domain/registry/model/tmch/TmchCrl.java +++ b/java/com/google/domain/registry/model/tmch/TmchCrl.java @@ -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 {