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

Fix heartbeats interval calculations, add unit tests for the calculator, rewrite to Kotlin #84

Merged
merged 18 commits into from
Oct 27, 2023

Conversation

wzieba
Copy link
Collaborator

@wzieba wzieba commented Oct 26, 2023

Description

This PR fixes the minor off difference when calculating heartbeat intervals (magnitude of up to 900ms). I won't change anything drastically, yet it's better to be in sync with iOS and have a clear implementation, without "hidden casting" issues.

It also covers the calculator with unit tests and changes the calculator implementation to use less error-prone kotlin.time.Duration class to make arithmetical operations between different times.

iOS implementation of this behavior: https://github.com/Parsely/AnalyticsSDK-iOS/blob/b1db4b05dcd5af6feb4710ec30d13fa704305692/Sources/Sampler.swift#L136

wzieba added 15 commits October 26, 2023 11:29
So `UpdateEngagementIntervalCalculator` can be injected with constant value of "now" in tests. Otherwise, the test will be time-sensitive.
UpdateEngagementIntervalCalculator class
Refactor part: interval calculator now uses `kotlin.time.Duration`

Thanks to this change we:
- fix the bugs of unwanted rounding of `double` values to `long`
- makes class easier to work, as we don't have to think about units with all the operation
- makes implementation more similar to iOS, which uses `TimeInterval` (see: https://github.com/Parsely/AnalyticsSDK-iOS/blob/b1db4b05dcd5af6feb4710ec30d13fa704305692/Sources/Sampler.swift#L136)
@codecov
Copy link

codecov bot commented Oct 26, 2023

Codecov Report

Attention: 1 lines in your changes are missing coverage. Please review.

Comparison is base (1caf06f) 42.06% compared to head (7d0fc02) 44.23%.

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #84      +/-   ##
==========================================
+ Coverage   42.06%   44.23%   +2.16%     
==========================================
  Files           7        8       +1     
  Lines         359      364       +5     
  Branches       56       56              
==========================================
+ Hits          151      161      +10     
+ Misses        194      189       -5     
  Partials       14       14              
Files Coverage Δ
.../com/parsely/parselyandroid/EngagementManager.java 69.56% <100.00%> (ø)
...sely/parselyandroid/HeartbeatIntervalCalculator.kt 100.00% <100.00%> (ø)
...ava/com/parsely/parselyandroid/ParselyTracker.java 11.41% <100.00%> (ø)
.../src/main/java/com/parsely/parselyandroid/Clock.kt 50.00% <50.00%> (ø)

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@wzieba wzieba requested a review from ParaskP7 October 26, 2023 13:50
Copy link
Collaborator

@ParaskP7 ParaskP7 left a comment

Choose a reason for hiding this comment

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

👋 @wzieba !

I have reviewed and tested this PR as per the instructions, everything works as expected, great job + Kotlin in production! 🌟 🎉 🌟

import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.seconds

internal open class HeartbeatIntervalCalculator(private val clock: Clock) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

  1. Praise (❤️): Great work on this, I love how this class is now using duration and the x.seconds/minutes/hours approach, much more readable. Also, kudos for fixing the bugs of unwanted rounding (f273ee1)! 🥇

It also covers the calculator with unit tests and changes the calculator implementation to use less error-prone kotlin.time.Duration class to make arithmetical operations between different times.

  1. Suggestion (💡): When converting a Java class to Kotlin (9823815), consider using the Extra commit for .java > .kt renames option while committing this change. This will make it easier for anyone reviewing this change later-on as it will show an actual diffing of files instead of showing the Java file being deleted and a new Kotlin file being added.

image

FYI: For more context on check this discussion I had with an external contributor a while back. Let me know your thoughts. 🙏

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks for sharing about Extra commit option, TIL!

companion object {
const val BACKOFF_PROPORTION = 0.3
val OFFSET_MATCHING_BASE_INTERVAL = 35.seconds
val MAX_TIME_BETWEEN_HEARTBEATS = 15.minutes
Copy link
Collaborator

Choose a reason for hiding this comment

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

This PR fixes the minor off difference when calculating heartbeat intervals (magnitude of up to 900ms). I won't change anything drastically, yet it's better to be in sync with iOS and have a clear implementation, without "hidden casting" issues.

👍

}

class FakeClock : Clock() {
var fakeNow = Duration.ZERO
Copy link
Collaborator

Choose a reason for hiding this comment

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

Praise (❤️): Nice!

// surpass MAX_TIME_BETWEEN_HEARTBEATS
// (currentTime + offset) * backoff = max
// currentTime = (max / backoff) - offset, so
// (15 minutes / 0.3) - 35 seconds = 2965 seconds. Add 1 second to be over the limit
Copy link
Collaborator

Choose a reason for hiding this comment

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

Praise (❤️): Thanks for adding these comments and making it clear how these numbers are calculated. 🙇

@wzieba wzieba merged commit 2bec4fe into main Oct 27, 2023
3 checks passed
@wzieba wzieba deleted the engagment_interval_calculator_tests branch October 27, 2023 10:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants