29
29
30
30
import com .fasterxml .jackson .databind .ObjectMapper ;
31
31
32
- import java .io .EOFException ;
33
- import java .io .FileInputStream ;
34
- import java .io .FileNotFoundException ;
35
- import java .io .FileOutputStream ;
36
32
import java .io .IOException ;
37
- import java .io .ObjectInputStream ;
38
- import java .io .ObjectOutputStream ;
39
33
import java .io .StringWriter ;
40
34
import java .util .ArrayList ;
41
35
import java .util .Formatter ;
42
36
import java .util .HashMap ;
43
37
import java .util .HashSet ;
38
+ import java .util .List ;
44
39
import java .util .Map ;
45
40
import java .util .Timer ;
46
41
import java .util .TimerTask ;
@@ -56,13 +51,10 @@ public class ParselyTracker {
56
51
private static ParselyTracker instance = null ;
57
52
private static final int DEFAULT_FLUSH_INTERVAL_SECS = 60 ;
58
53
private static final int DEFAULT_ENGAGEMENT_INTERVAL_MILLIS = 10500 ;
59
- private static final int QUEUE_SIZE_LIMIT = 50 ;
60
- private static final int STORAGE_SIZE_LIMIT = 100 ;
61
- private static final String STORAGE_KEY = "parsely-events.ser" ;
62
54
@ SuppressWarnings ("StringOperationCanBeSimplified" )
63
55
// private static final String ROOT_URL = "http://10.0.2.2:5001/".intern(); // emulator localhost
64
56
private static final String ROOT_URL = "https://p1.parsely.com/" .intern ();
65
- protected ArrayList <Map <String , Object >> eventQueue ;
57
+ private final ArrayList <Map <String , Object >> eventQueue ;
66
58
private boolean isDebug ;
67
59
private final Context context ;
68
60
private final Timer timer ;
@@ -72,14 +64,18 @@ public class ParselyTracker {
72
64
private String lastPageviewUuid = null ;
73
65
@ NonNull
74
66
private final EventsBuilder eventsBuilder ;
75
- @ NonNull final HeartbeatIntervalCalculator intervalCalculator = new HeartbeatIntervalCalculator (new Clock ());
67
+ @ NonNull
68
+ private final HeartbeatIntervalCalculator intervalCalculator = new HeartbeatIntervalCalculator (new Clock ());
69
+ @ NonNull
70
+ private final LocalStorageRepository localStorageRepository ;
76
71
77
72
/**
78
73
* Create a new ParselyTracker instance.
79
74
*/
80
75
protected ParselyTracker (String siteId , int flushInterval , Context c ) {
81
76
context = c .getApplicationContext ();
82
77
eventsBuilder = new EventsBuilder (context , siteId );
78
+ localStorageRepository = new LocalStorageRepository (context );
83
79
84
80
// get the adkey straight away on instantiation
85
81
timer = new Timer ();
@@ -89,7 +85,7 @@ protected ParselyTracker(String siteId, int flushInterval, Context c) {
89
85
90
86
flushManager = new FlushManager (timer , flushInterval * 1000L );
91
87
92
- if (getStoredQueue ().size () > 0 ) {
88
+ if (localStorageRepository . getStoredQueue ().size () > 0 ) {
93
89
startFlushTimer ();
94
90
}
95
91
@@ -102,6 +98,10 @@ protected ParselyTracker(String siteId, int flushInterval, Context c) {
102
98
);
103
99
}
104
100
101
+ List <Map <String , Object >> getInMemoryQueue () {
102
+ return eventQueue ;
103
+ }
104
+
105
105
/**
106
106
* Singleton instance accessor. Note: This must be called after {@link #sharedInstance(String, Context)}
107
107
*
@@ -411,14 +411,14 @@ public void resetVideo() {
411
411
* Place a data structure representing the event into the in-memory queue for later use.
412
412
* <p>
413
413
* **Note**: Events placed into this queue will be discarded if the size of the persistent queue
414
- * store exceeds {@link #STORAGE_SIZE_LIMIT}.
414
+ * store exceeds {@link QueueManager #STORAGE_SIZE_LIMIT}.
415
415
*
416
416
* @param event The event Map to enqueue.
417
417
*/
418
418
void enqueueEvent (Map <String , Object > event ) {
419
419
// Push it onto the queue
420
420
eventQueue .add (event );
421
- new QueueManager ().execute ();
421
+ new QueueManager (this , localStorageRepository ).execute ();
422
422
if (!flushTimerIsActive ()) {
423
423
startFlushTimer ();
424
424
PLog ("Flush flushTimer set to %ds" , (flushManager .getIntervalMillis () / 1000 ));
@@ -474,85 +474,9 @@ private boolean isReachable() {
474
474
return netInfo != null && netInfo .isConnectedOrConnecting ();
475
475
}
476
476
477
- /**
478
- * Save the event queue to persistent storage.
479
- */
480
- private synchronized void persistQueue () {
481
- PLog ("Persisting event queue" );
482
- ArrayList <Map <String , Object >> storedQueue = getStoredQueue ();
483
- HashSet <Map <String , Object >> hs = new HashSet <>();
484
- hs .addAll (storedQueue );
485
- hs .addAll (eventQueue );
486
- storedQueue .clear ();
487
- storedQueue .addAll (hs );
488
- persistObject (storedQueue );
489
- }
490
-
491
- /**
492
- * Get the stored event queue from persistent storage.
493
- *
494
- * @return The stored queue of events.
495
- */
496
- @ NonNull
497
- private ArrayList <Map <String , Object >> getStoredQueue () {
498
- ArrayList <Map <String , Object >> storedQueue = null ;
499
- try {
500
- FileInputStream fis = context .getApplicationContext ().openFileInput (STORAGE_KEY );
501
- ObjectInputStream ois = new ObjectInputStream (fis );
502
- //noinspection unchecked
503
- storedQueue = (ArrayList <Map <String , Object >>) ois .readObject ();
504
- ois .close ();
505
- } catch (EOFException ex ) {
506
- // Nothing to do here.
507
- } catch (FileNotFoundException ex ) {
508
- // Nothing to do here. Means there was no saved queue.
509
- } catch (Exception ex ) {
510
- PLog ("Exception thrown during queue deserialization: %s" , ex .toString ());
511
- }
512
-
513
- if (storedQueue == null ) {
514
- storedQueue = new ArrayList <>();
515
- }
516
- return storedQueue ;
517
- }
518
-
519
477
void purgeEventsQueue () {
520
478
eventQueue .clear ();
521
- purgeStoredQueue ();
522
- }
523
-
524
- /**
525
- * Delete the stored queue from persistent storage.
526
- */
527
- private void purgeStoredQueue () {
528
- persistObject (new ArrayList <Map <String , Object >>());
529
- }
530
-
531
- /**
532
- * Delete an event from the stored queue.
533
- */
534
- private void expelStoredEvent () {
535
- ArrayList <Map <String , Object >> storedQueue = getStoredQueue ();
536
- storedQueue .remove (0 );
537
- }
538
-
539
- /**
540
- * Persist an object to storage.
541
- *
542
- * @param o Object to store.
543
- */
544
- private void persistObject (Object o ) {
545
- try {
546
- FileOutputStream fos = context .getApplicationContext ().openFileOutput (
547
- STORAGE_KEY ,
548
- android .content .Context .MODE_PRIVATE
549
- );
550
- ObjectOutputStream oos = new ObjectOutputStream (fos );
551
- oos .writeObject (o );
552
- oos .close ();
553
- } catch (Exception ex ) {
554
- PLog ("Exception thrown during queue serialization: %s" , ex .toString ());
555
- }
479
+ localStorageRepository .purgeStoredQueue ();
556
480
}
557
481
558
482
/**
@@ -621,31 +545,14 @@ public int queueSize() {
621
545
* @return The number of events stored in persistent storage.
622
546
*/
623
547
public int storedEventsCount () {
624
- ArrayList <Map <String , Object >> ar = getStoredQueue ();
548
+ ArrayList <Map <String , Object >> ar = localStorageRepository . getStoredQueue ();
625
549
return ar .size ();
626
550
}
627
551
628
- private class QueueManager extends AsyncTask <Void , Void , Void > {
629
- @ Override
630
- protected Void doInBackground (Void ... params ) {
631
- // if event queue is too big, push to persisted storage
632
- if (eventQueue .size () > QUEUE_SIZE_LIMIT ) {
633
- PLog ("Queue size exceeded, expelling oldest event to persistent memory" );
634
- persistQueue ();
635
- eventQueue .remove (0 );
636
- // if persisted storage is too big, expel one
637
- if (storedEventsCount () > STORAGE_SIZE_LIMIT ) {
638
- expelStoredEvent ();
639
- }
640
- }
641
- return null ;
642
- }
643
- }
644
-
645
552
private class FlushQueue extends AsyncTask <Void , Void , Void > {
646
553
@ Override
647
554
protected synchronized Void doInBackground (Void ... params ) {
648
- ArrayList <Map <String , Object >> storedQueue = getStoredQueue ();
555
+ ArrayList <Map <String , Object >> storedQueue = localStorageRepository . getStoredQueue ();
649
556
PLog ("%d events in queue, %d stored events" , eventQueue .size (), storedEventsCount ());
650
557
// in case both queues have been flushed and app quits, don't crash
651
558
if ((eventQueue == null || eventQueue .size () == 0 ) && storedQueue .size () == 0 ) {
0 commit comments