Skip to content

Commit 81bc789

Browse files
author
Bartosz Litwiniuk
committed
Refactor BacktraceDatabase timer
1 parent dad6f0d commit 81bc789

File tree

1 file changed

+67
-59
lines changed

1 file changed

+67
-59
lines changed

backtrace-library/src/main/java/backtraceio/library/BacktraceDatabase.java

Lines changed: 67 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
*/
4444
public class BacktraceDatabase implements Database {
4545

46-
private static boolean _timerBackgroundWork = false;
4746
private static Timer _timer;
4847
private transient final String LOG_TAG = BacktraceDatabase.class.getSimpleName();
4948
private Api BacktraceApi;
@@ -96,21 +95,25 @@ public BacktraceDatabase(Context context, BacktraceDatabaseSettings databaseSett
9695
throw new IllegalArgumentException("Database settings or application context is null");
9796
}
9897

99-
if (databaseSettings.getDatabasePath() == null || databaseSettings.getDatabasePath().isEmpty()) {
98+
if (databaseSettings.getDatabasePath() == null || databaseSettings.getDatabasePath()
99+
.isEmpty()) {
100100
throw new IllegalArgumentException("Database path is null or empty");
101101
}
102102

103103
if (!FileHelper.isFileExists(databaseSettings.getDatabasePath())) {
104104
boolean createDirs = new File(databaseSettings.getDatabasePath()).mkdirs();
105105
if (!createDirs || !FileHelper.isFileExists(databaseSettings.getDatabasePath())) {
106-
throw new IllegalArgumentException("Incorrect database path or application " + "doesn't have permission to write to this path");
106+
throw new IllegalArgumentException("Incorrect database path or application " +
107+
"doesn't have permission to write to this path");
107108
}
108109
}
109110

110111
this._applicationContext = context;
111112
this.databaseSettings = databaseSettings;
112113
this.backtraceDatabaseContext = new BacktraceDatabaseContext(databaseSettings);
113-
this.backtraceDatabaseFileContext = new BacktraceDatabaseFileContext(this.getDatabasePath(), this.databaseSettings.getMaxDatabaseSize(), this.databaseSettings.getMaxRecordCount());
114+
this.backtraceDatabaseFileContext = new BacktraceDatabaseFileContext(this.getDatabasePath(),
115+
this.databaseSettings.getMaxDatabaseSize(), this.databaseSettings
116+
.getMaxRecordCount());
114117
this.breadcrumbs = new BacktraceBreadcrumbs(getDatabasePath());
115118
this.crashHandlerConfiguration = new CrashHandlerConfiguration();
116119
}
@@ -136,7 +139,8 @@ public Boolean setupNativeIntegration(BacktraceBase client, BacktraceCredentials
136139
* @param credentials Backtrace credentials
137140
* @param enableClientSideUnwinding Enable client side unwinding
138141
*/
139-
public Boolean setupNativeIntegration(BacktraceBase client, BacktraceCredentials credentials, boolean enableClientSideUnwinding) {
142+
public Boolean setupNativeIntegration(BacktraceBase client, BacktraceCredentials credentials,
143+
boolean enableClientSideUnwinding) {
140144
return setupNativeIntegration(client, credentials, enableClientSideUnwinding, UnwindingMode.REMOTE_DUMPWITHOUTCRASH);
141145
}
142146

@@ -153,10 +157,10 @@ public void useNativeCommunication(NativeCommunication nativeCommunication) {
153157
* @param client Backtrace client
154158
* @param credentials Backtrace credentials
155159
* @param enableClientSideUnwinding Enable client side unwinding
156-
* @param unwindingMode Unwinding mode to use for client side
157-
* unwinding
160+
* @param unwindingMode Unwinding mode to use for client side unwinding
158161
*/
159-
public Boolean setupNativeIntegration(BacktraceBase client, BacktraceCredentials credentials, boolean enableClientSideUnwinding, UnwindingMode unwindingMode) {
162+
public Boolean setupNativeIntegration(BacktraceBase client, BacktraceCredentials credentials,
163+
boolean enableClientSideUnwinding, UnwindingMode unwindingMode) {
160164
// avoid initialization when database doesn't exist
161165
if (_enable == false || getSettings() == null) {
162166
return false;
@@ -194,7 +198,15 @@ public Boolean setupNativeIntegration(BacktraceBase client, BacktraceCredentials
194198

195199
ApplicationInfo applicationInfo = _applicationContext.getApplicationInfo();
196200

197-
_enabledNativeIntegration = nativeCommunication.initializeJavaCrashHandler(minidumpSubmissionUrl, crashpadDatabaseDirectory, this.crashHandlerConfiguration.getClassPath(), keys, values, attachmentPaths, this.crashHandlerConfiguration.getCrashHandlerEnvironmentVariables(applicationInfo).toArray(new String[0]));
201+
_enabledNativeIntegration =
202+
nativeCommunication.initializeJavaCrashHandler(minidumpSubmissionUrl,
203+
crashpadDatabaseDirectory,
204+
this.crashHandlerConfiguration.getClassPath(),
205+
keys,
206+
values,
207+
attachmentPaths,
208+
this.crashHandlerConfiguration.getCrashHandlerEnvironmentVariables(applicationInfo).toArray(new String[0])
209+
);
198210

199211
if (_enabledNativeIntegration && this.breadcrumbs.isEnabled()) {
200212
this.breadcrumbs.setOnSuccessfulBreadcrumbAddEventListener(breadcrumbId -> {
@@ -252,7 +264,8 @@ public void start() {
252264

253265
this.removeOrphaned();
254266

255-
if (databaseSettings.getRetryBehavior() == RetryBehavior.ByInterval || databaseSettings.isAutoSendMode()) {
267+
if (databaseSettings.getRetryBehavior() == RetryBehavior.ByInterval || databaseSettings
268+
.isAutoSendMode()) {
256269
setupTimer();
257270
}
258271

@@ -274,69 +287,64 @@ private void setupTimer() {
274287
@Override
275288
public void run() {
276289
String dateTimeNow = Calendar.getInstance().getTime().toString();
277-
BacktraceLogger.d(LOG_TAG, "Timer - " + dateTimeNow);
290+
BacktraceLogger.d(LOG_TAG, "Backtrace DB Timer - " + dateTimeNow);
278291
if (backtraceDatabaseContext == null) {
279-
BacktraceLogger.w(LOG_TAG, "Timer - database context is null: " + dateTimeNow);
292+
BacktraceLogger.w(LOG_TAG, "Backtrace DB Timer - database context is null: " +
293+
dateTimeNow);
280294
return;
281295
}
282296

283297
if (backtraceDatabaseContext.isEmpty()) {
284-
BacktraceLogger.d(LOG_TAG, "Timer - database is empty (no records): " + dateTimeNow);
298+
BacktraceLogger.d(LOG_TAG, "Backtrace DB Timer - database is empty (no records): " +
299+
dateTimeNow);
285300
return;
286301
}
287302

288-
if (_timerBackgroundWork) {
289-
BacktraceLogger.d(LOG_TAG, "Timer - another timer works now: " + dateTimeNow);
290-
return;
291-
}
292-
293-
BacktraceLogger.d(LOG_TAG, "Timer - continue working: " + dateTimeNow);
294-
_timerBackgroundWork = true;
295-
_timer.cancel();
296-
_timer.purge();
297-
_timer = null;
298-
299-
BacktraceDatabaseRecord record = backtraceDatabaseContext.first();
300-
while (record != null) {
301-
final CountDownLatch threadWaiter = new CountDownLatch(1);
302-
BacktraceData backtraceData = record.getBacktraceData();
303-
if (backtraceData == null || backtraceData.getReport() == null) {
304-
BacktraceLogger.d(LOG_TAG, "Timer - backtrace data or report is null - " + "deleting record");
305-
delete(record);
306-
} else {
307-
final BacktraceDatabaseRecord currentRecord = record;
308-
BacktraceApi.send(backtraceData, new OnServerResponseEventListener() {
309-
@Override
310-
public void onEvent(BacktraceResult backtraceResult) {
311-
if (backtraceResult.status == BacktraceResultStatus.Ok) {
312-
BacktraceLogger.d(LOG_TAG, "Timer - deleting record");
313-
delete(currentRecord);
314-
} else {
315-
BacktraceLogger.d(LOG_TAG, "Timer - closing record");
316-
currentRecord.close();
317-
// backtraceDatabaseContext.incrementBatchRetry(); TODO: consider another way to
318-
// remove some records after few retries
303+
try {
304+
BacktraceDatabaseRecord record = backtraceDatabaseContext.first();
305+
while (record != null) {
306+
final CountDownLatch threadWaiter = new CountDownLatch(1);
307+
BacktraceData backtraceData = record.getBacktraceData();
308+
if (backtraceData == null || backtraceData.getReport() == null) {
309+
BacktraceLogger.d(LOG_TAG, "Backtrace DB Timer - backtrace data or report is null - " +
310+
"deleting record");
311+
delete(record);
312+
} else {
313+
final BacktraceDatabaseRecord currentRecord = record;
314+
BacktraceApi.send(backtraceData, new OnServerResponseEventListener() {
315+
@Override
316+
public void onEvent(BacktraceResult backtraceResult) {
317+
if (backtraceResult.status == BacktraceResultStatus.Ok) {
318+
BacktraceLogger.d(LOG_TAG, "Backtrace DB Timer - deleting record");
319+
delete(currentRecord);
320+
} else {
321+
BacktraceLogger.d(LOG_TAG, "Backtrace DB Timer - closing record");
322+
currentRecord.close();
323+
// backtraceDatabaseContext.incrementBatchRetry(); TODO: consider another way to remove some records after few retries
324+
}
325+
threadWaiter.countDown();
319326
}
320-
threadWaiter.countDown();
327+
});
328+
try {
329+
threadWaiter.await();
330+
} catch (Exception ex) {
331+
BacktraceLogger.e(LOG_TAG,
332+
"Error during waiting for result in Backtrace DB Timer", ex
333+
);
334+
}
335+
if (currentRecord.valid() && !currentRecord.locked) {
336+
BacktraceLogger.d(LOG_TAG, "Backtrace DB Timer - record is valid and unlocked");
337+
break;
321338
}
322-
});
323-
try {
324-
threadWaiter.await();
325-
} catch (Exception ex) {
326-
BacktraceLogger.e(LOG_TAG, "Error during waiting for result in Timer", ex);
327-
}
328-
if (currentRecord.valid() && !currentRecord.locked) {
329-
BacktraceLogger.d(LOG_TAG, "Timer - record is valid and unlocked");
330-
break;
331339
}
340+
record = backtraceDatabaseContext.first();
332341
}
333-
record = backtraceDatabaseContext.first();
334342
}
335-
BacktraceLogger.d(LOG_TAG, "Setup new timer");
336-
_timerBackgroundWork = false;
337-
setupTimer();
343+
catch (Exception e) {
344+
BacktraceLogger.e(LOG_TAG, "Exception in Backtrace DB timer", e);
345+
}
338346
}
339-
}, databaseSettings.getRetryInterval() * 1000L);
347+
}, databaseSettings.getRetryInterval() * 1000L, databaseSettings.getRetryInterval() * 1000L);
340348
}
341349

342350
public void flush() {

0 commit comments

Comments
 (0)