Conversation
WalkthroughAdds an internal SessionService and a new ClixConfig.sessionTimeoutMs; Clix.initialize now constructs and starts SessionService and stores it on Changes
Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
No actionable comments were generated in the recent review. 🎉 🧹 Recent nitpick comments
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6e9c3fd758
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
clix/src/main/kotlin/so/clix/core/Clix.kt (1)
1-1:⚠️ Potential issue | 🟡 MinorPipeline failure: ktfmt formatting check failed for this file.
The CI reports this file is not properly formatted. Please run
ktfmtto fix formatting before merging.
🤖 Fix all issues with AI agents
In `@clix/src/main/kotlin/so/clix/core/ClixConfig.kt`:
- Line 22: Add a `@property` entry for sessionTimeoutMs to the ClixConfig KDoc
explaining that sessionTimeoutMs is the session timeout in milliseconds used to
end idle sessions, state the default value (30_000 ms) and document the minimum
enforced value as implemented by ClixConfig (refer to the validation or init
logic that enforces the minimum) so readers know the lower bound and default.
In `@clix/src/main/kotlin/so/clix/services/SessionService.kt`:
- Line 1: The file with the package declaration "package so.clix.services"
failed ktfmt formatting; run the project's ktfmt formatter (e.g., ktfmt -w on
the file or the project's gradle task such as ./gradlew ktfmtFormat) to reformat
the file, verify there are no ktfmt violations, and commit the formatted changes
so the CI formatting check passes.
- Around line 29-54: The session continuation/check logic in start() and
onStart() is duplicated and can cause duplicate SESSION_START when addObserver
synchronously triggers onStart(); extract the shared logic into a single private
helper (e.g., ensureSessionOrStart or checkOrStartSession) that performs the
LAST_ACTIVITY_KEY read, elapsed check, updateLastActivity(), and
startNewSession(); then modify start() to only call
ProcessLifecycleOwner.get().lifecycle.addObserver(this) (no session check) and
call the new helper from onStart(), removing the duplicated block from start(),
ensuring startNewSession() can only be invoked once per lifecycle transition.
🧹 Nitpick comments (4)
clix/src/main/kotlin/so/clix/services/SessionService.kt (2)
69-69:Clix.coroutineScopecreates tight coupling to the singleton.Referencing
Clix.coroutineScopedirectly insideSessionServiceviolates the dependency-injection principle and makes this class harder to test. Inject theCoroutineScopeas a constructor parameter instead.Proposed fix
internal class SessionService( private val storageService: StorageService, private val eventService: EventService, sessionTimeoutMs: Int, + private val coroutineScope: CoroutineScope, ) : DefaultLifecycleObserver {Then replace
Clix.coroutineScope.launchwithcoroutineScope.launch.Based on learnings: "Do not use service locators or singletons (unless absolutely necessary)".
26-27:@Volatilealone is insufficient ifpendingMessageIdis read/cleared from a coroutine while set from the main thread.
setPendingMessageIdis called from the UI thread (NotificationTappedActivity), whilestartNewSessionreads and clears it potentially from the same main thread (lifecycle callback). In this specific flow both happen on the main thread, so@Volatileis sufficient. However, if the coroutine on line 69 or any future caller invokes this from a background thread, the read-then-clear on lines 65-66 is not atomic. Consider usingAtomicReferencewithgetAndSet(null)to be safe, or document the threading contract.clix/src/main/kotlin/so/clix/core/Clix.kt (2)
86-87:sessionService?.start()— safe-call is unnecessary immediately after assignment.Line 86 assigns a non-null
SessionServiceinstance, so line 87's?.is redundant. UsesessionService!!.start()or, better, a local val:Proposed fix
- sessionService = SessionService(storageService, eventService, config.sessionTimeoutMs) - sessionService?.start() + val session = SessionService(storageService, eventService, config.sessionTimeoutMs) + sessionService = session + session.start()
86-87:SessionService.start()registers aProcessLifecycleOwnerobserver, which requires the main thread.The
initializemethod is documented to be called fromApplication.onCreate()(main thread), but there's no runtime assertion. If a caller ever invokesinitializefrom a background thread,addObservercould throw or behave unexpectedly. Consider adding a main-thread check or documenting this requirement explicitly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
pitzcarraldo
left a comment
There was a problem hiding this comment.
lgtm. please just check the comments left by review bots.
Summary
SessionServicethat tracksSESSION_STARTevents based on app lifecycle (ProcessLifecycleOwner) with configurable timeoutsessionTimeoutMstoClixConfig(default: 30s, minimum: 5s)pendingMessageIdon push notification tap so the subsequentSESSION_STARTevent includes themessageIdChanges
clix/src/main/kotlin/so/clix/services/SessionService.kt— session timeout logic,ProcessLifecycleOwnerobserver,SessionEventenumclix/src/main/kotlin/so/clix/core/Clix.kt— initialize and startSessionServiceclix/src/main/kotlin/so/clix/core/ClixConfig.kt— addsessionTimeoutMspropertyclix/src/main/kotlin/so/clix/notification/NotificationTappedActivity.kt— callsetPendingMessageIdon notification tapSpec
Summary by CodeRabbit