Skip to content

Commit eba57e1

Browse files
authored
perf: avoid redundant work on informer event paths (#3545)
- Mappers#fromMetadata resolved the primary GroupVersionKind on every secondary event, although it only depends on the primary type. Hoist it out of the lambda and compare the encoded string before falling back to parsing the annotation value. - Mappers.SecondaryToPrimaryFromDefaultAnnotation built a whole new mapper on every invocation; hold a single delegate instead. The primaryResourceType field becomes unused and is dropped. - InformerEventSource#start walked the entire informer cache to seed the primary-to-secondary index even when that index is the no-op implementation (i.e. whenever a primaryToSecondaryMapper is configured), which is pure startup latency proportional to the number of cached secondaries. - ExternalResourceCachingEventSource#getSecondaryResources looked the primary up in the cache a second time although the value was already in a local. - PerResourcePollingEventSource#getAndCacheResource derived the same ResourceID twice in adjacent statements.
1 parent 9010df1 commit eba57e1

4 files changed

Lines changed: 15 additions & 10 deletions

File tree

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/ExternalResourceCachingEventSource.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ public Set<R> getSecondaryResources(ResourceID primaryID) {
242242
if (cachedValues == null) {
243243
return Collections.emptySet();
244244
} else {
245-
return new HashSet<>(cache.get(primaryID).values());
245+
return new HashSet<>(cachedValues.values());
246246
}
247247
}
248248

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/InformerEventSource.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,9 @@ public synchronized void start() {
177177
super.start();
178178
// this makes sure that on first reconciliation all resources are
179179
// present on the index
180-
manager().list().forEach(r -> primaryToSecondaryIndex.onAddOrUpdate(r, null));
180+
if (useSecondaryToPrimaryIndex()) {
181+
manager().list().forEach(r -> primaryToSecondaryIndex.onAddOrUpdate(r, null));
182+
}
181183
}
182184

183185
@SuppressWarnings("unchecked")

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/informer/Mappers.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ private static <T extends HasMetadata> SecondaryToPrimaryMapper<T> fromMetadata(
124124
String typeKey,
125125
Class<? extends HasMetadata> primaryResourceType,
126126
boolean isLabel) {
127+
final var expectedGvk = GroupVersionKind.gvkFor(primaryResourceType);
128+
final var expectedGvkString = expectedGvk.toGVKString();
127129
return resource -> {
128130
final var metadata = resource.getMetadata();
129131
if (metadata == null) {
@@ -143,8 +145,8 @@ private static <T extends HasMetadata> SecondaryToPrimaryMapper<T> fromMetadata(
143145
String gvkSimple = map.get(typeKey);
144146

145147
if (gvkSimple != null
146-
&& !GroupVersionKind.fromString(gvkSimple)
147-
.equals(GroupVersionKind.gvkFor(primaryResourceType))) {
148+
&& !expectedGvkString.equals(gvkSimple)
149+
&& !GroupVersionKind.fromString(gvkSimple).equals(expectedGvk)) {
148150
return Set.of();
149151
}
150152

@@ -183,24 +185,24 @@ SecondaryToPrimaryMapper<T> fromOwnerType(Class<OWNER> clazz) {
183185
}
184186
return owners.stream()
185187
.filter(it -> kind.equals(it.getKind()))
186-
.map(it -> new ResourceID(it.getName(), resource.getMetadata().getNamespace()))
188+
.map(it -> ResourceID.fromOwnerReference(resource, it, false))
187189
.collect(Collectors.toSet());
188190
};
189191
}
190192

191193
public static class SecondaryToPrimaryFromDefaultAnnotation
192194
implements SecondaryToPrimaryMapper<HasMetadata> {
193195

194-
private final Class<? extends HasMetadata> primaryResourceType;
196+
private final SecondaryToPrimaryMapper<HasMetadata> delegate;
195197

196198
public SecondaryToPrimaryFromDefaultAnnotation(
197199
Class<? extends HasMetadata> primaryResourceType) {
198-
this.primaryResourceType = primaryResourceType;
200+
this.delegate = Mappers.fromDefaultAnnotations(primaryResourceType);
199201
}
200202

201203
@Override
202204
public Set<ResourceID> toPrimaryResourceIDs(HasMetadata resource) {
203-
return Mappers.fromDefaultAnnotations(primaryResourceType).toPrimaryResourceIDs(resource);
205+
return delegate.toPrimaryResourceIDs(resource);
204206
}
205207
}
206208
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/source/polling/PerResourcePollingEventSource.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,9 @@ public PerResourcePollingEventSource(
7676

7777
private Set<R> getAndCacheResource(P primary, boolean fromGetter) {
7878
var values = resourceFetcher.fetchResources(primary);
79-
handleResources(ResourceID.fromResource(primary), values, !fromGetter);
80-
fetchedForPrimaries.add(ResourceID.fromResource(primary));
79+
var primaryID = ResourceID.fromResource(primary);
80+
handleResources(primaryID, values, !fromGetter);
81+
fetchedForPrimaries.add(primaryID);
8182
return values;
8283
}
8384

0 commit comments

Comments
 (0)