|
43 | 43 | */ |
44 | 44 | public class BacktraceDatabase implements Database { |
45 | 45 |
|
46 | | - private static boolean _timerBackgroundWork = false; |
47 | 46 | private static Timer _timer; |
48 | 47 | private transient final String LOG_TAG = BacktraceDatabase.class.getSimpleName(); |
49 | 48 | private Api BacktraceApi; |
@@ -284,83 +283,73 @@ public BacktraceDatabaseSettings getSettings() { |
284 | 283 |
|
285 | 284 | private void setupTimer() { |
286 | 285 | _timer = new Timer(); |
287 | | - _timer.scheduleAtFixedRate(new TimerTask() { |
| 286 | + _timer.schedule(new TimerTask() { |
288 | 287 | @Override |
289 | 288 | public void run() { |
290 | 289 | String dateTimeNow = Calendar.getInstance().getTime().toString(); |
291 | | - BacktraceLogger.d(LOG_TAG, "Timer - " + dateTimeNow); |
| 290 | + BacktraceLogger.d(LOG_TAG, "Backtrace DB Timer - " + dateTimeNow); |
292 | 291 | if (backtraceDatabaseContext == null) { |
293 | | - BacktraceLogger.w(LOG_TAG, "Timer - database context is null: " + |
| 292 | + BacktraceLogger.w(LOG_TAG, "Backtrace DB Timer - database context is null: " + |
294 | 293 | dateTimeNow); |
295 | 294 | return; |
296 | 295 | } |
297 | 296 |
|
298 | 297 | if (backtraceDatabaseContext.isEmpty()) { |
299 | | - BacktraceLogger.d(LOG_TAG, "Timer - database is empty (no records): " + |
| 298 | + BacktraceLogger.d(LOG_TAG, "Backtrace DB Timer - database is empty (no records): " + |
300 | 299 | dateTimeNow); |
301 | 300 | return; |
302 | 301 | } |
303 | 302 |
|
304 | | - if (_timerBackgroundWork) { |
305 | | - BacktraceLogger.d(LOG_TAG, "Timer - another timer works now: " + dateTimeNow); |
306 | | - return; |
307 | | - } |
308 | | - |
309 | | - BacktraceLogger.d(LOG_TAG, "Timer - continue working: " + dateTimeNow); |
310 | | - _timerBackgroundWork = true; |
311 | | - _timer.cancel(); |
312 | | - _timer.purge(); |
313 | | - _timer = null; |
314 | | - |
315 | | - BacktraceDatabaseRecord record = backtraceDatabaseContext.first(); |
316 | | - while (record != null) { |
317 | | - final CountDownLatch threadWaiter = new CountDownLatch(1); |
318 | | - BacktraceData backtraceData = record.getBacktraceData(); |
319 | | - if (backtraceData == null || backtraceData.getReport() == null) { |
320 | | - BacktraceLogger.d(LOG_TAG, "Timer - backtrace data or report is null - " + |
321 | | - "deleting record"); |
322 | | - delete(record); |
323 | | - } else { |
324 | | - final BacktraceDatabaseRecord currentRecord = record; |
325 | | - BacktraceApi.send(backtraceData, new OnServerResponseEventListener() { |
326 | | - @Override |
327 | | - public void onEvent(BacktraceResult backtraceResult) { |
328 | | - if (backtraceResult.status == BacktraceResultStatus.Ok) { |
329 | | - BacktraceLogger.d(LOG_TAG, "Timer - deleting record"); |
330 | | - delete(currentRecord); |
331 | | - } else { |
332 | | - BacktraceLogger.d(LOG_TAG, "Timer - closing record"); |
333 | | - currentRecord.close(); |
334 | | - // backtraceDatabaseContext.incrementBatchRetry(); TODO: consider another way to 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(); |
335 | 326 | } |
336 | | - 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; |
337 | 338 | } |
338 | | - }); |
339 | | - try { |
340 | | - threadWaiter.await(); |
341 | | - } catch (Exception ex) { |
342 | | - BacktraceLogger.e(LOG_TAG, |
343 | | - "Error during waiting for result in Timer", ex |
344 | | - ); |
345 | | - } |
346 | | - if (currentRecord.valid() && !currentRecord.locked) { |
347 | | - BacktraceLogger.d(LOG_TAG, "Timer - record is valid and unlocked"); |
348 | | - break; |
349 | 339 | } |
| 340 | + record = backtraceDatabaseContext.first(); |
350 | 341 | } |
351 | | - record = backtraceDatabaseContext.first(); |
352 | 342 | } |
353 | | - BacktraceLogger.d(LOG_TAG, "Setup new timer"); |
354 | | - _timerBackgroundWork = false; |
355 | | - setupTimer(); |
| 343 | + catch (Exception e) { |
| 344 | + BacktraceLogger.e(LOG_TAG, "Exception in Backtrace DB timer", e); |
| 345 | + } |
356 | 346 | } |
357 | | - }, databaseSettings.getRetryInterval() * 1000, databaseSettings.getRetryInterval() * 1000); |
| 347 | + }, databaseSettings.getRetryInterval() * 1000L, databaseSettings.getRetryInterval() * 1000L); |
358 | 348 | } |
359 | 349 |
|
360 | 350 | public void flush() { |
361 | 351 | if (this.BacktraceApi == null) { |
362 | | - throw new IllegalArgumentException("BacktraceApi is required " + |
363 | | - "if you want to use Flush method"); |
| 352 | + throw new IllegalArgumentException("BacktraceApi is required " + "if you want to use Flush method"); |
364 | 353 | } |
365 | 354 |
|
366 | 355 | BacktraceDatabaseRecord record = backtraceDatabaseContext.first(); |
@@ -396,13 +385,11 @@ public boolean validConsistency() { |
396 | 385 | return backtraceDatabaseFileContext.validFileConsistency(); |
397 | 386 | } |
398 | 387 |
|
399 | | - public BacktraceDatabaseRecord add(BacktraceReport backtraceReport, Map<String, Object> |
400 | | - attributes) { |
| 388 | + public BacktraceDatabaseRecord add(BacktraceReport backtraceReport, Map<String, Object> attributes) { |
401 | 389 | return add(backtraceReport, attributes, false); |
402 | 390 | } |
403 | 391 |
|
404 | | - public BacktraceDatabaseRecord add(BacktraceReport backtraceReport, Map<String, Object> |
405 | | - attributes, boolean isProguardEnabled) { |
| 392 | + public BacktraceDatabaseRecord add(BacktraceReport backtraceReport, Map<String, Object> attributes, boolean isProguardEnabled) { |
406 | 393 | if (!this._enable || backtraceReport == null) { |
407 | 394 | return null; |
408 | 395 | } |
@@ -446,8 +433,7 @@ private void loadReports() { |
446 | 433 |
|
447 | 434 | final long endLoadingReportsTime = System.currentTimeMillis(); |
448 | 435 |
|
449 | | - BacktraceLogger.d(LOG_TAG, "Loading " + backtraceDatabaseContext.count() + |
450 | | - " reports took " + (endLoadingReportsTime - startLoadingReportsTime) + " milliseconds"); |
| 436 | + BacktraceLogger.d(LOG_TAG, "Loading " + backtraceDatabaseContext.count() + " reports took " + (endLoadingReportsTime - startLoadingReportsTime) + " milliseconds"); |
451 | 437 | } |
452 | 438 |
|
453 | 439 | private void loadReportsToDbContext() { |
@@ -482,19 +468,16 @@ private boolean validateDatabaseSize() { |
482 | 468 | // Check how many records are stored in database |
483 | 469 | // Remove in case when we want to store one more than expected number |
484 | 470 | // If record count == 0 then we ignore this condition |
485 | | - if (backtraceDatabaseContext.count() + 1 > databaseSettings.getMaxRecordCount() && |
486 | | - databaseSettings.getMaxRecordCount() != 0) { |
| 471 | + if (backtraceDatabaseContext.count() + 1 > databaseSettings.getMaxRecordCount() && databaseSettings.getMaxRecordCount() != 0) { |
487 | 472 | if (!backtraceDatabaseContext.removeOldestRecord()) { |
488 | 473 | BacktraceLogger.e(LOG_TAG, "Can't remove last record. Database size is invalid"); |
489 | 474 | return false; |
490 | 475 | } |
491 | 476 | } |
492 | 477 |
|
493 | | - if (databaseSettings.getMaxDatabaseSize() != 0 && backtraceDatabaseContext |
494 | | - .getDatabaseSize() > databaseSettings.getMaxDatabaseSize()) { |
| 478 | + if (databaseSettings.getMaxDatabaseSize() != 0 && backtraceDatabaseContext.getDatabaseSize() > databaseSettings.getMaxDatabaseSize()) { |
495 | 479 | int deletePolicyRetry = 5; |
496 | | - while (backtraceDatabaseContext.getDatabaseSize() > databaseSettings |
497 | | - .getMaxDatabaseSize()) { |
| 480 | + while (backtraceDatabaseContext.getDatabaseSize() > databaseSettings.getMaxDatabaseSize()) { |
498 | 481 | backtraceDatabaseContext.removeOldestRecord(); |
499 | 482 | deletePolicyRetry--; // avoid infinity loop |
500 | 483 | if (deletePolicyRetry == 0) { |
|
0 commit comments