Skip to content

Conversation

@konraddysput
Copy link
Collaborator

This diff shows business logic responsible for event aggregation support in the Backtrace-Unity client.

Information for reviewers:

  • BacktraceClient - class responsible for Backtrace integration in Unity - creates a single instance of BacktraceSession on application startup. Developers can't create more instances than one. BacktraceClient manage BacktraceSession class lifecycle.
  • BacktraceSession allows adding unique (hearthbeat) events and session events.
  • BacktraceSession tick method will be invoked by BacktraceClient every time when Unity Engine calls the update method. In Unity, we prefer to avoid timers and this solution prevents from reserving additional resources for timers, jobs etc.
  • Diffs also contains integration tests and unit tests. If you have more idea about specific use cases for our users that we should also capture in this diff please let me know!

Code information for reviewers:

  • Please focus on the business logic in the code review - for example: Why we remove session events after successful upload?.

This diff contains only code - no technical descriptions, release announcement, readme/changelog changes. We will handle those changes in different diff once when we will be ready to ship all updates that we want to add to 3.5.0 to our customers

@konraddysput konraddysput self-assigned this Apr 21, 2021
Copy link

@ahicks92 ahicks92 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll give this another pass once we have the application launches event in. I didn't check the tests.

{
OnRequestCompleted();
}
else

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On first read, it seems that this doesn't try with backoff.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we're not in API that allows us to use coroutines (mono behavior) we can't, for example, wait for n seconds without blocking the main thread. We shouldn't also use threads because we previously agreed that this will increase resources that backtrace-unity integration consumes and might impact games with a small pc budget. unfortunately, I can't have a better solution for exponential backoff than trying instantly just after the previous request :(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the volume in question, we can't afford for these to spin out if the service goes down. We can wait for @wca to chime in if we want but this will effectively end up DDOSing ourselves one day. if we have to use a thread, then we probably have to use a thread. Maybe we can only do it when automatic submission is enabled?

I see that the interface for requests uses a callback; do we have a way to also do callbacks on timers, e..g JS setTimeout or something?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey. I've moved this code to tick/update method. Tick/Update method will be invoked by Untiy engine every time when unity generates a new frame. So tick method will occur every time when unity will try to render a new frame. With that being said without an additional thread/timer we can use the update method to schedule jobs to be sent by BacktraceSession.

Now I added default timeout which is 10 seconds. Every time when we failed we're waiting at least 10 seconds for the next retry. Also like previously - we're making only 3 requests.

@ahicks92 what do you think about this solution?

Copy link

@rqbacktrace rqbacktrace left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! Just had some minor comments!

Copy link

@ahicks92 ahicks92 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only really reviewed the retry/backoff logic.

const int jitterFraction = 1;
const int backoffBase = 10;
var value = DefaultTimeInSecBetweenRequests * Math.Pow(backoffBase, numberOfRetries);
var retryLower = Math.Max(0, Math.Min(RetryTimeMax, value));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is where you'd want clamp.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved it to our internal helpers - Unity Clamp doesn't support doubles.

var value = DefaultTimeInSecBetweenRequests * Math.Pow(backoffBase, numberOfRetries);
var retryLower = Math.Max(0, Math.Min(RetryTimeMax, value));
var retryUpper = retryLower + retryLower * jitterFraction;
return new System.Random().NextDouble() * (retryUpper - retryLower) + retryLower;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine if we don't have one, but this would be clearer if there were a version of random that took the endpoints of the range, rather than requiring us to scale.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unity uniform function require to use floats. Here we have doubles. So I prefer to stay with this implementation instead of just casting it to floats.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to Internal helpers (like Clamp)

return payload;
}

private double CalculateNextRetryTime(uint numberOfRetries)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd put this closer to send.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved it closer to the Send method.

/// <summary>
/// Force BacktraceSession to Send data to Backtrace
/// </summary>
public void Send()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a fan of how we're doing recursion by overloading a function of the same name 3 times. I'd consider giving these unique names.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about renaming Send method with unique/session events parameter to SendPayload?

{
OnRequestCompleted();
}
else if (statusCode == 503)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a pretty good chance this will be "retry on all 5xx" instead.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

statusCode > 501 && statusCode != 505

