import net.pterodactylus.sone.database.PostBuilder
import net.pterodactylus.sone.database.PostDatabase
import net.pterodactylus.sone.database.PostReplyBuilder
-import net.pterodactylus.sone.utils.unit
+import net.pterodactylus.sone.utils.*
import net.pterodactylus.util.config.Configuration
import net.pterodactylus.util.config.ConfigurationException
import java.util.concurrent.locks.ReentrantReadWriteLock
private val memoryBookmarkDatabase = MemoryBookmarkDatabase(this, configurationLoader)
private val memoryFriendDatabase = MemoryFriendDatabase(configurationLoader)
private val saveRateLimiter: RateLimiter = RateLimiter.create(1.0)
+ private val saveKnownPostsRateLimiter: RateLimiter = RateLimiter.create(1.0)
+ private val saveKnownPostRepliesRateLimiter: RateLimiter = RateLimiter.create(1.0)
override val soneLoader get() = this::getSone
}
private fun saveKnownPosts() =
- try {
- readLock.withLock {
- knownPosts.forEachIndexed { index, knownPostId ->
- configuration.getStringValue("KnownPosts/$index/ID").value = knownPostId
+ saveKnownPostsRateLimiter.tryAcquire().ifTrue {
+ try {
+ readLock.withLock {
+ knownPosts.forEachIndexed { index, knownPostId ->
+ configuration.getStringValue("KnownPosts/$index/ID").value = knownPostId
+ }
+ configuration.getStringValue("KnownPosts/${knownPosts.size}/ID").value = null
}
- configuration.getStringValue("KnownPosts/${knownPosts.size}/ID").value = null
+ } catch (ce1: ConfigurationException) {
+ throw DatabaseException("Could not save database.", ce1)
}
- } catch (ce1: ConfigurationException) {
- throw DatabaseException("Could not save database.", ce1)
}
private fun loadKnownPostReplies(): Unit =
}
private fun saveKnownPostReplies() =
- try {
- readLock.withLock {
- knownPostReplies.forEachIndexed { index, knownPostReply ->
- configuration.getStringValue("KnownReplies/$index/ID").value = knownPostReply
+ saveKnownPostRepliesRateLimiter.tryAcquire().ifTrue {
+ try {
+ readLock.withLock {
+ knownPostReplies.forEachIndexed { index, knownPostReply ->
+ configuration.getStringValue("KnownReplies/$index/ID").value = knownPostReply
+ }
+ configuration.getStringValue("KnownReplies/${knownPostReplies.size}/ID").value = null
}
- configuration.getStringValue("KnownReplies/${knownPostReplies.size}/ID").value = null
+ } catch (ce1: ConfigurationException) {
+ throw DatabaseException("Could not save database.", ce1)
}
- } catch (ce1: ConfigurationException) {
- throw DatabaseException("Could not save database.", ce1)
}
}
verify(configuration.getStringValue("KnownPosts/0/ID"), times(1)).value = null
}
+ @Test
+ @Dirty("the rate limiter should be mocked")
+ fun `setting posts as knows twice in a row only saves the database once`() {
+ prepareConfigurationValues()
+ val post = mock<Post>()
+ whenever(post.id).thenReturn("post-id")
+ memoryDatabase.setPostKnown(post, true)
+ memoryDatabase.setPostKnown(post, true)
+ verify(configuration, times(1)).getStringValue("KnownPosts/1/ID")
+ }
+
+ @Test
+ @Dirty("the rate limiter should be mocked")
+ fun `setting post replies as knows twice in a row only saves the database once`() {
+ prepareConfigurationValues()
+ val postReply = mock<PostReply>()
+ whenever(postReply.id).thenReturn("post-reply-id")
+ memoryDatabase.setPostReplyKnown(postReply, true)
+ memoryDatabase.setPostReplyKnown(postReply, true)
+ verify(configuration, times(1)).getStringValue("KnownReplies/1/ID")
+ }
+
}
private const val SONE_ID = "sone"