Skip to content

Conversation

@bryanatkinson
Copy link
Contributor

Created a SessionLifecycleService class which contains all the service-side code, and a SessionLifecycleClient object which handles the connection to the server and the sending and receiving of events.

Also added documentation to the code.

@google-oss-bot
Copy link
Contributor

1 Warning
⚠️ Did you forget to add a changelog entry? (Add the 'no-changelog' label to the PR to silence this warning.)

Generated by 🚫 Danger

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Oct 12, 2023

Coverage Report 1

Affected Products

  • firebase-sessions

    Overall coverage changed from ? (8e2255c) to 59.90% (c96707f) by ?.

    27 individual files with coverage change

    FilenameBase (8e2255c)Merge (c96707f)Diff
    ApplicationInfo.kt?100.00%?
    AutoSessionEventEncoder.java?100.00%?
    Comparisons.kt?0.00%?
    Emitters.kt?0.00%?
    EventGDTLogger.kt?75.00%?
    FirebaseSessions.kt?0.00%?
    FirebaseSessionsDependencies.kt?91.30%?
    FirebaseSessionsRegistrar.kt?78.13%?
    LocalOverrideSettings.kt?100.00%?
    RemoteSettings.kt?88.06%?
    RemoteSettingsFetcher.kt?65.85%?
    SafeCollector.common.kt?0.00%?
    SessionCoordinator.kt?75.00%?
    SessionDatastore.kt?0.00%?
    SessionEvent.kt?100.00%?
    SessionEvents.kt?97.78%?
    SessionGenerator.kt?91.67%?
    SessionInitiateListener.kt?0.00%?
    SessionInitiator.kt?74.19%?
    SessionLifecycleClient.kt?0.00%?
    SessionLifecycleService.kt?0.00%?
    SessionMaintainer.kt?0.00%?
    SessionsSettings.kt?70.45%?
    SessionSubscriber.kt?75.00%?
    SettingsCache.kt?94.83%?
    SettingsProvider.kt?50.00%?
    Time.kt?0.00%?

Test Logs

  1. https://storage.googleapis.com/firebase-sdk-metric-reports/daUUqJGLxC.html

@github-actions
Copy link
Contributor

github-actions bot commented Oct 12, 2023

Unit Test Results

     83 files       83 suites   2m 44s ⏱️
1 044 tests 1 043 ✔️ 0 💤 1
1 113 runs  1 112 ✔️ 0 💤 1

For more details on these failures, see this check.

Results for commit cf2726d.

♻️ This comment has been updated with latest results.

@google-oss-bot
Copy link
Contributor

The public api surface has changed for the subproject firebase-sessions:
error: Added class com.google.firebase.sessions.SessionDatastoreKt [AddedClass]
error: Added class com.google.firebase.sessions.SessionLifecycleClient [AddedClass]

Please update the api.txt files for the subprojects being affected by this change by running ./gradlew ${subproject}:generateApiTxtFile. Also perform a major/minor bump accordingly.

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Oct 12, 2023

Size Report 1

Affected Products

  • base

    TypeBase (8e2255c)Merge (c96707f)Diff
    apk (aggressive)?8.39 kB? (?)
    apk (release)?8.66 kB? (?)
  • firebase-installations

    TypeBase (8e2255c)Merge (c96707f)Diff
    aar?58.8 kB? (?)
    apk (aggressive)?127 kB? (?)
    apk (release)?1.67 MB? (?)
  • firebase-installations-interop

    TypeBase (8e2255c)Merge (c96707f)Diff
    aar?8.17 kB? (?)
    apk (aggressive)?65.2 kB? (?)
    apk (release)?652 kB? (?)
  • firebase-sessions

    TypeBase (8e2255c)Merge (c96707f)Diff
    aar?139 kB? (?)
    apk (aggressive)?366 kB? (?)
    apk (release)?2.08 MB? (?)

Test Logs

  1. https://storage.googleapis.com/firebase-sdk-metric-reports/A4wUf3nggC.html


private var service: Messenger? = null
private var serviceBound: Boolean = false
private val queuedMessages = LinkedList<Message>()
Copy link
Contributor

Choose a reason for hiding this comment

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

does this need to be thread-safe?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated to use LinkedBlockingDeque

* whether or not this foregrounding event should result in a new session being generated.
*/
fun foregrounded(activity: Activity): Unit {
sendLifecycleEvent(SessionLifecycleService.FOREGROUNDED)
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm almost certain this isn't thread-safe.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated to use LinkedBlockingDeque

* Queues the given [Message] up for delivery to the [SessionLifecycleService] once the connection
* is established.
*/
private fun queueMessage(msg: Message) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This isn't thread-safe and I think it needs to be. Removing the oldest messages is certainly the most correct thing to do, but I think it isn't terrible to simply drop the current message in this case. If you're comfortable with this, then usingLinkedBlockingQueue::offer would work beautifully here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated to use LinkedBlockingDeque. I still try to shrink the queue before calling ::offer. It's still possible the offer fails if some other thread adds the latest, but IMO it's still worth try to clean the oldest first.

private fun sendLifecycleEvent(msg: Message) {
if (service != null) {
try {
service?.send(msg)
Copy link
Contributor

Choose a reason for hiding this comment

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

If this succeeds, then why not drain the queue here as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated to always try to drain the latest messages on send.

…es and only sends the latest BACKGROUND and FOREGROUND messages to the server when draining. Also draining the queue on every send in the event of a previous failure.
@google-oss-bot
Copy link
Contributor

The public api surface has changed for the subproject firebase-sessions:
error: Added class com.google.firebase.sessions.SessionDatastoreKt [AddedClass]
error: Added class com.google.firebase.sessions.SessionLifecycleClient [AddedClass]

Please update the api.txt files for the subprojects being affected by this change by running ./gradlew ${subproject}:generateApiTxtFile. Also perform a major/minor bump accordingly.

*/
private fun sendLifecycleEvent(messageCode: Int) {
val allMessages = ArrayList<Message>()
queuedMessages.drainTo(allMessages)
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe this line and the line above could be extracted to a method drainQueuedToNewList()? You do it a couple of times.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

*/
private fun queueMessage(msg: Message) {
Log.i(TAG, "Queueing message ${msg.what}")
while (queuedMessages.size >= MAX_QUEUED_MESSAGES) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This isn't really thread-safe (two threads could be doing this at the same time with unpredictable results). Though it's probably okay, we can also probably live without it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed.

// Note: it is possible this still fails to insert if another thread inserts in the meantime.
// However this indicates that many lifecycle events are ocurring and so a missed message is
// very unlikely to result in a missed session.
queuedMessages.offer(msg)
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe log the result (true if success, false if full)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done


private val boundClients = mutableListOf<Messenger>()
private var curSessionId: String? = null
private var isAppInForeground: Boolean = false
Copy link
Contributor

Choose a reason for hiding this comment

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

Didn't we agree that this could be dropped?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@google-oss-bot
Copy link
Contributor

The public api surface has changed for the subproject firebase-sessions:
error: Added class com.google.firebase.sessions.SessionDatastoreKt [AddedClass]
error: Added class com.google.firebase.sessions.SessionLifecycleClient [AddedClass]

Please update the api.txt files for the subprojects being affected by this change by running ./gradlew ${subproject}:generateApiTxtFile. Also perform a major/minor bump accordingly.

@google-oss-bot
Copy link
Contributor

The public api surface has changed for the subproject firebase-sessions:
error: Added class com.google.firebase.sessions.SessionDatastoreKt [AddedClass]

Please update the api.txt files for the subprojects being affected by this change by running ./gradlew ${subproject}:generateApiTxtFile. Also perform a major/minor bump accordingly.

}
)
} catch (e: Exception) {
if (e is DeadObjectException) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not catch DeadObjectException and then catch Exception ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@google-oss-bot
Copy link
Contributor

The public api surface has changed for the subproject firebase-sessions:
error: Added class com.google.firebase.sessions.SessionDatastoreKt [AddedClass]

Please update the api.txt files for the subprojects being affected by this change by running ./gradlew ${subproject}:generateApiTxtFile. Also perform a major/minor bump accordingly.

@google-oss-bot
Copy link
Contributor

The public api surface has changed for the subproject firebase-sessions:
error: Added class com.google.firebase.sessions.SessionDatastoreKt [AddedClass]

Please update the api.txt files for the subprojects being affected by this change by running ./gradlew ${subproject}:generateApiTxtFile. Also perform a major/minor bump accordingly.

@bryanatkinson bryanatkinson merged commit c7e23f6 into sessions-nine Oct 12, 2023
@bryanatkinson bryanatkinson deleted the sessions-service-split branch October 12, 2023 17:47
@firebase firebase locked and limited conversation to collaborators Nov 12, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants