Skip to content

Reappearing notifications on slow homeservers #4238

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

Merged
merged 6 commits into from
Oct 14, 2021

Conversation

ouchadam
Copy link
Contributor

@ouchadam ouchadam commented Oct 13, 2021

Fixes #3437 - reappearing notifications after dismissing

Adds a in memory cache for keeping track of notification events we've already seen, this allows us to skip displaying already dismissed events received by the push flow which the /sync response then returns at a later point.

The cache is a simple circular buffer of 25 event ids to avoid us tracking every single event over the lifetime of the application. The cache size is a finger in the air estimate, could many users receive and dismiss 25+ push notifications before a sync response completes 🤔

*with a forced 5 second delay when syncing

BEFORE AFTER
before-delayed-sync after-delayed-sync

The gif isn't very exciting, basically the after shows the notification no longer reappearing after dismissing

…es causing already dismissed notifications from being shown again

- uses a simple circular buffer to limit the memory usage
@github-actions
Copy link

github-actions bot commented Oct 13, 2021

Unit Test Results

  48 files  +  4    48 suites  +4   50s ⏱️ +2s
  91 tests +  4    91 ✔️ +  4  0 💤 ±0  0 ±0 
244 runs  +16  244 ✔️ +16  0 💤 ±0  0 ±0 

Results for commit fc793c4. ± Comparison against base commit 7ec0872.

♻️ This comment has been updated with latest results.

Copy link
Member

@bmarty bmarty left a comment

Choose a reason for hiding this comment

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

LGTM, just one small remark and one suggestion that you must feel free to just ignore :)

cache[writeIndex] = key
writeIndex++
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Thinking of a small rework, also more generic, but with the disadvantage of exposing the whole MutableList API...

/**
 * A FIFO circular buffer of elements
 */
class CircularCache<T>(cacheSize: Int) : MutableList<T> by ArrayList(cacheSize) {
    private var writeIndex = 0

    override fun add(element: T): Boolean {
        if (writeIndex == size - 1) {
            writeIndex = 0
        }
        set(writeIndex, element)
        writeIndex++
        return true
    }
}

You decide if it's better

Copy link
Member

Choose a reason for hiding this comment

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

set(writeIndex, element) may crash (not tested)

Copy link
Member

Choose a reason for hiding this comment

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

Also maybe add as a comment that this is not thread safe (I think)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  • 👍 for switching to a List, I originally chose Array to try and be as memory efficient as possible (as List will auto resize when it gets close to the capacity) but List allows it to be generic

  • I'd prefer to avoid exposing the List to avoid it being used in unexpected ways

  • 👍 will document the class as not being 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.

ended up going back to using an Array, a list means we have to handle prefilling or add/remove logic

// we've already seen the event, lets' skip
Timber.d("onNotifiableEventReceived(): skipping event, already seen}")
} else {
// Not an edit
Copy link
Member

Choose a reason for hiding this comment

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

This comment refer to the first if so should be moved above this new if

Copy link
Member

Choose a reason for hiding this comment

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

Sorry if it wasn't clear. I would like to have:

                    // Not an edit
                    if (seenEventIds.contains(notifiableEvent.eventId)) {
                         // we've already seen the event, lets skip
                        Timber.d("onNotifiableEventReceived(): skipping event, already seen")
                    } else {
                        seenEventIds.put(notifiableEvent.eventId)
                        eventList.add(notifiableEvent)
                    }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ah 🤦 will do 👍

eventList.add(notifiableEvent)
if (seenEventIds.contains(notifiableEvent.eventId)) {
// we've already seen the event, lets' skip
Timber.d("onNotifiableEventReceived(): skipping event, already seen}")
Copy link
Member

Choose a reason for hiding this comment

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

Ah, small } at the end of the String

@ouchadam ouchadam force-pushed the feature/adm/delayed-sync-duplicated-notification branch from 73d0ebd to 926a123 Compare October 14, 2021 12:45
import org.amshove.kluent.shouldBeEqualTo
import org.junit.Test

class CircularCacheTest {
Copy link
Member

Choose a reason for hiding this comment

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

💯 for adding tests!

@ouchadam ouchadam force-pushed the feature/adm/delayed-sync-duplicated-notification branch from 926a123 to fc793c4 Compare October 14, 2021 13:02
Copy link
Member

@bmarty bmarty left a comment

Choose a reason for hiding this comment

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

Thanks for the update!

@bmarty bmarty merged commit a208732 into develop Oct 14, 2021
@bmarty bmarty deleted the feature/adm/delayed-sync-duplicated-notification branch October 14, 2021 15:01
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.

Push notifications are repeated if the sync takes too long
2 participants