Skip to content

Commit 79623cb

Browse files
committed
Update gauge collection based on app update state
1 parent ea80eb1 commit 79623cb

File tree

4 files changed

+80
-79
lines changed

4 files changed

+80
-79
lines changed

firebase-perf/src/main/java/com/google/firebase/perf/session/SessionManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ private void startOrStopCollectingGauges(ApplicationProcessState appState) {
165165
perfSession, "Session is not ready while trying to startOrStopCollectingGauges");
166166

167167
if (perfSession.isGaugeAndEventCollectionEnabled()) {
168-
gaugeManager.startCollectingGauges(perfSession, appState);
168+
gaugeManager.startCollectingGauges(perfSession);
169169
} else {
170170
gaugeManager.stopCollectingGauges();
171171
}

firebase-perf/src/main/java/com/google/firebase/perf/session/gauges/GaugeManager.java

Lines changed: 32 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import androidx.annotation.Nullable;
2121
import androidx.annotation.VisibleForTesting;
2222
import com.google.firebase.components.Lazy;
23+
import com.google.firebase.perf.application.AppStateUpdateHandler;
2324
import com.google.firebase.perf.config.ConfigResolver;
2425
import com.google.firebase.perf.logging.AndroidLogger;
2526
import com.google.firebase.perf.session.PerfSession;
@@ -31,7 +32,6 @@
3132
import com.google.firebase.perf.v1.GaugeMetadata;
3233
import com.google.firebase.perf.v1.GaugeMetric;
3334
import java.util.concurrent.Executors;
34-
import java.util.concurrent.RejectedExecutionException;
3535
import java.util.concurrent.ScheduledExecutorService;
3636
import java.util.concurrent.ScheduledFuture;
3737
import java.util.concurrent.TimeUnit;
@@ -41,7 +41,7 @@
4141
* information and logging it to the Transport.
4242
*/
4343
@Keep // Needed because of b/117526359.
44-
public class GaugeManager {
44+
public class GaugeManager extends AppStateUpdateHandler {
4545

4646
private static final AndroidLogger logger = AndroidLogger.getInstance();
4747
private static final GaugeManager instance = new GaugeManager();
@@ -59,8 +59,8 @@ public class GaugeManager {
5959
private final TransportManager transportManager;
6060

6161
@Nullable private GaugeMetadataManager gaugeMetadataManager;
62-
@Nullable private ScheduledFuture gaugeManagerDataCollectionJob = null;
63-
@Nullable private String sessionId = null;
62+
@Nullable private ScheduledFuture<?> gaugeManagerDataCollectionJob = null;
63+
@Nullable private PerfSession session = null;
6464
private ApplicationProcessState applicationProcessState =
6565
ApplicationProcessState.APPLICATION_PROCESS_STATE_UNKNOWN;
6666

@@ -91,13 +91,27 @@ private GaugeManager() {
9191
this.gaugeMetadataManager = gaugeMetadataManager;
9292
this.cpuGaugeCollector = cpuGaugeCollector;
9393
this.memoryGaugeCollector = memoryGaugeCollector;
94+
registerForAppState();
9495
}
9596

9697
/** Initializes GaugeMetadataManager which requires application context. */
9798
public void initializeGaugeMetadataManager(Context appContext) {
9899
this.gaugeMetadataManager = new GaugeMetadataManager(appContext);
99100
}
100101

102+
@Override
103+
public void onUpdateAppState(ApplicationProcessState applicationProcessState) {
104+
this.applicationProcessState = applicationProcessState;
105+
106+
if (session == null) {
107+
// If the session is null, it means there's no gauges being collected.
108+
return;
109+
}
110+
111+
stopCollectingGauges();
112+
startCollectingGauges(this.applicationProcessState, session.getTimer());
113+
}
114+
101115
/** Returns the singleton instance of this class. */
102116
public static synchronized GaugeManager getInstance() {
103117
return instance;
@@ -112,47 +126,22 @@ public static synchronized GaugeManager getInstance() {
112126
* will then be associated with the same or new sessionId and applicationProcessState.
113127
*
114128
* @param session The {@link PerfSession} to which the collected gauges will be associated with.
115-
* @param applicationProcessState The {@link ApplicationProcessState} the collected GaugeMetrics
116-
* will be associated with.
117129
* @note: This method is NOT thread safe - {@link this.startCollectingGauges()} and {@link
118-
* this.stopCollectingGauges()} should always be called from the same thread.
130+
* this.stopCollectingGauges()} should always be called from the same thread.
119131
*/
120-
public void startCollectingGauges(
121-
PerfSession session, ApplicationProcessState applicationProcessState) {
122-
if (this.sessionId != null) {
132+
public void startCollectingGauges(PerfSession session) {
133+
if (this.session != null) {
123134
stopCollectingGauges();
124135
}
125136

126-
long collectionFrequency = startCollectingGauges(applicationProcessState, session.getTimer());
137+
long collectionFrequency =
138+
startCollectingGauges(this.applicationProcessState, session.getTimer());
127139
if (collectionFrequency == INVALID_GAUGE_COLLECTION_FREQUENCY) {
128140
logger.warn("Invalid gauge collection frequency. Unable to start collecting Gauges.");
129141
return;
130142
}
131143

132-
this.sessionId = session.sessionId();
133-
this.applicationProcessState = applicationProcessState;
134-
135-
// This is needed, otherwise the Runnable might use a stale value.
136-
final String sessionIdForScheduledTask = sessionId;
137-
final ApplicationProcessState applicationProcessStateForScheduledTask = applicationProcessState;
138-
139-
// TODO(b/394127311): Switch to using AQS.
140-
try {
141-
gaugeManagerDataCollectionJob =
142-
gaugeManagerExecutor
143-
.get()
144-
.scheduleWithFixedDelay(
145-
() -> {
146-
syncFlush(sessionIdForScheduledTask, applicationProcessStateForScheduledTask);
147-
},
148-
/* initialDelay= */ collectionFrequency
149-
* APPROX_NUMBER_OF_DATA_POINTS_PER_GAUGE_METRIC,
150-
/* period= */ collectionFrequency * APPROX_NUMBER_OF_DATA_POINTS_PER_GAUGE_METRIC,
151-
TimeUnit.MILLISECONDS);
152-
153-
} catch (RejectedExecutionException e) {
154-
logger.warn("Unable to start collecting Gauges: " + e.getMessage());
155-
}
144+
this.session = session;
156145
}
157146

158147
/**
@@ -190,12 +179,12 @@ private long startCollectingGauges(ApplicationProcessState appState, Timer refer
190179
* this.stopCollectingGauges()} should always be called from the same thread.
191180
*/
192181
public void stopCollectingGauges() {
193-
if (this.sessionId == null) {
182+
if (session == null) {
194183
return;
195184
}
196185

197186
// This is needed, otherwise the Runnable might use a stale value.
198-
final String sessionIdForScheduledTask = sessionId;
187+
final String sessionIdForScheduledTask = session.sessionId();
199188
final ApplicationProcessState applicationProcessStateForScheduledTask = applicationProcessState;
200189

201190
cpuGaugeCollector.get().stopCollecting();
@@ -205,10 +194,9 @@ public void stopCollectingGauges() {
205194
gaugeManagerDataCollectionJob.cancel(false);
206195
}
207196

208-
// TODO(b/394127311): Switch to using AQS.
209197
// Flush any data that was collected for this session one last time.
210198
@SuppressWarnings("FutureReturnValueIgnored")
211-
ScheduledFuture unusedFuture =
199+
ScheduledFuture<?> unusedFuture =
212200
gaugeManagerExecutor
213201
.get()
214202
.schedule(
@@ -218,7 +206,7 @@ public void stopCollectingGauges() {
218206
TIME_TO_WAIT_BEFORE_FLUSHING_GAUGES_QUEUE_MS,
219207
TimeUnit.MILLISECONDS);
220208

221-
this.sessionId = null;
209+
this.session = null;
222210
this.applicationProcessState = ApplicationProcessState.APPLICATION_PROCESS_STATE_UNKNOWN;
223211
}
224212

@@ -227,7 +215,7 @@ public void stopCollectingGauges() {
227215
* proto and logs it to transport.
228216
*
229217
* @param sessionId The sessionId to which the collected GaugeMetrics should be associated with.
230-
* @param appState The app state for which these gauges are collected.
218+
* @param appState The app state for which these gauges are attributed to.
231219
*/
232220
private void syncFlush(String sessionId, ApplicationProcessState appState) {
233221
GaugeMetric.Builder gaugeMetricBuilder = GaugeMetric.newBuilder();
@@ -244,7 +232,6 @@ private void syncFlush(String sessionId, ApplicationProcessState appState) {
244232
}
245233

246234
// Adding Session ID info.
247-
// TODO(b/394127311): Switch to using AQS.
248235
gaugeMetricBuilder.setSessionId(sessionId);
249236

250237
transportManager.log(gaugeMetricBuilder.build(), appState);
@@ -253,16 +240,16 @@ private void syncFlush(String sessionId, ApplicationProcessState appState) {
253240
/**
254241
* Log the Gauge Metadata information to the transport.
255242
*
256-
* @param aqsSessionId The {@link PerfSession#aqsSessionId()} ()} to which the collected Gauge Metrics
243+
* @param sessionId The {@link PerfSession#sessionId()} ()} to which the collected Gauge Metrics
257244
* should be associated with.
258245
* @param appState The {@link ApplicationProcessState} for which these gauges are collected.
259246
* @return true if GaugeMetadata was logged, false otherwise.
260247
*/
261-
public boolean logGaugeMetadata(String aqsSessionId, ApplicationProcessState appState) {
248+
public boolean logGaugeMetadata(String sessionId, ApplicationProcessState appState) {
262249
if (gaugeMetadataManager != null) {
263250
GaugeMetric gaugeMetric =
264251
GaugeMetric.newBuilder()
265-
.setSessionId(aqsSessionId)
252+
.setSessionId(sessionId)
266253
.setGaugeMetadata(getGaugeMetadata())
267254
.build();
268255
transportManager.log(gaugeMetric, appState);

firebase-perf/src/test/java/com/google/firebase/perf/session/SessionManagerTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,7 @@ public void testUpdatePerfSessionStartsCollectingGaugesIfSessionIsVerbose() {
144144
testSessionManager.setApplicationContext(mockApplicationContext);
145145

146146
verify(mockGaugeManager, times(1)).initializeGaugeMetadataManager(mockApplicationContext);
147-
verify(mockGaugeManager, times(1))
148-
.startCollectingGauges(newSession, ApplicationProcessState.FOREGROUND);
147+
verify(mockGaugeManager, times(1)).startCollectingGauges(newSession);
149148
}
150149

151150
@Test

0 commit comments

Comments
 (0)