Skip to content

Commit

Permalink
GH-772 Remove coroutines for now, export frontend and release 3.0.0-a…
Browse files Browse the repository at this point in the history
…lpha.4
  • Loading branch information
dzikoysk committed Oct 5, 2021
1 parent 1782314 commit 5a94722
Show file tree
Hide file tree
Showing 56 changed files with 275 additions and 349 deletions.
4 changes: 2 additions & 2 deletions .github/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ For huge public repositories you can adjust memory limit and even size of used t

```bash
# Launching a standalone JAR file
$ java -Xmx16M -jar reposilite-3.0.0-alpha.3.jar
$ java -Xmx16M -jar reposilite-3.0.0-alpha.4.jar

# Using a Docker
$ docker pull dzikoysk/reposilite:3.0.0-alpha.3
$ docker pull dzikoysk/reposilite:3.0.0-alpha.4
```

Visit official guide to read more about extra parameters and configuration details.
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version: "3.9"
services:
reposilite:
image: reposilite:3.0.0-alpha.3
image: reposilite:3.0.0-alpha.4
build:
context: .
dockerfile: Dockerfile
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/docker.html
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
</ul>
<h2><a class="anchor" aria-hidden="true" id="installation"></a><a href="#installation" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Installation</h2>
<p>First of all, you have to pull the image from <a href="https://hub.docker.com/r/dzikoysk/reposilite">DockerHub</a>:</p>
<pre><code class="hljs css language-shell-session"><span class="hljs-comment">// released builds, e.g. 3.0.0-alpha.3</span>
<pre><code class="hljs css language-shell-session"><span class="hljs-comment">// released builds, e.g. 3.0.0-alpha.4</span>
$ docker pull dzikoysk/reposilite:<span class="hljs-number">3.0</span><span class="hljs-number">.0</span>-SNAPSHOT

<span class="hljs-comment">// nightly builds</span>
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/docker/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
</ul>
<h2><a class="anchor" aria-hidden="true" id="installation"></a><a href="#installation" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Installation</h2>
<p>First of all, you have to pull the image from <a href="https://hub.docker.com/r/dzikoysk/reposilite">DockerHub</a>:</p>
<pre><code class="hljs css language-shell-session"><span class="hljs-comment">// released builds, e.g. 3.0.0-alpha.3</span>
<pre><code class="hljs css language-shell-session"><span class="hljs-comment">// released builds, e.g. 3.0.0-alpha.4</span>
$ docker pull dzikoysk/reposilite:<span class="hljs-number">3.0</span><span class="hljs-number">.0</span>-SNAPSHOT

<span class="hljs-comment">// nightly builds</span>
Expand Down
2 changes: 1 addition & 1 deletion reposilite-backend/.run/Reposilite.run.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<option name="MAIN_CLASS_NAME" value="com.reposilite.ReposiliteLauncherKt" />
<module name="reposilite-backend.main" />
<option name="PROGRAM_PARAMETERS" value="--token name:secret" />
<option name="VM_PARAMETERS" value="-Xmx32M" />
<option name="VM_PARAMETERS" value="-Xmx128M" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/reposilite-backend/src/test/workspace" />
<method v="2">
<option name="Make" enabled="true" />
Expand Down
9 changes: 5 additions & 4 deletions reposilite-backend/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import org.gradle.api.tasks.testing.logging.TestLogEvent
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

group = "org.panda-lang"
version = "3.0.0-alpha.3"
version = "3.0.0-alpha.4"

