-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #12 from FoxesWorld/modules
Modules
- Loading branch information
Showing
3 changed files
with
224 additions
and
0 deletions.
There are no files selected for viewing
101 changes: 101 additions & 0 deletions
101
src/main/kotlin/ru/foxesworld/foxxey/logging/Logging.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
package ru.foxesworld.foxxey.logging | ||
|
||
import kotlinx.coroutines.runBlocking | ||
import mu.KLogger | ||
import mu.KotlinLogging | ||
import kotlin.system.measureTimeMillis | ||
|
||
/** | ||
* @author vie10 | ||
**/ | ||
|
||
private val log = KotlinLogging.logger { } | ||
|
||
fun main() { | ||
runBlocking { | ||
log.wrappedRunWithoutResult("module", "start") { | ||
|
||
} | ||
} | ||
} | ||
|
||
fun KLogger.debugExceptionAndInfoMessage(exception: Throwable, msg: () -> Any) { | ||
info(msg) | ||
debug(exception, msg) | ||
} | ||
|
||
suspend fun KLogger.wrappedRunWithoutResult( | ||
target: Any, | ||
verb: String, | ||
startEnd: String = "ing", | ||
failureEnd: String = "ing", | ||
successEnd: String = "ed", | ||
block: suspend () -> Unit | ||
) { | ||
wrappedRunWithoutResult( | ||
logging = { | ||
onStart = { | ||
info { "${verb.replaceFirstChar { it.uppercase() }}$startEnd $target.." } | ||
} | ||
onFailure = { | ||
debugExceptionAndInfoMessage(it) { "${verb}$failureEnd $target failed." } | ||
} | ||
onSuccess = { measuredMillis, _ -> | ||
info { | ||
"${ | ||
target.toString().replaceFirstChar { it.uppercase() } | ||
} ${verb}$successEnd in $measuredMillis millis." | ||
} | ||
} | ||
}, | ||
block | ||
) | ||
} | ||
|
||
suspend fun wrappedRunWithoutResult( | ||
logging: (LoggingBlock<Unit>.() -> Unit)? = null, | ||
block: suspend () -> Unit | ||
) { | ||
val loggingBlock = if (logging != null) LoggingBlock<Unit>().apply(logging) else null | ||
loggingBlock?.onStart?.invoke() | ||
val result: Result<Unit> | ||
val measuredMillis = measureTimeMillis { | ||
result = runCatching { | ||
block() | ||
} | ||
} | ||
|
||
result.onSuccess { | ||
loggingBlock?.onSuccess?.invoke(measuredMillis, it) | ||
}.onFailure { | ||
loggingBlock?.onFailure?.invoke(it) | ||
} | ||
} | ||
|
||
suspend fun <T> wrappedRun( | ||
logging: (LoggingBlock<T>.() -> Unit)? = null, | ||
block: suspend () -> T | ||
): Result<T> { | ||
val loggingBlock = if (logging != null) LoggingBlock<T>().apply(logging) else null | ||
loggingBlock?.onStart?.invoke() | ||
val result: Result<T> | ||
val measuredMillis = measureTimeMillis { | ||
result = runCatching { | ||
block() | ||
} | ||
} | ||
|
||
result.onSuccess { | ||
loggingBlock?.onSuccess?.invoke(measuredMillis, it) | ||
}.onFailure { | ||
loggingBlock?.onFailure?.invoke(it) | ||
} | ||
|
||
return result | ||
} | ||
|
||
class LoggingBlock<T>( | ||
var onStart: (() -> Unit)? = null, | ||
var onSuccess: ((measuredMillis: Long, result: T) -> Unit)? = null, | ||
var onFailure: ((exception: Throwable) -> Unit)? = null | ||
) |
61 changes: 61 additions & 0 deletions
61
src/main/kotlin/ru/foxesworld/foxxey/modules/BaseModule.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package ru.foxesworld.foxxey.modules | ||
|
||
import mu.KotlinLogging | ||
import org.koin.dsl.module | ||
import ru.foxesworld.foxxey.commands.Command | ||
import ru.foxesworld.foxxey.logging.wrappedRunWithoutResult | ||
import ru.foxesworld.foxxey.modules.Module.Info | ||
import ru.foxesworld.foxxey.modules.Module.State | ||
import org.koin.core.module.Module as KoinModule | ||
|
||
private val log = KotlinLogging.logger { } | ||
|
||
/** | ||
* @author vie10 | ||
**/ | ||
abstract class BaseModule( | ||
override val info: Info, | ||
module: (KoinModule.() -> Unit)? = null, | ||
commands: (ArrayList<Command>.() -> Unit)? = null | ||
) : Module { | ||
|
||
private val module: KoinModule = module { | ||
module?.run { this() } | ||
} | ||
override val commands: List<Command> = arrayListOf<Command>().apply { | ||
commands?.run { this() } | ||
} | ||
override val state: State | ||
get() = _state | ||
private var _state: State = State.Unloaded | ||
|
||
final override suspend fun start() = log.wrappedRunWithoutResult( | ||
target = "module $info", | ||
verb = "start" | ||
) { | ||
onStart() | ||
_state = State.Started | ||
} | ||
|
||
protected abstract fun onStart() | ||
|
||
final override suspend fun stop() = log.wrappedRunWithoutResult( | ||
target = "module $module", | ||
verb = "stop" | ||
) { | ||
onStop() | ||
_state = State.Stopped | ||
} | ||
|
||
protected abstract fun onStop() | ||
|
||
final override suspend fun load() { | ||
getKoin().loadModules(listOf(module)) | ||
_state = State.Loaded | ||
} | ||
|
||
final override suspend fun unload() { | ||
getKoin().unloadModules(listOf(module)) | ||
_state = State.Unloaded | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package ru.foxesworld.foxxey.modules | ||
|
||
import kotlinx.serialization.SerialName | ||
import org.koin.core.component.KoinComponent | ||
import ru.foxesworld.foxxey.commands.Command | ||
import ru.foxesworld.foxxey.config.ConfigInfo | ||
|
||
/** | ||
* @author vie10 | ||
**/ | ||
interface Module : KoinComponent { | ||
|
||
val info: Info | ||
val state: State | ||
val commands: List<Command> | ||
|
||
suspend fun start() | ||
|
||
suspend fun stop() | ||
|
||
suspend fun load() | ||
|
||
suspend fun unload() | ||
|
||
data class Info( | ||
@SerialName("id") | ||
val id: String, | ||
@SerialName("name") | ||
val name: String, | ||
@SerialName("version-code") | ||
val versionCode: String, | ||
@SerialName("version") | ||
val version: String, | ||
@SerialName("dependencies") | ||
val dependencies: Set<Dependency>, | ||
@SerialName("config") | ||
val config: Set<ConfigInfo> | ||
) { | ||
|
||
data class Dependency( | ||
@SerialName("id") | ||
val id: String, | ||
@SerialName("version-code") | ||
val versionCode: VersionCode | ||
) { | ||
|
||
data class VersionCode( | ||
@SerialName("from") | ||
val from: Int, | ||
@SerialName("to") | ||
val to: Int | ||
) | ||
} | ||
} | ||
|
||
enum class State { | ||
Unloaded, | ||
Loaded, | ||
Stopped, | ||
Started | ||
} | ||
} |