Skip to content

Commit

Permalink
Allow OptionsChecksumCache to fail to prime itself, resulting in a …
Browse files Browse the repository at this point in the history
…`SerializationException`.

PiperOrigin-RevId: 565814705
Change-Id: Id4f43c31f2f51c8a871bbbbdfffc6e570404d710
  • Loading branch information
justinhorvitz authored and copybara-github committed Sep 16, 2023
1 parent d8d3593 commit 1cf392f
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -715,8 +715,10 @@ public Class<BuildOptions> getEncodedClass() {
@Override
public void serialize(
SerializationContext context, BuildOptions options, CodedOutputStream codedOut)
throws IOException {
context.getDependency(OptionsChecksumCache.class).prime(options);
throws SerializationException, IOException {
if (!context.getDependency(OptionsChecksumCache.class).prime(options)) {
throw new SerializationException("Failed to prime cache for " + options.checksum());
}
codedOut.writeStringNoTag(options.checksum());
}

Expand All @@ -740,15 +742,22 @@ public interface OptionsChecksumCache {

/**
* Called during deserialization to transform a checksum into a {@link BuildOptions} instance.
*
* <p>Returns {@code null} when the given checksum is unknown, in which case the codec throws
* {@link SerializationException}.
*/
@Nullable
BuildOptions getOptions(String checksum);

/**
* Notifies the cache that it may be necessary to deserialize the given options diff's checksum.
*
* <p>Called each time an {@link BuildOptions} instance is serialized.
*
* @return whether this cache was successfully primed, if {@code false} the codec will throw
* {@link SerializationException}
*/
void prime(BuildOptions options);
boolean prime(BuildOptions options);
}

/**
Expand All @@ -760,13 +769,15 @@ public static final class MapBackedChecksumCache implements OptionsChecksumCache
private final ConcurrentMap<String, BuildOptions> map = new ConcurrentHashMap<>();

@Override
@Nullable
public BuildOptions getOptions(String checksum) {
return map.get(checksum);
}

@Override
public void prime(BuildOptions options) {
public boolean prime(BuildOptions options) {
map.putIfAbsent(options.checksum(), options);
return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,29 @@ private static ImmutableList.Builder<Class<? extends FragmentOptions>> makeOptio
.add(CppOptions.class);
}

@Test
public void serialize_primeFails_throws() throws Exception {
OptionsChecksumCache failToPrimeCache =
new OptionsChecksumCache() {
@Override
public BuildOptions getOptions(String checksum) {
throw new UnsupportedOperationException();
}

@Override
public boolean prime(BuildOptions options) {
return false;
}
};
BuildOptions options = BuildOptions.of(BUILD_CONFIG_OPTIONS);
SerializationContext serializationContext =
new SerializationContext(
ImmutableClassToInstanceMap.of(OptionsChecksumCache.class, failToPrimeCache));

assertThrows(
SerializationException.class, () -> TestUtils.toBytes(serializationContext, options));
}

@Test
public void deserialize_unprimedCache_throws() throws Exception {
BuildOptions options = BuildOptions.of(BUILD_CONFIG_OPTIONS);
Expand Down Expand Up @@ -252,7 +275,7 @@ public void deserialize_primedCache_returnsPrimedInstance() throws Exception {

// Different checksum cache than the one used for serialization, but it has been primed.
OptionsChecksumCache checksumCache = new MapBackedChecksumCache();
checksumCache.prime(options);
assertThat(checksumCache.prime(options)).isTrue();
DeserializationContext deserializationContext =
new DeserializationContext(
ImmutableClassToInstanceMap.of(OptionsChecksumCache.class, checksumCache));
Expand Down

0 comments on commit 1cf392f

Please sign in to comment.