plugins {
`java-library`
Expand Down Expand Up @@ -52,7 +52,7 @@ tasks.withType<KotlinCompile>().configureEach {
dependencies {
implementation("org.jetbrains.kotlin:kotlin-reflect:1.5.21")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.21")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2")
// implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2")

val expressible = "1.0.17"
implementation("org.panda-lang:expressible:$expressible")
Expand Down Expand Up @@ -84,9 +84,10 @@ dependencies {
implementation("io.javalin-rfc:javalin-openapi-plugin:$openapi")
implementation("io.javalin-rfc:javalin-swagger-plugin:$openapi")

val javalinRfcs = "4.0.27"
val javalinRfcs = "4.1.0"
implementation("com.reposilite.javalin-rfcs:javalin-context:$javalinRfcs")
implementation("com.reposilite.javalin-rfcs:javalin-reactive-routing:$javalinRfcs")
implementation("com.reposilite.javalin-rfcs:javalin-routing:$javalinRfcs")
//implementation("com.reposilite.javalin-rfcs:javalin-reactive-routing:$javalinRfcs")

// val javalin = "4.0.0.RC3"
// implementation("io.javalin:javalin:$javalin")
Expand Down
25 changes: 9 additions & 16 deletions reposilite-backend/src/main/kotlin/com/reposilite/Reposilite.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,19 @@ import com.reposilite.status.StatusFacade
import com.reposilite.token.AccessTokenFacade
import com.reposilite.web.JavalinWebServer
import com.reposilite.web.WebConfiguration
import com.reposilite.web.coroutines.ExclusiveDispatcher
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import org.jetbrains.exposed.sql.Database
import panda.utilities.console.Effect
import java.util.concurrent.CompletableFuture
import java.util.concurrent.ExecutorService
import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.atomic.AtomicBoolean

const val VERSION = "3.0.0-alpha.3"
const val VERSION = "3.0.0-alpha.4"

class Reposilite(
val journalist: ReposiliteJournalist,
val parameters: ReposiliteParameters,
val configuration: Configuration,
val ioDispatcher: ExclusiveDispatcher?,
val ioService: ExecutorService,
val scheduler: ScheduledExecutorService,
val database: Database,
val webServer: JavalinWebServer,
Expand All @@ -66,7 +63,7 @@ class Reposilite(
alive.peek { shutdown() }
}

suspend fun launch() {
fun launch() {
load()
start()
}
Expand All @@ -83,7 +80,7 @@ class Reposilite(

logger.info("Platform: ${System.getProperty("java.version")} (${System.getProperty("os.name")})")
logger.info("Working directory: ${parameters.workingDirectory.toAbsolutePath()}")
logger.info("Mode: ${if (configuration.reactiveMode) "Reactive" else "Blocking"}")
logger.info("Threads: ${configuration.webThreadPool} WEB / ${configuration.ioThreadPool} IO")
logger.info("")

logger.info("--- Loading domain configurations")
Expand All @@ -97,7 +94,7 @@ class Reposilite(
logger.info("")
}

private suspend fun start(): Reposilite {
private fun start(): Reposilite {
alive.set(true)
Thread.currentThread().name = "Reposilite | Main Thread"

Expand All @@ -111,17 +108,13 @@ class Reposilite(
logger.info("")
consoleFacade.executeCommand("help")

val task = suspend {
ioService.execute {
logger.info("")
logger.info("Collecting status metrics...")
logger.info("")
consoleFacade.executeCommand("status")
logger.info("")
}

ioDispatcher
?.also { withContext(ioDispatcher) { task() } }
?: CompletableFuture.runAsync { runBlocking { task() } }
} catch (exception: Exception) {
logger.error("Failed to start Reposilite")
logger.exception(exception)
Expand All @@ -137,11 +130,11 @@ class Reposilite(
alive.set(false)
logger.info("Shutting down ${parameters.hostname}::${parameters.port}...")
scheduler.shutdown()
ioDispatcher?.prepareShutdown()
ioService.shutdown()
webs.forEach { it.dispose(this@Reposilite) }
webServer.stop()
scheduler.shutdownNow()
ioDispatcher?.completeShutdown()
ioService.shutdownNow()
journalist.shutdown()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,15 @@ import com.reposilite.journalist.Journalist
import com.reposilite.journalist.backend.PrintStreamLogger
import com.reposilite.maven.application.MavenWebConfiguration
import com.reposilite.shared.HttpRemoteClient
import com.reposilite.shared.newFixedThreadPool
import com.reposilite.shared.newSingleThreadScheduledExecutor
import com.reposilite.statistics.application.StatisticsWebConfiguration
import com.reposilite.status.application.FailureWebConfiguration
import com.reposilite.status.application.StatusWebConfiguration
import com.reposilite.token.application.AccessTokenWebConfiguration
import com.reposilite.web.JavalinWebServer
import com.reposilite.web.WebConfiguration
import com.reposilite.web.coroutines.ExclusiveDispatcher
import com.reposilite.web.web
import java.util.concurrent.Executors
import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.ThreadPoolExecutor
import java.util.concurrent.TimeUnit.MILLISECONDS

object ReposiliteFactory {

Expand All @@ -51,33 +48,29 @@ object ReposiliteFactory {

fun createReposilite(parameters: ReposiliteParameters, journalist: Journalist, configuration: Configuration): Reposilite {
parameters.applyLoadedConfiguration(configuration)

val webServer = JavalinWebServer()
val logger = ReposiliteJournalist(journalist, configuration.cachedLogSize, parameters.testEnv)
val scheduler = Executors.newSingleThreadScheduledExecutor()
val database = DatabaseSourceConfiguration.createConnection(parameters.workingDirectory, configuration.database)

val ioDispatcher =
if (configuration.reactiveMode)
ExclusiveDispatcher(ThreadPoolExecutor(2, configuration.ioThreadPool, 0L, MILLISECONDS, LinkedBlockingQueue()))
else
null
val scheduler = newSingleThreadScheduledExecutor("Reposilite | Scheduler")
val ioService = newFixedThreadPool(2, configuration.ioThreadPool, "Reposilite | IO")
val database = DatabaseSourceConfiguration.createConnection(parameters.workingDirectory, configuration.database)

val webServer = JavalinWebServer()
val webs = mutableListOf<WebConfiguration>()

val statusFacade = web(webs, StatusWebConfiguration) { createFacade(parameters.testEnv, webServer) }
val failureFacade = web(webs, FailureWebConfiguration) { createFacade(logger) }
val consoleFacade = web(webs, ConsoleWebConfiguration) { createFacade(logger, failureFacade) }
val mavenFacade = web(webs, MavenWebConfiguration) { createFacade(logger, parameters.workingDirectory, HttpRemoteClient(logger), configuration.repositories) }
val frontendFacade = web(webs, FrontendWebConfiguration) { createFacade(configuration) }
val statisticFacade = web(webs, StatisticsWebConfiguration) { createFacade(logger, ioDispatcher, database) }
val accessTokenFacade = web(webs, AccessTokenWebConfiguration) { createFacade(ioDispatcher, database) }
val statisticFacade = web(webs, StatisticsWebConfiguration) { createFacade(logger, database) }
val accessTokenFacade = web(webs, AccessTokenWebConfiguration) { createFacade(database) }
val authenticationFacade = web(webs, AuthenticationWebConfiguration) { createFacade(logger, accessTokenFacade) }

return Reposilite(
journalist = logger,
parameters = parameters,
configuration = configuration,
ioDispatcher = ioDispatcher,
ioService = ioService,
scheduler = scheduler,
database = database,
webServer = webServer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*/
package com.reposilite

import kotlinx.coroutines.runBlocking
import picocli.CommandLine

fun createWithParameters(vararg args: String): Reposilite? {
Expand All @@ -35,6 +34,6 @@ fun createWithParameters(vararg args: String): Reposilite? {
return ReposiliteFactory.createReposilite(parameters)
}

fun main(args: Array<String>): Unit = runBlocking {
fun main(args: Array<String>) {
createWithParameters(*args)?.launch()
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,21 @@ import com.reposilite.web.http.extractFromString
import io.javalin.http.HttpCode.UNAUTHORIZED
import panda.std.Result
import panda.std.asSuccess
import panda.std.coroutines.rxFlatMap

class AuthenticationFacade internal constructor(
private val journalist: Journalist,
private val accessTokenFacade: AccessTokenFacade
) : Journalist {

suspend fun authenticateByHeader(headers: Map<String, String>): Result<AccessToken, ErrorResponse> =
fun authenticateByHeader(headers: Map<String, String>): Result<AccessToken, ErrorResponse> =
extractFromHeaders(headers)
.rxFlatMap { (name, secret) -> authenticateByCredentials(name, secret) }
.flatMap { (name, secret) -> authenticateByCredentials(name, secret) }

suspend fun authenticateByCredentials(credentials: String): Result<AccessToken, ErrorResponse> =
fun authenticateByCredentials(credentials: String): Result<AccessToken, ErrorResponse> =
extractFromString(credentials)
.rxFlatMap { (name, secret) -> authenticateByCredentials(name, secret) }
.flatMap { (name, secret) -> authenticateByCredentials(name, secret) }

suspend fun authenticateByCredentials(name: String, secret: String): Result<AccessToken, ErrorResponse> =
fun authenticateByCredentials(name: String, secret: String): Result<AccessToken, ErrorResponse> =
accessTokenFacade.getToken(name)
?.takeIf { B_CRYPT_TOKENS_ENCODER.matches(secret, it.secret) }
?.asSuccess()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,20 +264,21 @@ class Configuration : Serializable {

/* Performance */

@Description(
"",
"# Note: It might be hard to estimate the best amount of threads for your use case,",
"# but you can safely increase amount of threads if needed and Reposilite will create only as much as it needs.",
"# This option might be more useful to limit available memory resources to minimum (1 thread requires around 200kb to 1MB of memory)",
"",
"# By default, Reposilite 3.x uses experimental reactive mode to maximize performance of each spawned thread.",
"# If you've noticed various unresolved behaviours like freezing and deadlocking, you can switch to the standard blocking mode.",
"# Remember: Blocking mode requires more resources (threads) to handle the same throughput. "
)
@JvmField
var reactiveMode = true
// @Description(
// "",
// "# Note: It might be hard to estimate the best amount of threads for your use case,",
// "# but you can safely increase amount of threads if needed and Reposilite will create only as much as it needs.",
// "# This option might be more useful to limit available memory resources to minimum (1 thread requires around 200kb to 1MB of memory)",
// "",
// "# By default, Reposilite 3.x uses experimental reactive mode to maximize performance of each spawned thread.",
// "# If you've noticed various unresolved behaviours like freezing and deadlocking, you can switch to the standard blocking mode.",
// "# Remember: Blocking mode requires more resources (threads) to handle the same throughput. "
// )
// @JvmField
// var reactiveMode = true

@Description(
"",
"# Max amount of threads used by core thread pool (min: 4)",
"# The web thread pool handles first few steps of incoming http connections, as soon as possible all tasks are redirected to IO thread pool."
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import com.reposilite.console.api.ReposiliteCommand
import com.reposilite.journalist.Journalist
import com.reposilite.journalist.Logger
import com.reposilite.status.FailureFacade
import kotlinx.coroutines.CoroutineDispatcher
import picocli.CommandLine
import picocli.CommandLine.Command
import picocli.CommandLine.MissingParameterException
Expand All @@ -40,10 +39,10 @@ internal class CommandExecutor(
private val consoleThread = ConsoleThread(this, source, failureFacade)
private val commandExecutor = CommandLine(this)

suspend fun execute(command: String): ExecutionResponse =
fun execute(command: String): ExecutionResponse =
execute(command) { logger.info(it) }

suspend fun execute(command: String, outputConsumer: Consumer<String>): ExecutionResponse =
fun execute(command: String, outputConsumer: Consumer<String>): ExecutionResponse =
executeCommand(command).also {
it.response.forEach { message ->
message.replace(System.lineSeparator(), "\n").split("\n").toTypedArray().forEach { line ->
Expand All @@ -52,7 +51,7 @@ internal class CommandExecutor(
}
}

private suspend fun executeCommand(command: String): ExecutionResponse {
private fun executeCommand(command: String): ExecutionResponse {
val processedCommand = command.trim()

if (processedCommand.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class ConsoleFacade internal constructor(
internal val commandExecutor: CommandExecutor
) : Journalist {

suspend fun executeCommand(command: String): Result<ExecutionResponse, ErrorResponse> {
fun executeCommand(command: String): Result<ExecutionResponse, ErrorResponse> {
if (StringUtils.isEmpty(command)) {
return errorResponse(BAD_REQUEST, "Missing command")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
package com.reposilite.console

import com.reposilite.status.FailureFacade
import kotlinx.coroutines.runBlocking
import java.io.InputStream
import java.util.Scanner

Expand All @@ -40,27 +39,6 @@ internal class ConsoleThread(
return
}

/*
val reader = LineReaderBuilder.builder().build();
val prompt = "$"
while (!isInterrupted && input.hasNextLine()) {
try {
val line = reader.readLine(prompt)
runBlocking {
console.logger.info("")
console.execute(line)
console.logger.info("")
}
} catch (e: UserInterruptException) {
// Ignore
} catch (e: EndOfFileException) {
return
}
}
*/

do {
val command = input.nextLine().trim()

Expand All @@ -69,11 +47,9 @@ internal class ConsoleThread(
}

runCatching {
runBlocking {
commandExecutor.logger.info("")
commandExecutor.execute(command)
commandExecutor.logger.info("")
}
commandExecutor.logger.info("")
commandExecutor.execute(command)
commandExecutor.logger.info("")
}.onFailure {
failureFacade.throwException("Command: $command", it)
}
Expand Down
Loading

0 comments on commit 5a94722

Please sign in to comment.