Skip to content

Commit 71992f9

Browse files
committed
Fix PolicyStepsRegistry's cachedSteps null handling (#84588)
1 parent c406dae commit 71992f9

File tree

3 files changed

+34
-9
lines changed

3 files changed

+34
-9
lines changed

docs/changelog/84588.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 84588
2+
summary: Fix `PolicyStepsRegistry's` `cachedSteps` null handling
3+
area: ILM+SLM
4+
type: bug
5+
issues: []

x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/PolicyStepsRegistry.java

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -305,14 +305,30 @@ private List<Step> parseStepsFromPhase(String policy, String currentPhase, Strin
305305
return phaseSteps;
306306
}
307307

308+
/**
309+
* Read-only internal helper for getStep that returns a non-null step if one is cached for the provided
310+
* IndexMetadata and StepKey, and null otherwise.
311+
*/
308312
@Nullable
309-
public Step getStep(final IndexMetadata indexMetadata, final Step.StepKey stepKey) {
313+
private Step getCachedStep(final IndexMetadata indexMetadata, final Step.StepKey stepKey) {
310314
final Tuple<IndexMetadata, Step> cachedStep = cachedSteps.get(indexMetadata.getIndex());
311315
// n.b. we're using instance equality here for the IndexMetadata rather than object equality because it's fast,
312316
// this means that we're erring on the side of cache misses (if the IndexMetadata changed in any way, it'll be
313317
// a new instance, so we'll miss-and-repopulate the cache for the index in question)
314-
if (cachedStep != null && cachedStep.v1() == indexMetadata && cachedStep.v2().getKey().equals(stepKey)) {
315-
return cachedStep.v2();
318+
if (cachedStep != null && cachedStep.v1() == indexMetadata) {
319+
assert cachedStep.v2() != null : "null steps should never be cached in the policy step registry";
320+
if (cachedStep.v2() != null && cachedStep.v2().getKey().equals(stepKey)) {
321+
return cachedStep.v2();
322+
}
323+
}
324+
return null;
325+
}
326+
327+
@Nullable
328+
public Step getStep(final IndexMetadata indexMetadata, final Step.StepKey stepKey) {
329+
final Step cachedStep = getCachedStep(indexMetadata, stepKey);
330+
if (cachedStep != null) {
331+
return cachedStep;
316332
}
317333

318334
if (ErrorStep.NAME.equals(stepKey.getName())) {
@@ -354,7 +370,12 @@ public Step getStep(final IndexMetadata indexMetadata, final Step.StepKey stepKe
354370

355371
// Return the step that matches the given stepKey or else null if we couldn't find it
356372
final Step s = phaseSteps.stream().filter(step -> step.getKey().equals(stepKey)).findFirst().orElse(null);
357-
cachedSteps.put(indexMetadata.getIndex(), Tuple.tuple(indexMetadata, s));
373+
if (s != null) {
374+
cachedSteps.put(indexMetadata.getIndex(), Tuple.tuple(indexMetadata, s));
375+
// assert that the cache works as expected -- that is, if we put something into the cache,
376+
// we should get back the same thing if we were to invoke getStep again with the same arguments
377+
assert s == getCachedStep(indexMetadata, stepKey) : "policy step registry cache failed sanity check";
378+
}
358379
return s;
359380
}
360381

x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/PolicyStepsRegistryTests.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -191,11 +191,10 @@ public void testGetStepUnknownStepKey() {
191191
SortedMap<String, LifecyclePolicyMetadata> metas = new TreeMap<>();
192192
metas.put("policy", policyMetadata);
193193
PolicyStepsRegistry registry = new PolicyStepsRegistry(metas, null, null, REGISTRY, client, null);
194-
Step actualStep = registry.getStep(
195-
indexMetadata,
196-
new Step.StepKey(step.getKey().getPhase(), step.getKey().getAction(), step.getKey().getName() + "-bad")
197-
);
198-
assertNull(actualStep);
194+
Step.StepKey badStepKey = new Step.StepKey(step.getKey().getPhase(), step.getKey().getAction(), step.getKey().getName() + "-bad");
195+
assertNull(registry.getStep(indexMetadata, badStepKey));
196+
// repeat the test to make sure that nulls don't poison the registry's cache
197+
assertNull(registry.getStep(indexMetadata, badStepKey));
199198
}
200199

201200
public void testUpdateFromNothingToSomethingToNothing() throws Exception {

0 commit comments

Comments
 (0)