Skip to content

Commit 9c03b7b

Browse files
authored
Remove the logging of GaugeMetadata to allow using AQS (#6678)
Based on the behaviour of AQS w/ Fireperf, an AQS session isn't available when (currently) logging gauge metadata. Changes: - Remove the current logging of gauge metadata - will be re-introduced in a future PR. - Switch Gauge collection from `scheduleAtFixedRate` to `scheduleWithFixedDelay`. As [documented](https://stackoverflow.com/a/78405653), this *should* prevent a potentially large amounts of gauge collection if a process is cached, and then restored during a verbose session - which *should* make it work better w/ AQS. - Remove API restricted behaviour which is no longer relevant.
1 parent b8803fc commit 9c03b7b

File tree

8 files changed

+14
-190
lines changed

8 files changed

+14
-190
lines changed

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,6 @@ public static FirebasePerformance getInstance() {
182182
.initialize(firebaseApp, firebaseInstallationsApi, transportFactoryProvider);
183183

184184
Context appContext = firebaseApp.getApplicationContext();
185-
// TODO(b/110178816): Explore moving off of main thread.
186185
mMetadataBundle = extractMetadata(appContext);
187186

188187
remoteConfigManager.setFirebaseRemoteConfigProvider(firebaseRemoteConfigProvider);

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

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -79,20 +79,13 @@ public SessionManager(
7979
* (currently that is before onResume finishes) to ensure gauge collection starts on time.
8080
*/
8181
public void setApplicationContext(final Context appContext) {
82-
// Get PerfSession in main thread first, because it is possible that app changes fg/bg state
83-
// which creates a new perfSession, before the following is executed in background thread
84-
final PerfSession appStartSession = perfSession;
8582
// TODO(b/258263016): Migrate to go/firebase-android-executors
8683
@SuppressLint("ThreadPoolCreation")
8784
ExecutorService executorService = Executors.newSingleThreadExecutor();
8885
syncInitFuture =
8986
executorService.submit(
9087
() -> {
9188
gaugeManager.initializeGaugeMetadataManager(appContext);
92-
if (appStartSession.isGaugeAndEventCollectionEnabled()) {
93-
gaugeManager.logGaugeMetadata(
94-
appStartSession.sessionId(), ApplicationProcessState.FOREGROUND);
95-
}
9689
});
9790
}
9891

@@ -164,9 +157,6 @@ public void updatePerfSession(PerfSession perfSession) {
164157
}
165158
}
166159

167-
// Log the gauge metadata event if data collection is enabled.
168-
logGaugeMetadataIfCollectionEnabled(appStateMonitor.getAppState());
169-
170160
// Start of stop the gauge data collection.
171161
startOrStopCollectingGauges(appStateMonitor.getAppState());
172162
}
@@ -178,7 +168,6 @@ public void updatePerfSession(PerfSession perfSession) {
178168
* this does not reset the perfSession.
179169
*/
180170
public void initializeGaugeCollection() {
181-
logGaugeMetadataIfCollectionEnabled(ApplicationProcessState.FOREGROUND);
182171
startOrStopCollectingGauges(ApplicationProcessState.FOREGROUND);
183172
}
184173

@@ -206,12 +195,6 @@ public void unregisterForSessionUpdates(WeakReference<SessionAwareObject> client
206195
}
207196
}
208197

209-
private void logGaugeMetadataIfCollectionEnabled(ApplicationProcessState appState) {
210-
if (perfSession.isGaugeAndEventCollectionEnabled()) {
211-
gaugeManager.logGaugeMetadata(perfSession.sessionId(), appState);
212-
}
213-
}
214-
215198
private void startOrStopCollectingGauges(ApplicationProcessState appState) {
216199
if (perfSession.isGaugeAndEventCollectionEnabled()) {
217200
gaugeManager.startCollectingGauges(perfSession, appState);

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

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
import static android.system.Os.sysconf;
1818

1919
import android.annotation.SuppressLint;
20-
import android.os.Build.VERSION;
21-
import android.os.Build.VERSION_CODES;
2220
import android.system.OsConstants;
2321
import androidx.annotation.Nullable;
2422
import androidx.annotation.VisibleForTesting;
@@ -163,7 +161,7 @@ private synchronized void scheduleCpuMetricCollectionWithRate(
163161
this.cpuMetricCollectionRateMs = cpuMetricCollectionRate;
164162
try {
165163
cpuMetricCollectorJob =
166-
cpuMetricCollectorExecutor.scheduleAtFixedRate(
164+
cpuMetricCollectorExecutor.scheduleWithFixedDelay(
167165
() -> {
168166
CpuMetricReading currCpuReading = syncCollectCpuMetric(referenceTime);
169167
if (currCpuReading != null) {
@@ -181,7 +179,7 @@ private synchronized void scheduleCpuMetricCollectionWithRate(
181179
private synchronized void scheduleCpuMetricCollectionOnce(Timer referenceTime) {
182180
try {
183181
@SuppressWarnings("FutureReturnValueIgnored")
184-
ScheduledFuture unusedFuture =
182+
ScheduledFuture<?> unusedFuture =
185183
cpuMetricCollectorExecutor.schedule(
186184
() -> {
187185
CpuMetricReading currCpuReading = syncCollectCpuMetric(referenceTime);
@@ -227,12 +225,7 @@ private CpuMetricReading syncCollectCpuMetric(Timer referenceTime) {
227225
}
228226

229227
private long getClockTicksPerSecond() {
230-
if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
231-
return sysconf(OsConstants._SC_CLK_TCK);
232-
} else {
233-
// TODO(b/110779408): Figure out how to collect this info for Android API 20 and below.
234-
return INVALID_SC_PER_CPU_CLOCK_TICK;
235-
}
228+
return sysconf(OsConstants._SC_CLK_TCK);
236229
}
237230

238231
private long convertClockTicksToMicroseconds(long clockTicks) {

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,16 +72,16 @@ private GaugeManager() {
7272
TransportManager.getInstance(),
7373
ConfigResolver.getInstance(),
7474
null,
75-
new Lazy<>(() -> new CpuGaugeCollector()),
76-
new Lazy<>(() -> new MemoryGaugeCollector()));
75+
new Lazy<>(CpuGaugeCollector::new),
76+
new Lazy<>(MemoryGaugeCollector::new));
7777
}
7878

7979
@VisibleForTesting
8080
GaugeManager(
8181
Lazy<ScheduledExecutorService> gaugeManagerExecutor,
8282
TransportManager transportManager,
8383
ConfigResolver configResolver,
84-
GaugeMetadataManager gaugeMetadataManager,
84+
@Nullable GaugeMetadataManager gaugeMetadataManager,
8585
Lazy<CpuGaugeCollector> cpuGaugeCollector,
8686
Lazy<MemoryGaugeCollector> memoryGaugeCollector) {
8787

@@ -140,7 +140,7 @@ public void startCollectingGauges(
140140
gaugeManagerDataCollectionJob =
141141
gaugeManagerExecutor
142142
.get()
143-
.scheduleAtFixedRate(
143+
.scheduleWithFixedDelay(
144144
() -> {
145145
syncFlush(sessionIdForScheduledTask, applicationProcessStateForScheduledTask);
146146
},
@@ -256,6 +256,7 @@ private void syncFlush(String sessionId, ApplicationProcessState appState) {
256256
* @return true if GaugeMetadata was logged, false otherwise.
257257
*/
258258
public boolean logGaugeMetadata(String sessionId, ApplicationProcessState appState) {
259+
// TODO(b/394127311): Re-introduce logging of metadata for AQS.
259260
if (gaugeMetadataManager != null) {
260261
GaugeMetric gaugeMetric =
261262
GaugeMetric.newBuilder()

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

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,11 @@
1717
import android.app.ActivityManager;
1818
import android.app.ActivityManager.MemoryInfo;
1919
import android.content.Context;
20-
import android.os.Build.VERSION;
21-
import android.os.Build.VERSION_CODES;
2220
import androidx.annotation.VisibleForTesting;
2321
import com.google.firebase.perf.logging.AndroidLogger;
2422
import com.google.firebase.perf.util.StorageUnit;
2523
import com.google.firebase.perf.util.Utils;
2624
import com.google.firebase.perf.v1.GaugeMetadata;
27-
import java.io.BufferedReader;
28-
import java.io.FileReader;
29-
import java.io.IOException;
30-
import java.util.regex.Matcher;
31-
import java.util.regex.Pattern;
3225

3326
/**
3427
* The {@code GaugeMetadataManager} class is responsible for collecting {@link GaugeMetadata}
@@ -41,7 +34,6 @@ class GaugeMetadataManager {
4134
private final Runtime runtime;
4235
private final ActivityManager activityManager;
4336
private final MemoryInfo memoryInfo;
44-
private final Context appContext;
4537

4638
GaugeMetadataManager(Context appContext) {
4739
this(Runtime.getRuntime(), appContext);
@@ -50,7 +42,6 @@ class GaugeMetadataManager {
5042
@VisibleForTesting
5143
GaugeMetadataManager(Runtime runtime, Context appContext) {
5244
this.runtime = runtime;
53-
this.appContext = appContext;
5445
this.activityManager = (ActivityManager) appContext.getSystemService(Context.ACTIVITY_SERVICE);
5546
memoryInfo = new ActivityManager.MemoryInfo();
5647
activityManager.getMemoryInfo(memoryInfo);
@@ -75,29 +66,6 @@ public int getMaxEncouragedAppJavaHeapMemoryKb() {
7566

7667
/** Returns the total memory (in kilobytes) accessible by the kernel (called the RAM size). */
7768
public int getDeviceRamSizeKb() {
78-
if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
79-
return Utils.saturatedIntCast(StorageUnit.BYTES.toKilobytes(memoryInfo.totalMem));
80-
}
81-
82-
return readTotalRAM(/* procFileName= */ "/proc/meminfo");
83-
}
84-
85-
/** Returns the total ram size of the device (in kilobytes) by reading the "proc/meminfo" file. */
86-
@VisibleForTesting
87-
int readTotalRAM(String procFileName) {
88-
try (BufferedReader br = new BufferedReader(new FileReader(procFileName))) {
89-
for (String s = br.readLine(); s != null; s = br.readLine()) {
90-
if (s.startsWith("MemTotal")) {
91-
Matcher m = Pattern.compile("\\d+").matcher(s);
92-
return m.find() ? Integer.parseInt(m.group()) : 0;
93-
}
94-
}
95-
} catch (IOException ioe) {
96-
logger.warn("Unable to read '" + procFileName + "' file: " + ioe.getMessage());
97-
} catch (NumberFormatException nfe) {
98-
logger.warn("Unable to parse '" + procFileName + "' file: " + nfe.getMessage());
99-
}
100-
101-
return 0;
69+
return Utils.saturatedIntCast(StorageUnit.BYTES.toKilobytes(memoryInfo.totalMem));
10270
}
10371
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public class MemoryGaugeCollector {
5050
public final ConcurrentLinkedQueue<AndroidMemoryReading> memoryMetricReadings;
5151
private final Runtime runtime;
5252

53-
@Nullable private ScheduledFuture memoryMetricCollectorJob = null;
53+
@Nullable private ScheduledFuture<?> memoryMetricCollectorJob = null;
5454
private long memoryMetricCollectionRateMs = UNSET_MEMORY_METRIC_COLLECTION_RATE;
5555

5656
// TODO(b/258263016): Migrate to go/firebase-android-executors
@@ -124,7 +124,7 @@ private synchronized void scheduleMemoryMetricCollectionWithRate(
124124

125125
try {
126126
memoryMetricCollectorJob =
127-
memoryMetricCollectorExecutor.scheduleAtFixedRate(
127+
memoryMetricCollectorExecutor.scheduleWithFixedDelay(
128128
() -> {
129129
AndroidMemoryReading memoryReading = syncCollectMemoryMetric(referenceTime);
130130
if (memoryReading != null) {
@@ -142,7 +142,7 @@ private synchronized void scheduleMemoryMetricCollectionWithRate(
142142
private synchronized void scheduleMemoryMetricCollectionOnce(Timer referenceTime) {
143143
try {
144144
@SuppressWarnings("FutureReturnValueIgnored")
145-
ScheduledFuture unusedFuture =
145+
ScheduledFuture<?> unusedFuture =
146146
memoryMetricCollectorExecutor.schedule(
147147
() -> {
148148
AndroidMemoryReading memoryReading = syncCollectMemoryMetric(referenceTime);

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

Lines changed: 1 addition & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public void testInstanceCreation() {
7474
}
7575

7676
@Test
77-
public void setApplicationContext_logGaugeMetadata_afterGaugeMetadataManagerIsInitialized()
77+
public void setApplicationContext_initializeGaugeMetadataManager()
7878
throws ExecutionException, InterruptedException {
7979
when(mockPerfSession.isGaugeAndEventCollectionEnabled()).thenReturn(true);
8080
InOrder inOrder = Mockito.inOrder(mockGaugeManager);
@@ -84,7 +84,6 @@ public void setApplicationContext_logGaugeMetadata_afterGaugeMetadataManagerIsIn
8484

8585
testSessionManager.getSyncInitFuture().get();
8686
inOrder.verify(mockGaugeManager).initializeGaugeMetadataManager(any());
87-
inOrder.verify(mockGaugeManager).logGaugeMetadata(any(), any());
8887
}
8988

9089
@Test
@@ -136,20 +135,6 @@ public void testOnUpdateAppStateGeneratesNewSessionIdOnBackgroundStateIfPerfSess
136135
assertThat(oldSessionId).isNotEqualTo(testSessionManager.perfSession().sessionId());
137136
}
138137

139-
@Test
140-
public void
141-
testOnUpdateAppStateMakesGaugeManagerLogGaugeMetadataOnForegroundStateIfSessionIsVerbose() {
142-
forceVerboseSession();
143-
144-
SessionManager testSessionManager =
145-
new SessionManager(mockGaugeManager, mockPerfSession, mockAppStateMonitor);
146-
testSessionManager.onUpdateAppState(ApplicationProcessState.FOREGROUND);
147-
148-
verify(mockGaugeManager)
149-
.logGaugeMetadata(
150-
anyString(), nullable(com.google.firebase.perf.v1.ApplicationProcessState.class));
151-
}
152-
153138
@Test
154139
public void
155140
testOnUpdateAppStateDoesntMakeGaugeManagerLogGaugeMetadataOnForegroundStateIfSessionIsNonVerbose() {
@@ -178,21 +163,6 @@ public void testOnUpdateAppStateGeneratesNewSessionIdOnBackgroundStateIfPerfSess
178163
anyString(), nullable(com.google.firebase.perf.v1.ApplicationProcessState.class));
179164
}
180165

181-
@Test
182-
public void
183-
testOnUpdateAppStateMakesGaugeManagerLogGaugeMetadataOnBackgroundAppStateIfSessionIsVerboseAndTimedOut() {
184-
when(mockPerfSession.isSessionRunningTooLong()).thenReturn(true);
185-
forceVerboseSession();
186-
187-
SessionManager testSessionManager =
188-
new SessionManager(mockGaugeManager, mockPerfSession, mockAppStateMonitor);
189-
testSessionManager.onUpdateAppState(ApplicationProcessState.BACKGROUND);
190-
191-
verify(mockGaugeManager)
192-
.logGaugeMetadata(
193-
anyString(), nullable(com.google.firebase.perf.v1.ApplicationProcessState.class));
194-
}
195-
196166
@Test
197167
public void testOnUpdateAppStateMakesGaugeManagerStartCollectingGaugesIfSessionIsVerbose() {
198168
forceVerboseSession();
@@ -232,32 +202,6 @@ public void testOnUpdateAppStateMakesGaugeManagerStopCollectingGaugesWhenSession
232202
verify(mockGaugeManager).stopCollectingGauges();
233203
}
234204

235-
@Test
236-
public void testGaugeMetadataIsFlushedOnlyWhenNewVerboseSessionIsCreated() {
237-
when(mockPerfSession.isSessionRunningTooLong()).thenReturn(false);
238-
239-
// Start with a non verbose session
240-
forceNonVerboseSession();
241-
SessionManager testSessionManager =
242-
new SessionManager(
243-
mockGaugeManager, PerfSession.createWithId("testSessionId1"), mockAppStateMonitor);
244-
245-
verify(mockGaugeManager, times(0))
246-
.logGaugeMetadata(
247-
eq("testSessionId1"),
248-
eq(com.google.firebase.perf.v1.ApplicationProcessState.FOREGROUND));
249-
250-
// Forcing a verbose session will enable Gauge collection
251-
forceVerboseSession();
252-
testSessionManager.updatePerfSession(PerfSession.createWithId("testSessionId2"));
253-
verify(mockGaugeManager, times(1)).logGaugeMetadata(eq("testSessionId2"), any());
254-
255-
// Force a non-verbose session and verify if we are not logging metadata
256-
forceVerboseSession();
257-
testSessionManager.updatePerfSession(PerfSession.createWithId("testSessionId3"));
258-
verify(mockGaugeManager, times(1)).logGaugeMetadata(eq("testSessionId3"), any());
259-
}
260-
261205
@Test
262206
public void testSessionIdDoesNotUpdateIfPerfSessionRunsTooLong() {
263207
Timer mockTimer = mock(Timer.class);

0 commit comments

Comments
 (0)