mirror of
https://github.com/google/nomulus
synced 2026-08-02 05:16:08 +00:00
Speed up updating of premium lists (#1482)
* Speed up updating of premium lists There are two parts to this: 1. Don't load the premium entries in the command prompt (this isn't necessary and we didn't display that information anyway). 2. Set a proper batch size (rather than just 1) when saving all the premium entries. This means that we generate only one INSERT statement rather than N statements.
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
|
||||
package google.registry.model.tld.label;
|
||||
|
||||
import static com.google.common.collect.ImmutableMap.toImmutableMap;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static com.google.common.truth.Truth8.assertThat;
|
||||
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
|
||||
@@ -24,14 +25,18 @@ import static org.joda.money.CurrencyUnit.USD;
|
||||
import static org.joda.time.Duration.standardDays;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import com.google.common.base.Stopwatch;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.flogger.FluentLogger;
|
||||
import google.registry.persistence.transaction.TransactionManagerUtil;
|
||||
import google.registry.testing.AppEngineExtension;
|
||||
import google.registry.testing.FakeClock;
|
||||
import google.registry.testing.TestCacheExtension;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.IntStream;
|
||||
import org.joda.money.CurrencyUnit;
|
||||
import org.joda.money.Money;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -41,6 +46,8 @@ import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
/** Unit tests for {@link PremiumListDao}. */
|
||||
public class PremiumListDaoTest {
|
||||
|
||||
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
|
||||
|
||||
private final FakeClock fakeClock = new FakeClock();
|
||||
|
||||
@RegisterExtension
|
||||
@@ -260,6 +267,27 @@ public class PremiumListDaoTest {
|
||||
assertThat(PremiumListDao.premiumListCache.getIfPresent("testname")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSave_largeSize_savedQuickly() {
|
||||
Stopwatch stopwatch = Stopwatch.createStarted();
|
||||
ImmutableMap<String, BigDecimal> prices =
|
||||
IntStream.range(0, 20000).boxed().collect(toImmutableMap(String::valueOf, BigDecimal::new));
|
||||
PremiumList list =
|
||||
new PremiumList.Builder()
|
||||
.setName("testname")
|
||||
.setCurrency(USD)
|
||||
.setLabelsToPrices(prices)
|
||||
.setCreationTimestamp(fakeClock.nowUtc())
|
||||
.build();
|
||||
PremiumListDao.save(list);
|
||||
long duration = stopwatch.stop().elapsed(TimeUnit.MILLISECONDS);
|
||||
if (duration >= 6000) {
|
||||
// Don't fail directly since we can't rely on what sort of machines the test is running on
|
||||
logger.atSevere().log(
|
||||
"Expected premium list update to take 2-3 seconds but it took %d ms", duration);
|
||||
}
|
||||
}
|
||||
|
||||
private static Money moneyOf(CurrencyUnit unit, double amount) {
|
||||
return Money.of(unit, BigDecimal.valueOf(amount).setScale(unit.getDecimalPlaces()));
|
||||
}
|
||||
|
||||
@@ -60,7 +60,6 @@ import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Streams;
|
||||
import com.google.common.net.InetAddresses;
|
||||
import com.googlecode.objectify.Key;
|
||||
import google.registry.dns.writer.VoidDnsWriter;
|
||||
@@ -1264,7 +1263,7 @@ public class DatabaseHelper {
|
||||
|
||||
/** Returns the entire map of {@link PremiumEntry}s for the given {@link PremiumList}. */
|
||||
public static ImmutableMap<String, PremiumEntry> loadPremiumEntries(PremiumList premiumList) {
|
||||
return Streams.stream(PremiumListDao.loadAllPremiumEntries(premiumList.getName()))
|
||||
return PremiumListDao.loadAllPremiumEntries(premiumList.getName()).stream()
|
||||
.collect(toImmutableMap(PremiumEntry::getDomainLabel, Function.identity()));
|
||||
}
|
||||
|
||||
|
||||
@@ -14,17 +14,20 @@
|
||||
|
||||
package google.registry.tools;
|
||||
|
||||
import static com.google.common.collect.ImmutableList.toImmutableList;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static google.registry.model.ImmutableObjectSubject.immutableObjectCorrespondence;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.joda.money.CurrencyUnit.USD;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.io.Files;
|
||||
import google.registry.model.tld.Registry;
|
||||
import google.registry.model.tld.label.PremiumList;
|
||||
import google.registry.model.tld.label.PremiumList.PremiumEntry;
|
||||
import google.registry.model.tld.label.PremiumListDao;
|
||||
import java.io.File;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Optional;
|
||||
@@ -46,12 +49,10 @@ class UpdatePremiumListCommandTest<C extends UpdatePremiumListCommand>
|
||||
Optional<PremiumList> list = PremiumListDao.getLatestRevision(TLD_TEST);
|
||||
// ensure that no premium list is created before running the command
|
||||
assertThat(list.isPresent()).isTrue();
|
||||
// ensure that there's value in existing premium list;
|
||||
UpdatePremiumListCommand command = new UpdatePremiumListCommand();
|
||||
ImmutableSet<String> entries = command.getExistingPremiumEntry(list.get());
|
||||
assertThat(entries.size()).isEqualTo(1);
|
||||
// data from @beforeEach of CreateOrUpdatePremiumListCommandTestCase.java
|
||||
assertThat(entries.contains("doge,USD 9090.00")).isTrue();
|
||||
assertThat(PremiumListDao.loadPremiumEntries(list.get()))
|
||||
.comparingElementsUsing(immutableObjectCorrespondence("revisionId"))
|
||||
.containsExactly(PremiumEntry.create(0L, new BigDecimal("9090.00"), "doge"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -77,11 +78,9 @@ class UpdatePremiumListCommandTest<C extends UpdatePremiumListCommand>
|
||||
command.inputFile = Paths.get(tmpFile.getPath());
|
||||
runCommandForced("--name=" + TLD_TEST, "--input=" + command.inputFile);
|
||||
|
||||
ImmutableSet<String> entries =
|
||||
command.getExistingPremiumEntry(PremiumListDao.getLatestRevision(TLD_TEST).get());
|
||||
assertThat(entries.size()).isEqualTo(1);
|
||||
// verify that list is updated; cannot use only string since price is formatted;
|
||||
assertThat(entries.contains("eth,USD 9999.00")).isTrue();
|
||||
assertThat(PremiumListDao.loadAllPremiumEntries(TLD_TEST))
|
||||
.comparingElementsUsing(immutableObjectCorrespondence("revisionId"))
|
||||
.containsExactly(PremiumEntry.create(0L, new BigDecimal("9999.00"), "eth"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -98,11 +97,9 @@ class UpdatePremiumListCommandTest<C extends UpdatePremiumListCommand>
|
||||
command.inputFile = Paths.get(newPremiumFile.getPath());
|
||||
runCommandForced("--name=" + TLD_TEST, "--input=" + command.inputFile);
|
||||
|
||||
ImmutableSet<String> entries =
|
||||
command.getExistingPremiumEntry(PremiumListDao.getLatestRevision(TLD_TEST).get());
|
||||
assertThat(entries.size()).isEqualTo(1);
|
||||
// verify that list is updated; cannot use only string since price is formatted;
|
||||
assertThat(entries.contains("eth,USD 9999.00")).isTrue();
|
||||
assertThat(PremiumListDao.loadAllPremiumEntries(TLD_TEST))
|
||||
.comparingElementsUsing(immutableObjectCorrespondence("revisionId"))
|
||||
.containsExactly(PremiumEntry.create(0L, new BigDecimal("9999.00"), "eth"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -116,12 +113,11 @@ class UpdatePremiumListCommandTest<C extends UpdatePremiumListCommand>
|
||||
runCommandForced("--name=" + TLD_TEST, "--input=" + command.inputFile);
|
||||
|
||||
// assert all three lines from premiumTerms are added
|
||||
ImmutableSet<String> entries =
|
||||
command.getExistingPremiumEntry(PremiumListDao.getLatestRevision(TLD_TEST).get());
|
||||
assertThat(entries.size()).isEqualTo(3);
|
||||
assertThat(entries.contains("foo,USD 9000.00")).isTrue();
|
||||
assertThat(entries.contains("doge,USD 100.00")).isTrue();
|
||||
assertThat(entries.contains("elon,USD 2021.00")).isTrue();
|
||||
assertThat(
|
||||
PremiumListDao.loadAllPremiumEntries(TLD_TEST).stream()
|
||||
.map(Object::toString)
|
||||
.collect(toImmutableList()))
|
||||
.containsExactly("foo, 9000.00", "doge, 100.00", "elon, 2021.00");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user