From 140e4a62613e2f4fab1722329a401800e0b0d806 Mon Sep 17 00:00:00 2001
From: Jan-Niclas Struewer <j.n.struewer@gmail.com>
Date: Wed, 19 Apr 2023 17:02:19 +0200
Subject: [PATCH] started task manager implementation based upon Kotlin
 coroutines

---
 .../dataprovider/DataProviderApplication.kt   |  1 +
 .../dataprovider/WebSecurityConfiguration.kt  |  5 +-
 .../iem/dataprovider/git/GitService.kt        | 20 +++++++
 .../iem/dataprovider/git/TaskManager.kt       | 53 +++++++++++++++++++
 .../dataprovider/gitlab/GitlabController.kt   |  2 +-
 .../iem/dataprovider/gitlab/GitlabService.kt  | 16 +++---
 6 files changed, 85 insertions(+), 12 deletions(-)
 create mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/git/GitService.kt
 create mode 100644 src/main/kotlin/de/fraunhofer/iem/dataprovider/git/TaskManager.kt

diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/DataProviderApplication.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/DataProviderApplication.kt
index ed3c240b..dbc39208 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/DataProviderApplication.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/DataProviderApplication.kt
@@ -8,5 +8,6 @@ import org.springframework.boot.runApplication
 class DataProviderApplication
 
 fun main(args: Array<String>) {
+	println("Started app [${Thread.currentThread().name}]")
 	runApplication<DataProviderApplication>(*args)
 }
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/WebSecurityConfiguration.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/WebSecurityConfiguration.kt
index 9d8cd000..202fbbb8 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/WebSecurityConfiguration.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/WebSecurityConfiguration.kt
@@ -18,8 +18,9 @@ class SecurityConfiguration {
             authorizeExchange {
                 authorize("/gitlab/repoChanged", permitAll)
             }
-            csrf { disable() }
-
+            csrf {
+                disable()
+            }
         }
     }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/git/GitService.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/git/GitService.kt
new file mode 100644
index 00000000..4ba78604
--- /dev/null
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/git/GitService.kt
@@ -0,0 +1,20 @@
+package de.fraunhofer.iem.dataprovider.git
+
+import org.springframework.stereotype.Service
+import kotlinx.coroutines.*
+import kotlinx.coroutines.channels.*
+@Service
+class GitService(private val taskManager: TaskManager) {
+
+
+    suspend fun cloneGit() {
+        println("clone git called")
+        repeat(20) {
+            taskManager.addTask("Task no $it")
+        }
+        //        val git: Git = Git.cloneRepository()
+//            .setURI("https://github.com/eclipse/jgit.git")
+//            .setDirectory("/path/to/repo")
+//            .call()
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/git/TaskManager.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/git/TaskManager.kt
new file mode 100644
index 00000000..5d335ada
--- /dev/null
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/git/TaskManager.kt
@@ -0,0 +1,53 @@
+package de.fraunhofer.iem.dataprovider.git
+
+import jakarta.annotation.PostConstruct
+import jakarta.annotation.PreDestroy
+import kotlinx.coroutines.*
+import kotlinx.coroutines.channels.Channel
+import org.springframework.stereotype.Component
+import kotlin.coroutines.CoroutineContext
+
+@Component
+class TaskManager : CoroutineScope {
+
+    private val job = SupervisorJob()
+    override val coroutineContext: CoroutineContext
+        get() = Dispatchers.Default + job
+
+    // TODO: this could be dangerous to give it unlimited memory
+    private val tasks = Channel<String>(Channel.UNLIMITED)
+
+    @PostConstruct
+    fun startWorkers() {
+        // TODO: spawn threads equal to number of cores
+        repeat(10) {
+            println("[${Thread.currentThread().name}] launching coroutine")
+            launchWorker(it)
+        }
+    }
+
+    private fun launchWorker(id: Int) = launch {
+        for (task in tasks) {
+            println("[${Thread.currentThread().name}] Processor #$id received $task")
+            executeTask(task)
+            println("[${Thread.currentThread().name}] Processor #$id finished $task")
+        }
+    }
+
+    private suspend fun executeTask(task: String) {
+        // simulate a long running task
+        delay(5000)
+    }
+
+    fun addTask(task: String) {
+        launch {
+            tasks.send(task)
+        }
+    }
+
+    @PreDestroy
+    fun stop() {
+        job.cancel()
+    }
+
+}
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/GitlabController.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/GitlabController.kt
index 3ba2c9b1..c062fcb3 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/GitlabController.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/GitlabController.kt
@@ -14,7 +14,7 @@ class GitlabController(private val gitlabService: GitlabService) {
     private val logger = getLogger(javaClass)
 
     @PostMapping("/repoChanged")
-    fun repoChanged(@RequestBody repositoryChangedDto: RepositoryChangedDto) {
+    suspend fun repoChanged(@RequestBody repositoryChangedDto: RepositoryChangedDto) {
         logger.info("Repo changed POST request for ID ${repositoryChangedDto.repoId} received.")
         gitlabService.queryRepo(repositoryChangedDto.repoId)
     }
diff --git a/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/GitlabService.kt b/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/GitlabService.kt
index 12e5670f..13128991 100644
--- a/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/GitlabService.kt
+++ b/src/main/kotlin/de/fraunhofer/iem/dataprovider/gitlab/GitlabService.kt
@@ -1,23 +1,21 @@
 package de.fraunhofer.iem.dataprovider.gitlab
 
+import de.fraunhofer.iem.dataprovider.git.GitService
 import de.fraunhofer.iem.dataprovider.logger.getLogger
 import org.eclipse.jgit.api.Git
 import org.gitlab4j.api.GitLabApi
 import org.springframework.stereotype.Service
 
 @Service
-class GitlabService(gitlabConfiguration: GitlabConfiguration) {
+class GitlabService(gitlabConfiguration: GitlabConfiguration, val gitService: GitService) {
 
     private val logger = getLogger(javaClass)
     private var gitlabApi = GitLabApi(gitlabConfiguration.host, gitlabConfiguration.accessToken)
-    fun queryRepo(repoId: Long) {
-        val project = gitlabApi.projectApi.getProject(repoId)
-        logger.info(project.toString())
-        val projectUri = project.sshUrlToRepo
-//        val git: Git = Git.cloneRepository()
-//            .setURI("https://github.com/eclipse/jgit.git")
-//            .setDirectory("/path/to/repo")
-//            .call()
+    suspend fun queryRepo(repoId: Long) {
+//        val project = gitlabApi.projectApi.getProject(repoId)
+//        logger.info(project.toString())
+//        val projectUri = project.sshUrlToRepo
+        gitService.cloneGit()
     }
 
 }
\ No newline at end of file
-- 
GitLab