Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The tracking stops working after a burst of user interactions #156

Closed
mr-mmmmore opened this issue Mar 24, 2021 · 4 comments · Fixed by #157
Closed

The tracking stops working after a burst of user interactions #156

mr-mmmmore opened this issue Mar 24, 2021 · 4 comments · Fixed by #157

Comments

@mr-mmmmore
Copy link

Interacting quickly with ui elements that trigger some tracking causes the package to stop working.

This comes from the ThrottlingBucket.removeDrop() method that always returns false after a "successful" burst of requests, which prevents any subsequent attempt to send a payload to GA. The ThrottlingBucket class doesn't recover from this burst: the number of drops remains forever negative.

The problem appeared while I was navigating rather fast in my app, but at a speed similar to a real life situation. And I am only tracking screen views at the moment, so this problem might occur more frequently when the app tracks screen views, events, exceptions, etc. and the stress on the throttling bucket increases.

I have narrowed it down to the throttling bucket by adding a break point to the else part of the _sendPayload method:

Future _sendPayload(String hitType, Map<String, dynamic> args) {
   if (!enabled) return Future.value();

   if (_bucket.removeDrop()) {
     _variableMap.forEach((key, value) {
       args[key] = value;
     });

     args['v'] = '1'; // protocol version
     args['tid'] = trackingId;
     args['cid'] = clientId;
     args['t'] = hitType;

     _sendController.add(args);

     return _recordFuture(postHandler.sendPost(_url, args));
   } else {
     return Future.value(); // <========= BREAK POINT HERE
   }
 }

The app never stops there, until the burst of interaction succeeds in messing the throttling, then any subsequent attempt to track stops there, which I think proves the number of drops stays negative.

@devoncarew
Copy link
Member

In the usage_impl.dart file, can you confirm the behavior in the _checkReplenish() method? We should be incrementing the drop count in that method.

@mr-mmmmore
Copy link
Author

What do you want me to test about this method? I am not sure how exactly it's supposed to work.

But I am wondering why this throttling is being used here: is it to prevent bursts in bandwidth use on the device? The problem is that the hits are lost with this algorithm if the bucket is full, isn't it?

There might be some bursts, but usually right after that there are no requests anymore, so ideally the hits that haven't been sent because of the throttling could be send later.

@mr-mmmmore
Copy link
Author

Hi @devoncarew, can you please tell me what you want me to check in the _checkReplenish() method? That the drops get incremented?

I am wondering about this test: if (_lastReplenish + 1000 >= now), shouldn't it be <=? At the moment the boolean test will be false anytime later than _lastReplenish + 1 second, so there are no chances that the drops get incremented past this delay, which could explain the problem I am encoutering: if the drops get negative because of a burst, but then the next call occurs more than 1 second later, the bucket get stucked.

@devoncarew
Copy link
Member

@mr-mmmmore - thanks for the report. After looking at it, it does look like you've found an issue. I have #157 with a fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants