RUM-5182: Add precheck conditions when registering session replay feature#2264
Conversation
2072869 to
7ebd002
Compare
7ebd002 to
4275f94
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## feature/sr-dynamic-optimisation #2264 +/- ##
===================================================================
+ Coverage 70.09% 70.10% +0.01%
===================================================================
Files 731 734 +3
Lines 27241 27328 +87
Branches 4598 4609 +11
===================================================================
+ Hits 19092 19156 +64
- Misses 6845 6870 +25
+ Partials 1304 1302 -2
|
4275f94 to
a17dc90
Compare
6792490 to
d57126f
Compare
d57126f to
d15d780
Compare
de30f0a to
3ed945f
Compare
|
@0xnm @jonathanmos I just refactored the PR, please review it again if you want, main changes:
|
6669428 to
6cc73ca
Compare
6cc73ca to
281cb42
Compare
355b137 to
c089683
Compare
|
I applied the @0xnm 's change in my branch, please check again, thanks! |
| companion object | ||
| val DEFAULT: SystemRequirementConfiguration | ||
| val NONE: SystemRequirementConfiguration |
There was a problem hiding this comment.
should these be exposed to the user? what is the case for using NONE on the client-side - always enable Session Replay?
There was a problem hiding this comment.
Yes, I think we need to provide an option to the client that session replay can be enabled in any case without checking any system requirements.
| private var textAndInputPrivacy = TextAndInputPrivacy.MASK_ALL | ||
| private var extensionSupport: ExtensionSupport = NoOpExtensionSupport() | ||
| private var dynamicOptimizationEnabled = true | ||
| private var systemRequirementConfiguration = SystemRequirementConfiguration.NONE |
There was a problem hiding this comment.
shouldn't it be DEFAULT? because the default value for the default Session Replay configuration is NONE, while DEFAULT also exists.
There was a problem hiding this comment.
Well, from my point of view of product design, I assume that at the beginning, most of user will not be aware of the existence of this API, in this case should we add a default limiter to disable the session replay? with this concern I use NONE as the default configuration, for the client who is aware of this API, they can use DEFAULT one to setup manually.
There was a problem hiding this comment.
my point is that default is not called DEFAULT, but NONE, but I see that it is for the backward compatibility
There was a problem hiding this comment.
You are right, but I wonder what name we should give to them, let's check the opinion of the other reviewers.
There was a problem hiding this comment.
Note
I share @0xnm 's concern, mostly in term of naming.
The default value is NONE, so maybe the other value could be BASIC. Another option could be to use a naming similar to Facebook's device-year-class library. That lib would categorize the device with the year when devices with the same capabilities were most popular. E.g.: it would tell you that a low-end phone purchased today is equivalent to a 2018 standard phone.
Our "default" setting (minCPUCores = 2, minRAMSizeMb = 1024) looks like a 2011 phone specs.
d00334f to
277ad5a
Compare
0xnm
left a comment
There was a problem hiding this comment.
I think this one mostly lgtm, but I would like to have another pair of eyes having a fresh look here, especially on the public API changes.
@xgouchet or @mariusc83 can you please take a look?
| private var textAndInputPrivacy = TextAndInputPrivacy.MASK_ALL | ||
| private var extensionSupport: ExtensionSupport = NoOpExtensionSupport() | ||
| private var dynamicOptimizationEnabled = true | ||
| private var systemRequirementConfiguration = SystemRequirementConfiguration.NONE |
There was a problem hiding this comment.
my point is that default is not called DEFAULT, but NONE, but I see that it is for the backward compatibility
a9cd682 to
72d14db
Compare
| private var textAndInputPrivacy = TextAndInputPrivacy.MASK_ALL | ||
| private var extensionSupport: ExtensionSupport = NoOpExtensionSupport() | ||
| private var dynamicOptimizationEnabled = true | ||
| private var systemRequirementConfiguration = SystemRequirementConfiguration.NONE |
There was a problem hiding this comment.
Note
I share @0xnm 's concern, mostly in term of naming.
The default value is NONE, so maybe the other value could be BASIC. Another option could be to use a naming similar to Facebook's device-year-class library. That lib would categorize the device with the year when devices with the same capabilities were most popular. E.g.: it would tell you that a low-end phone purchased today is equivalent to a 2018 standard phone.
Our "default" setting (minCPUCores = 2, minRAMSizeMb = 1024) looks like a 2011 phone specs.
| /** | ||
| * Defines the minimum system requirements for enabling the Session Replay feature. | ||
| * When [SessionReplay.enable] is invoked, the system configuration is verified against these requirements. | ||
| * If the system meets the specified criteria, Session Replay will be successfully enabled. |
There was a problem hiding this comment.
Note
We should add in the kdoc here that by default, we do not have any minimum requirements and Session Replay will be applied to all devices
There was a problem hiding this comment.
@xgouchet Should our approach not be to optimize performance by default (including not running by default on weak devices), but give users a way to opt-out of our optimizations? If so, the default precheck would be applied for all users with the caveat that they can turn it off with the flag that we've provided in the configuration.
There was a problem hiding this comment.
@jonathanmos as we discussed with @MaelNamNam before, this precheck should not be covered by the flag of the dynamic optimisation, they should be different API to enable/disable. I think we can keep it disable by default, I will add doc to elaborate
| val checkers = listOf( | ||
| CPURequirementChecker(minCPUCores, internalLogger = internalLogger), | ||
| MemoryRequirementChecker(minRAMSizeMb, internalLogger = internalLogger) | ||
| ) | ||
| (sdkCore as InternalSdkCore).getPersistenceExecutorService().submitSafe(OPERATION_NAME, internalLogger) { | ||
| val checkResult = checkers.all { | ||
| it.checkMinimumRequirement() | ||
| } |
There was a problem hiding this comment.
Warning
So I have a bit of a concern here. Right now it's not a problem, but it could become one eventually.
We create a new Checker instance and perform the checks every time we call the runIfMeetRequirements() method. The thing is that the cpu and ram size will never change on a given device, meaning we could memoize the result of the check for the current session and ensure we don't perform the check on every call. Not necessary for this PR but we should probably add a task for this.
There was a problem hiding this comment.
I see the point here, so the way of memorising it for me is to persist result in shared preference or a file, but I may wonder if this solution will have the same effect with the current one because current checkers actually just read files. So the difference of two solutions is just the file that they are reading if I am not wrong?
There was a problem hiding this comment.
Well, I was more thinking on an in memory check (technically some device coud have a Ram upgrade, or we could have some different checks in the future), to limit the check to once per app run.
In the current use case (the SystemRequirementConfiguration class being only used in one place) it wouldn't change anything, as I said, which is why just keeping a Jira task (and maybe a TODO comment in the class) is enough for now
b52034f
b52034f to
24d1af6
Compare
0xnm
left a comment
There was a problem hiding this comment.
Lgtm. I left a few suggestions, but nothing blocking.
24d1af6 to
70b09b1
Compare
What does this PR do?
SystemRequirementConfigurationclass to contain requirements to checkSystemRequirementCheckerto check if every condition can be met:MemoryRequirementCheckerimplementation to check max RAM sizeCpuRequirementCheckerimplementation to check cpu cores numberSessionReplayRequirementclass to useSystemRequirementConfigurationand all the checkers to determine if the task can be executed after checking the conditions.Motivation
RUN-5182
Review checklist (to be filled by reviewers)