Skip to content

Commit 0d9ba90

Browse files
committed
init
1 parent 8fe1383 commit 0d9ba90

File tree

3 files changed

+94
-31
lines changed

3 files changed

+94
-31
lines changed

firebase-perf/src/main/java/com/google/firebase/perf/FirebasePerfEarly.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,8 @@ public FirebasePerfEarly(
5151
uiExecutor.execute(new AppStartTrace.StartFromBackgroundRunnable(appStartTrace));
5252
}
5353

54-
// TODO: Bring back Firebase Sessions dependency to watch for updates to sessions.
54+
// In the case of a cold start, we initialize gauge collection with a legacy PerfSession.
5555

56-
// In the case of cold start, we create a session and start collecting gauges as early as
57-
// possible.
58-
// There is code in SessionManager that prevents us from resetting the session twice in case
59-
// of app cold start.
6056
SessionManager.getInstance().initializeGaugeCollection();
6157
}
6258
}

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

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import androidx.annotation.Keep;
2020
import androidx.annotation.VisibleForTesting;
2121
import com.google.firebase.perf.application.AppStateMonitor;
22+
import com.google.firebase.perf.application.AppStateUpdateHandler;
2223
import com.google.firebase.perf.logging.FirebaseSessionsEnforcementCheck;
2324
import com.google.firebase.perf.session.gauges.GaugeManager;
2425
import com.google.firebase.perf.v1.ApplicationProcessState;
@@ -32,7 +33,7 @@
3233

3334
/** Session manager to generate sessionIDs and broadcast to the application. */
3435
@Keep // Needed because of b/117526359.
35-
public class SessionManager {
36+
public class SessionManager extends AppStateUpdateHandler {
3637
@SuppressLint("StaticFieldLeak")
3738
private static final SessionManager instance = new SessionManager();
3839

@@ -66,6 +67,7 @@ public SessionManager(
6667
this.gaugeManager = gaugeManager;
6768
this.perfSession = perfSession;
6869
this.appStateMonitor = appStateMonitor;
70+
registerForAppState();
6971
}
7072

7173
/**
@@ -76,6 +78,20 @@ public void setApplicationContext(final Context appContext) {
7678
gaugeManager.initializeGaugeMetadataManager(appContext);
7779
}
7880

81+
@Override
82+
public void onUpdateAppState(ApplicationProcessState newAppState) {
83+
super.onUpdateAppState(newAppState);
84+
if (appStateMonitor.isColdStart()) {
85+
// Ignore the app state change if it's a cold start.
86+
return;
87+
}
88+
89+
if (this.perfSession.isVerbose()) {
90+
long collectionFrequency = updateGaugeCollection(newAppState);
91+
updateGaugeLogging(perfSession.sessionId(), newAppState, collectionFrequency);
92+
}
93+
}
94+
7995
/**
8096
* Checks if the current {@link PerfSession} is expired/timed out. If so, stop collecting gauges.
8197
*
@@ -92,12 +108,10 @@ public void stopGaugeCollectionIfSessionRunningTooLong() {
92108
}
93109

94110
/**
95-
* Updates the currently associated {@link #perfSession} and broadcast the change.
96-
*
97-
* <p>Uses the provided PerfSession {@link PerfSession}, log the {@link GaugeMetadata} and
98-
* start/stop the collection of {@link GaugeMetric} depending upon Session verbosity.
111+
* Updates the currently associated {@link #perfSession} and broadcast the change to relevant
112+
* traces.
99113
*
100-
* @see PerfSession#isVerbose()
114+
* <p>Uses the provided PerfSession {@link PerfSession}.
101115
*/
102116
public void updatePerfSession(PerfSession perfSession) {
103117
// Do not update the perf session if it is the exact same sessionId.
@@ -106,9 +120,6 @@ public void updatePerfSession(PerfSession perfSession) {
106120
}
107121

108122
this.perfSession = perfSession;
109-
110-
// TODO(b/394127311): Update/verify behavior for Firebase Sessions.
111-
112123
synchronized (clients) {
113124
for (Iterator<WeakReference<SessionAwareObject>> i = clients.iterator(); i.hasNext(); ) {
114125
SessionAwareObject callback = i.next().get();
@@ -121,9 +132,6 @@ public void updatePerfSession(PerfSession perfSession) {
121132
}
122133
}
123134
}
124-
125-
// Start of stop the gauge data collection.
126-
startOrStopCollectingGauges(appStateMonitor.getAppState());
127135
}
128136

129137
/**
@@ -133,7 +141,9 @@ public void updatePerfSession(PerfSession perfSession) {
133141
* this does not reset the perfSession.
134142
*/
135143
public void initializeGaugeCollection() {
136-
startOrStopCollectingGauges(ApplicationProcessState.FOREGROUND);
144+
if (perfSession.isVerbose()) {
145+
updateGaugeCollection(ApplicationProcessState.FOREGROUND);
146+
}
137147
}
138148

139149
/**
@@ -160,17 +170,25 @@ public void unregisterForSessionUpdates(WeakReference<SessionAwareObject> client
160170
}
161171
}
162172

163-
private void startOrStopCollectingGauges(ApplicationProcessState appState) {
164-
FirebaseSessionsEnforcementCheck.checkSession(
165-
perfSession, "Session is not ready while trying to startOrStopCollectingGauges");
173+
private long updateGaugeCollection(ApplicationProcessState applicationProcessState) {
174+
return gaugeManager.updateGaugeCollection(applicationProcessState, perfSession.getTimer());
175+
}
166176

167-
if (perfSession.isGaugeAndEventCollectionEnabled()) {
168-
gaugeManager.startCollectingGauges(perfSession, appState);
169-
} else {
170-
gaugeManager.stopCollectingGauges();
171-
}
177+
private void updateGaugeLogging(String sessionId, ApplicationProcessState applicationProcessState, long collectionFrequency) {
178+
gaugeManager.updateGaugeLogging(sessionId, applicationProcessState, collectionFrequency);
172179
}
173180

181+
// private void startOrStopCollectingGauges(ApplicationProcessState appState) {
182+
// FirebaseSessionsEnforcementCheck.checkSession(
183+
// perfSession, "Session is not ready while trying to startOrStopCollectingGauges");
184+
//
185+
// if (perfSession.isGaugeAndEventCollectionEnabled()) {
186+
// gaugeManager.startCollectingGauges(perfSession, appState);
187+
// } else {
188+
// gaugeManager.stopCollectingGauges();
189+
// }
190+
// }
191+
174192
@VisibleForTesting
175193
public void setPerfSession(PerfSession perfSession) {
176194
this.perfSession = perfSession;

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

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,10 @@ public class GaugeManager {
5959
private final TransportManager transportManager;
6060

6161
@Nullable private GaugeMetadataManager gaugeMetadataManager;
62-
@Nullable private ScheduledFuture gaugeManagerDataCollectionJob = null;
62+
@Nullable private ScheduledFuture<?> gaugeManagerDataCollectionJob = null;
6363
@Nullable private String sessionId = null;
64+
65+
private boolean isCollectingGauges = false;
6466
private ApplicationProcessState applicationProcessState =
6567
ApplicationProcessState.APPLICATION_PROCESS_STATE_UNKNOWN;
6668

@@ -103,6 +105,32 @@ public static synchronized GaugeManager getInstance() {
103105
return instance;
104106
}
105107

108+
public void updateGaugeLogging(String sessionId, ApplicationProcessState applicationProcessState, long collectionFrequency) {
109+
try {
110+
gaugeManagerDataCollectionJob =
111+
gaugeManagerExecutor
112+
.get()
113+
.scheduleWithFixedDelay(
114+
() -> {
115+
syncFlush(sessionId, applicationProcessState);
116+
},
117+
/* initialDelay= */ collectionFrequency
118+
* APPROX_NUMBER_OF_DATA_POINTS_PER_GAUGE_METRIC,
119+
/* period= */ collectionFrequency * APPROX_NUMBER_OF_DATA_POINTS_PER_GAUGE_METRIC,
120+
TimeUnit.MILLISECONDS);
121+
122+
} catch (RejectedExecutionException e) {
123+
logger.warn("Unable to start collecting Gauges: " + e.getMessage());
124+
}
125+
}
126+
127+
public long updateGaugeCollection(ApplicationProcessState applicationProcessState, Timer gaugeCollectionTimer) {
128+
if (isCollectingGauges) {
129+
stopCollectingGauges();
130+
}
131+
return startCollectingGauges(applicationProcessState, gaugeCollectionTimer);
132+
}
133+
106134
/**
107135
* Starts the collection of available gauges for the given {@code sessionId} and {@code
108136
* applicationProcessState}. The collected Gauge Metrics will be flushed at regular intervals.
@@ -190,7 +218,7 @@ private long startCollectingGauges(ApplicationProcessState appState, Timer refer
190218
* this.stopCollectingGauges()} should always be called from the same thread.
191219
*/
192220
public void stopCollectingGauges() {
193-
if (this.sessionId == null) {
221+
if (!this.isCollectingGauges) {
194222
return;
195223
}
196224

@@ -219,6 +247,7 @@ public void stopCollectingGauges() {
219247
TimeUnit.MILLISECONDS);
220248

221249
this.sessionId = null;
250+
this.isCollectingGauges = false;
222251
this.applicationProcessState = ApplicationProcessState.APPLICATION_PROCESS_STATE_UNKNOWN;
223252
}
224253

@@ -253,16 +282,16 @@ private void syncFlush(String sessionId, ApplicationProcessState appState) {
253282
/**
254283
* Log the Gauge Metadata information to the transport.
255284
*
256-
* @param aqsSessionId The {@link PerfSession#aqsSessionId()} ()} to which the collected Gauge Metrics
285+
* @param sessionId The {@link PerfSession#sessionId()} ()} to which the collected Gauge Metrics
257286
* should be associated with.
258287
* @param appState The {@link ApplicationProcessState} for which these gauges are collected.
259288
* @return true if GaugeMetadata was logged, false otherwise.
260289
*/
261-
public boolean logGaugeMetadata(String aqsSessionId, ApplicationProcessState appState) {
290+
public boolean logGaugeMetadata(String sessionId, ApplicationProcessState appState) {
262291
if (gaugeMetadataManager != null) {
263292
GaugeMetric gaugeMetric =
264293
GaugeMetric.newBuilder()
265-
.setSessionId(aqsSessionId)
294+
.setSessionId(sessionId)
266295
.setGaugeMetadata(getGaugeMetadata())
267296
.build();
268297
transportManager.log(gaugeMetric, appState);
@@ -335,6 +364,22 @@ public void collectGaugeMetricOnce(Timer referenceTime) {
335364
collectGaugeMetricOnce(cpuGaugeCollector.get(), memoryGaugeCollector.get(), referenceTime);
336365
}
337366

367+
public void logExistingGaugeMetrics(String sessionId, ApplicationProcessState applicationProcessState) {
368+
// Flush any data that was collected and associate it with the given session ID and
369+
// applicationProcessState.
370+
@SuppressWarnings("FutureReturnValueIgnored")
371+
ScheduledFuture<?> unusedFuture =
372+
gaugeManagerExecutor
373+
.get()
374+
.schedule(
375+
() -> {
376+
syncFlush(sessionId, applicationProcessState);
377+
},
378+
TIME_TO_WAIT_BEFORE_FLUSHING_GAUGES_QUEUE_MS,
379+
TimeUnit.MILLISECONDS);
380+
381+
}
382+
338383
private static void collectGaugeMetricOnce(
339384
CpuGaugeCollector cpuGaugeCollector,
340385
MemoryGaugeCollector memoryGaugeCollector,
@@ -405,4 +450,8 @@ private long getMemoryGaugeCollectionFrequencyMs(
405450
return memoryGaugeCollectionFrequency;
406451
}
407452
}
453+
454+
private long getGaugeLoggingFrequency(ApplicationProcessState applicationProcessState) {
455+
return Math.min(getMemoryGaugeCollectionFrequencyMs(applicationProcessState), getCpuGaugeCollectionFrequencyMs(applicationProcessState));
456+
}
408457
}

0 commit comments

Comments
 (0)