From 0f5eba1ebee1e818a0b540f23bbbebb090917567 Mon Sep 17 00:00:00 2001 From: xis Date: Sun, 15 Oct 2023 18:01:23 +0200 Subject: [PATCH] content tree rebuilding ifcheck fix --- .../nextcloud/content/ContentTreeProvider.kt | 22 ++++---- .../schowek/nextclouddlna/util/ClockConfig.kt | 13 +++++ .../content/ContentTreeProviderTest.groovy | 53 +++++++++++++++++++ 3 files changed, 79 insertions(+), 9 deletions(-) create mode 100644 src/main/kotlin/net/schowek/nextclouddlna/util/ClockConfig.kt create mode 100644 src/test/groovy/net/schowek/nextclouddlna/nextcloud/content/ContentTreeProviderTest.groovy diff --git a/src/main/kotlin/net/schowek/nextclouddlna/nextcloud/content/ContentTreeProvider.kt b/src/main/kotlin/net/schowek/nextclouddlna/nextcloud/content/ContentTreeProvider.kt index 48f223d..88ec872 100644 --- a/src/main/kotlin/net/schowek/nextclouddlna/nextcloud/content/ContentTreeProvider.kt +++ b/src/main/kotlin/net/schowek/nextclouddlna/nextcloud/content/ContentTreeProvider.kt @@ -4,6 +4,7 @@ import mu.KLogging import net.schowek.nextclouddlna.nextcloud.NextcloudDB import org.springframework.scheduling.annotation.Scheduled import org.springframework.stereotype.Component +import java.time.Clock import java.time.Instant import java.util.concurrent.atomic.AtomicInteger import java.util.regex.Pattern @@ -11,27 +12,30 @@ import java.util.regex.Pattern @Component class ContentTreeProvider( - private val nextcloudDB: NextcloudDB + private val nextcloudDB: NextcloudDB, + private val clock: Clock ) { private var tree = buildContentTree() - private var lastMTime = 0L + var lastMTime = 0L @Scheduled(fixedDelay = REBUILD_TREE_DELAY_IN_MS, initialDelay = REBUILD_TREE_INIT_DELAY_IN_MS) - final fun rebuildTree() { - rebuildTree(false) + final fun rebuildTree(): Boolean { + return rebuildTree(false) } - final fun rebuildTree(force: Boolean) { + final fun rebuildTree(force: Boolean): Boolean { val maxMtime: Long = nextcloudDB.maxMtime() - val now = Instant.now().epochSecond - if (force || lastMTime < maxMtime || lastMTime + MAX_REBUILD_OFFSET_IN_S > now) { + val now = Instant.now(clock).epochSecond + val rebuild = force || lastMTime < maxMtime || lastMTime + MAX_REBUILD_OFFSET_IN_S < now + if (rebuild) { logger.info("ContentTree seems to be outdated - Loading...") this.tree = buildContentTree() - lastMTime = maxMtime + lastMTime = Instant.now().epochSecond } + return rebuild } - private fun buildContentTree(): ContentTree { + private final fun buildContentTree(): ContentTree { val tree = ContentTree() val root = ContentNode(0, -1, "ROOT") tree.addNode(root) diff --git a/src/main/kotlin/net/schowek/nextclouddlna/util/ClockConfig.kt b/src/main/kotlin/net/schowek/nextclouddlna/util/ClockConfig.kt new file mode 100644 index 0000000..fe48e46 --- /dev/null +++ b/src/main/kotlin/net/schowek/nextclouddlna/util/ClockConfig.kt @@ -0,0 +1,13 @@ +package net.schowek.nextclouddlna.util + +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import java.time.Clock + +@Configuration +class ClockConfig { + @Bean + fun clock(): Clock { + return Clock.systemDefaultZone() + } +} \ No newline at end of file diff --git a/src/test/groovy/net/schowek/nextclouddlna/nextcloud/content/ContentTreeProviderTest.groovy b/src/test/groovy/net/schowek/nextclouddlna/nextcloud/content/ContentTreeProviderTest.groovy new file mode 100644 index 0000000..cf36008 --- /dev/null +++ b/src/test/groovy/net/schowek/nextclouddlna/nextcloud/content/ContentTreeProviderTest.groovy @@ -0,0 +1,53 @@ +package net.schowek.nextclouddlna.nextcloud.content + +import net.schowek.nextclouddlna.nextcloud.NextcloudDB +import spock.lang.Specification + +import java.time.Clock +import java.time.Instant +import java.time.ZoneId +import java.time.temporal.ChronoUnit +import java.time.temporal.Temporal +import java.time.temporal.TemporalUnit +import java.util.function.Consumer + +import static java.time.Instant.* +import static java.time.Instant.now +import static java.time.temporal.ChronoUnit.* + +class ContentTreeProviderTest extends Specification { + def nextcloudDB + + void setup() { + nextcloudDB = Mock(NextcloudDB) + nextcloudDB.mainNodes() >> [] + nextcloudDB.groupFolders() >> [] + nextcloudDB.processThumbnails(_ as Consumer) >> null + } + + def "should rebuild tree if it's outdated"() { + given: + def clock = Clock.fixed(now, ZoneId.systemDefault()) + + def sut = new ContentTreeProvider(nextcloudDB, clock) + sut.lastMTime = lastMTime.epochSecond + nextcloudDB.maxMtime() >> maxMtime.epochSecond + + when: + def rebuild = sut.rebuildTree(force) + + then: + rebuild == expectedResult + + where: + force | now | lastMTime | maxMtime || expectedResult + true | now() | ofEpochSecond(0L) | now().minus(1, DAYS) || true + true | now() | ofEpochSecond(0L) | now().plus(1, DAYS) || true + false | now() | ofEpochSecond(0L) | now().minus(1, DAYS) || true + false | now() | ofEpochSecond(0L) | now().plus(1, DAYS) || true + false | now() | now() | now().minus(1, DAYS) || false + false | now() | now() | now().plus(1, DAYS) || true + false | now().plus(1, DAYS) | now() | now().minus(1, DAYS) || true + false | now().minus(1, DAYS) | now() | now().minus(1, DAYS) || false + } +}