Make FlightRecorderApplicationStartup thread safe
Prior to this commit, in some cases application context startup steps could be created concurrently, which could cause issues with the current implementation tracking the parent/child relationship between steps. This commit ensures that the flight recorder implementation is using thread safe collection implementations for that. Fixes gh-26941
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,8 +16,9 @@
|
||||
|
||||
package org.springframework.core.metrics.jfr;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.springframework.core.metrics.ApplicationStartup;
|
||||
import org.springframework.core.metrics.StartupStep;
|
||||
@@ -37,24 +38,23 @@ import org.springframework.core.metrics.StartupStep;
|
||||
*/
|
||||
public class FlightRecorderApplicationStartup implements ApplicationStartup {
|
||||
|
||||
private long currentSequenceId;
|
||||
private final AtomicLong currentSequenceId = new AtomicLong(0);
|
||||
|
||||
private final Deque<Long> currentSteps;
|
||||
|
||||
|
||||
public FlightRecorderApplicationStartup() {
|
||||
this.currentSequenceId = 0;
|
||||
this.currentSteps = new ArrayDeque<>();
|
||||
this.currentSteps.offerFirst(0L);
|
||||
this.currentSteps = new ConcurrentLinkedDeque<>();
|
||||
this.currentSteps.offerFirst(this.currentSequenceId.get());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public StartupStep start(String name) {
|
||||
FlightRecorderStartupStep step = new FlightRecorderStartupStep(++this.currentSequenceId, name,
|
||||
this.currentSteps.getFirst(), committedStep -> this.currentSteps.removeFirst());
|
||||
this.currentSteps.offerFirst(this.currentSequenceId);
|
||||
return step;
|
||||
long sequenceId = this.currentSequenceId.incrementAndGet();
|
||||
this.currentSteps.offerFirst(sequenceId);
|
||||
return new FlightRecorderStartupStep(sequenceId, name,
|
||||
this.currentSteps.getFirst(), committedStep -> this.currentSteps.removeFirstOccurrence(sequenceId));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user