else if (statusCode == 503)
{
_numberOfDroppedRequests++;
if (numberOfRetries - 1 != 0)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is where you want your retry counter to go up instead of down. If it did, you can just compare directly to defaultNumberOfRetries after incrementing, and pass directly to CalculateNextRetryTime. it seems like it would be easy to forget whether or not the number of retries is going up or going down, and almost anything interesting you want to do with retry counters needs them to be going up so I'd rather see us standardize on that.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

renamed to attemps and now we're increasing variable (not decreasing it like previously)

@ahicks92
Copy link

Approved pending changing the last place where we're flipping attempts which I discussed on slack.

@konraddysput konraddysput merged commit ea7b5b7 into feature/event-aggregation Apr 30, 2021
@konraddysput konraddysput deleted the feature/event-aggregation-reviewers branch April 30, 2021 13:00
konraddysput added a commit that referenced this pull request May 12, 2021
* Divided commit into two branches for reviewers. Added attribute provider and Backtrace http client for testing purpose.

* Adjusted labels

* Start default event on the application startup + send empty string instead of null

* Event aggregation logic for reviewers (#74)

* Event aggregation logic for reviewers

* Adjusted the most flexible cases

* Code review suggestions

* Default event support

* backoff for session events when request failed

* Retry only on 503

* Exponential backoff

* Avoid casting to float, fixed Math.Pow

* Added Rameez suggestions

* Code review suggestions

* Fixed wrong retry function argument

* line ending fix

* Fixed invalid property name after merge

* Adjusted nullable JSON values

* Create attribute provider dynamically

* Enable attribute provider

* Disable maximum number of events in store from config

* Adjust session aggregation support to spec requirements and meeting suggestions

* Fixed typo

* git attributes for line endings

* Adjust current flow to new requirements + editor changes

* Allow for overriding default unique event

* Added getter and setter for backtracesesion support

* Adjust backtrace session object

* Backtrace session API improvements

* Safe native attribute ios

* Safe native attributes

* Adjusted native build

* Use empty list of classifiers instead of empty string

* Adjusted API

* Adjusted API + Session=>Summed + BacktraceSession=>BacktraceMetrics

* Adjusted API + Session=>Summed + BacktraceSession=>BacktraceMetrics

* Renamed ms to sec
konraddysput added a commit that referenced this pull request Jun 21, 2021
* Divided commit into two branches for reviewers. Added attribute provider and Backtrace http client for testing purpose.

* Adjusted labels

* Start default event on the application startup + send empty string instead of null

* Event aggregation logic for reviewers (#74)

* Event aggregation logic for reviewers

* Adjusted the most flexible cases

* Code review suggestions

* Default event support

* backoff for session events when request failed

* Retry only on 503

* Exponential backoff

* Avoid casting to float, fixed Math.Pow

* Added Rameez suggestions

* Code review suggestions

* Fixed wrong retry function argument

* line ending fix

* Fixed invalid property name after merge

* Adjusted nullable JSON values

* Create attribute provider dynamically

* Enable attribute provider

* Disable maximum number of events in store from config

* Adjust session aggregation support to spec requirements and meeting suggestions

* Fixed typo

* git attributes for line endings

* Adjust current flow to new requirements + editor changes

* Allow for overriding default unique event

* Added getter and setter for backtracesesion support

* Adjust backtrace session object

* Backtrace session API improvements

* Safe native attribute ios

* Safe native attributes

* Adjusted native build

* Use empty list of classifiers instead of empty string

* Adjusted API

* Adjusted API + Session=>Summed + BacktraceSession=>BacktraceMetrics

* Adjusted API + Session=>Summed + BacktraceSession=>BacktraceMetrics

* Renamed ms to sec

* Event aggregation support (#79)

* Divided commit into two branches for reviewers. Added attribute provider and Backtrace http client for testing purpose.

* Adjusted labels

* Start default event on the application startup + send empty string instead of null

* Event aggregation logic for reviewers (#74)

* Event aggregation logic for reviewers

* Adjusted the most flexible cases

* Code review suggestions

* Default event support

* backoff for session events when request failed

* Retry only on 503

* Exponential backoff

* Avoid casting to float, fixed Math.Pow

* Added Rameez suggestions

* Code review suggestions

* Fixed wrong retry function argument

* line ending fix

* Fixed invalid property name after merge

* Adjusted nullable JSON values

* Create attribute provider dynamically

* Enable attribute provider

* Disable maximum number of events in store from config

* Adjust session aggregation support to spec requirements and meeting suggestions

* Fixed typo

* git attributes for line endings

* Adjust current flow to new requirements + editor changes

* Allow for overriding default unique event

* Added getter and setter for backtracesesion support

* Adjust backtrace session object

* Backtrace session API improvements

* Safe native attribute ios

* Safe native attributes

* Adjusted native build

* Use empty list of classifiers instead of empty string

* Adjusted API

* Adjusted API + Session=>Summed + BacktraceSession=>BacktraceMetrics

* Adjusted API + Session=>Summed + BacktraceSession=>BacktraceMetrics

* Renamed ms to sec

* Fixed stucture size (#80)

* Guess native library path when application context is not available (#81)

* Guessing lib path based on the current game directory when the activity is not available

* Code reformat

* Renamed ms to sec

* Handle different unity player java class name (#87)

* Removed warnings generated by Unity2020 + Unity2021 (#85)

* Fixed problem with Unity2021 - symbols upload warnings on the android upload symbols task

* Removed warnings generated by Unity2020

* Fixed compatibility issues

* Formatting

* Metrics support imrovements (#88)

* divided summed/unique events into different queues

* Fully worked unit tests

* adjusted url + json keys

* Code review feedback

* Breadcrumbs support (#83)

* Breadcrumbs support: before database operations cleanup

* Breadcrumbs improvements

* Database adjustements

* Adjusted database code

* Removed try/catch block from function that handles exception and prevent from sending nullable records

* Allow nullable record in SendData method

* Squashed commit of the following:

commit 8c2cec9
Author: kdysput <konrad.dysput@gmail.com>
Date:   Thu May 6 00:00:10 2021 +0200

    Adjusted nullable JSON values

commit 2ed2d7f
Author: kdysput <konrad.dysput@gmail.com>
Date:   Wed May 5 23:55:47 2021 +0200

    Fixed invalid property name after merge

* Undo session aggregation changes

* Create attribute provider dynamically

* Undo maximum number of events

* Undo attribute provider management

* Fixed labels

* Expose enableBreadcrumbs API

* Fixed name

* breadcrumbs tests

* Breadcrumbs unit tests - breadcrumb file tests

* Renamed enums

* Log cleanup tests

* Size consistency test

* Add stack trace attribute only to error/exception logs

* Adjusted native build

* Safe native attributes

* Safe native attribute ios

* Fixed timestamp comparision

* Fixed missing namespace + line endings

* API update + removed two low memory warnings

* breadcrumbs adjustements

* Unit tests that validates navigation and logs events

* Renamed AddBreadcrumb to Log

* Send unique attachments (or include (#n) to attachment name)

* Fixed condition + handling empty nullable files

* Order beadcrumbs

* breadcrumbs support - fixed ios side (delay breadcrumbs startup)

* Removed database checks

* added breadcrumbs.lastId + offline db support

* removed early access flag

* Fixed breadcrumb structure + unit tests

* typos + new lines updates

* Adjusted formating

* Adjusted if statement

* Removed extra line

* COde cleanup - adjustemenets after CR

* Fixed compilation issue

* Don't dispose before checking network status

* Use UTC timestamp

* Removed universe ane token submission URL - allow user to override them (#89)

* fixed line endings

* Editor configuraiton improvements - foldout improvements

* Apply default log file size

* Label change

* Final ios library

* Use copy of attributes

* Fixed reference shared between native client and managed client

* applicaiton.session attribute

* Limit number of events to 50

* Use breadcrumbs as double not long

* Use only one variable to determinate maximum number of elements in queue

* Setting maximum number of events per unique/summed events + breadcrumbId type change

* Getter/Setter api interface improvements

* Breadcrumbs improvements -> changed types + metrics expose maximum number of events + adjust api to new requiremenets

* Unit tests for 502 status code + disabled auto send, long => uint api change, adjusted metrics initialization flow

* Changed breadcurmb type: http => system for internet connection check

* Read application version and name from cache  to add support for background threads

* Block WebGL

* Calculate retry based on the time

* version update

* Update CHANGELOG.md

* Update CHANGELOG.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update CHANGELOG.md

Minor edits

* TOC Update for Breadcrumbs and Crash Free Metrics

* Ignore LogType.Error (#92)

* Ignore errors

* Adjusted comment

* Screenshot management (#91)

* Screenshot management

* Changed default screenshot quality

* Ratio typo

* version bump: preview.2 update

* Adjusted attachments + breadcrumbs support

* Allow overriding default attributes

* Add missing namespace

* Application.session + api adjustements backtrace metrics

* empty json object adjustement

* Windows native dump event aggregation attributes

* Correct unit test namespace

* Convert device attributes to scoped attributes + include native attributes before native integration start

* Breadcrumbs log level tooltip adjustement

* Native upload handler tests

* Version 3.5.0: Version update

* Update README.md

* Update README.md

* Update CHANGELOG.md

* Update README.md

* Label change

Co-authored-by: Vincent Lussenburg <vlussenburg@users.noreply.github.com>
Co-authored-by: jasoncdavis0 <jdavis@backtrace.io>
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 this pull request may close these issues.

4 participants