From: Olaf Wintermann Date: Sun, 7 Sep 2025 12:33:09 +0000 (+0200) Subject: implement background sync X-Git-Url: https://uap-core.de/gitweb/?a=commitdiff_plain;h=f7527a779df227f14448f0125c9d2be20718605a;p=rssreader.git implement background sync --- diff --git a/rss-application/src/main/kotlin/de/unixwork/rssreader/App.kt b/rss-application/src/main/kotlin/de/unixwork/rssreader/App.kt index 33eeec1..ee09628 100644 --- a/rss-application/src/main/kotlin/de/unixwork/rssreader/App.kt +++ b/rss-application/src/main/kotlin/de/unixwork/rssreader/App.kt @@ -3,10 +3,18 @@ package de.unixwork.rssreader import de.unixwork.ui.Application import de.unixwork.ui.ToolbarPosition import de.unixwork.ui.Toolkit +import de.unixwork.ui.kotlin.ToolkitDispatcher import de.unixwork.ui.kotlin.toolbarItem import de.unixwork.ui.kotlin.addToolbarDefault +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.IO +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch class App : Application { + var window: MainWindow? = null + init { initToolbar() } @@ -25,13 +33,41 @@ class App : Application { } override fun startup() { - val window = MainWindow() - window.show() + window = MainWindow() + window?.show() + + backgroundSync(10 * 1000L) } override fun shutdown() { System.exit(0) } + + fun backgroundSync(delayedStart: Long = 0) { + GlobalScope.launch(Dispatchers.IO) { + delay(delayedStart) + + while(true) { + println("Background sync") + try { + val pending = Database.getPendingFeeds(1 * 60) + SyncJob { pending }.syncBlocking() + GlobalScope.launch(ToolkitDispatcher) { + window!!.sourceList.invalidateCache() + window!!.sourceList.reloadStatus() + window!!.feedList.reloadCurrentFeed() + } + } catch (e: Exception) { + e.printStackTrace() + } + println("Background sync done") + + // TODO: check time until next feed needs sync + + delay(60 * 1000L) + } + } + } } fun main() { diff --git a/rss-application/src/main/kotlin/de/unixwork/rssreader/Database.kt b/rss-application/src/main/kotlin/de/unixwork/rssreader/Database.kt index e667789..85b6b00 100644 --- a/rss-application/src/main/kotlin/de/unixwork/rssreader/Database.kt +++ b/rss-application/src/main/kotlin/de/unixwork/rssreader/Database.kt @@ -296,27 +296,30 @@ object Database { return feeds } - public fun getPendingFeeds() : MutableList { + public fun getPendingFeeds(defaultInterval: Int) : MutableList { val feeds = mutableListOf() dataSource.connection.use { conn -> conn.prepareStatement(""" select f.* from feeds f inner join feedcollections c on f.feedcollection_id = c.feedcollection_id - where datediff(ss, coalesce(last_update, '1970-01-01'), now()) > case when c.update_interval > 0 then c.update_interval else 60 end + where datediff(ss, now(), coalesce(last_update, '1970-01-01')) > case when c.update_interval > 0 then c.update_interval else ? end """.trimIndent()).use { stmt -> + stmt.setInt(1, defaultInterval) stmt.executeQuery().use { rs -> - val id = rs.getInt("feed_id") - val feedCollectionId = rs.getInt("feedcollection_id") - val url = rs.getString("url") - val authUser = rs.getString("auth_user") - val authPassword = rs.getString("auth_password") - val certPath = rs.getString("certpath") - val feed = Feed(id, feedCollectionId, url) - feed.user = authUser - feed.password = authPassword - feed.certpath = certPath - feeds.add(feed) + while(rs.next()) { + val id = rs.getInt("feed_id") + val feedCollectionId = rs.getInt("feedcollection_id") + val url = rs.getString("url") + val authUser = rs.getString("auth_user") + val authPassword = rs.getString("auth_password") + val certPath = rs.getString("certpath") + val feed = Feed(id, feedCollectionId, url) + feed.user = authUser + feed.password = authPassword + feed.certpath = certPath + feeds.add(feed) + } } } } diff --git a/rss-application/src/main/kotlin/de/unixwork/rssreader/SyncJob.kt b/rss-application/src/main/kotlin/de/unixwork/rssreader/SyncJob.kt index f205f7d..a1c81f3 100644 --- a/rss-application/src/main/kotlin/de/unixwork/rssreader/SyncJob.kt +++ b/rss-application/src/main/kotlin/de/unixwork/rssreader/SyncJob.kt @@ -8,7 +8,9 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.IO import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking import java.net.URI import java.net.http.HttpClient import java.net.http.HttpRequest @@ -21,10 +23,24 @@ class SyncJob(feeds: () -> List) { fun sync(completion: () -> Unit = {}) { GlobalScope.launch(Dispatchers.IO) { val feeds = getFeeds() + syncFeeds(feeds) + GlobalScope.launch(completionContext) { + completion() + } + } + } + + fun syncBlocking() { + runBlocking { + syncFeeds(getFeeds()) + } + } + private suspend fun syncFeeds(feeds: List) { + coroutineScope { val client = HttpClient.newBuilder().build() val jobs = feeds.map { feed -> - async { + async(Dispatchers.IO) { try { val requestBuilder = HttpRequest.newBuilder() .uri(URI(feed.uri)) @@ -86,10 +102,6 @@ class SyncJob(feeds: () -> List) { } } jobs.awaitAll() - - GlobalScope.launch(completionContext) { - completion() - } } } } \ No newline at end of file