Ktor 2024 Roadmap DI Update

Since the Ktor Roadmap for 2024 was published there have been a lot of questions regarding Dependency Injection (DI). Specifically how Ktor will be changed to support DI, and to integrate existing DI frameworks. This work is still in its early stages, but we would like to clarify our intentions and invite feedback.

First and foremost, we would stress that:

  1. There will never be any requirement to use a DI framework with Ktor.
  2. Ktor itself will never include a DI framework as part of its design.

The proposed feature is solely for users who wish to combine DI with their Ktor services. We want to help existing DI frameworks integrate with Ktor as seamlessly as possible.

How the proposed Dependency Injection feature will work

Let’s consider how we could use Koin within a Ktor route. Imagine the unfortunate scenario where we require seven separate services in order to purchase the contents of the customer’s shopping cart:

fun Application.root() {
   install(Koin) {
      modules(module {
         single { PricingRules() }
         single { DiscountRules() }
         single { StockCheckRepository() }
         single { DeliveryRoutePlanner() }
         single { PaymentGateway() }
         single { CreditRatingChecker() }
         single { PastPurchasesRecord() }
      })
   }
   ...
}

The DI framework will create and inject the dependencies for us. But because Ktor has no knowledge of Koin we have to specify the dependencies manually. Also the injection process is complex, requiring Delegated Properties and Type Parameters.

Our proposal is to replace the above with something like this:

fun Application.root() {
   install(Koin)
   ...
}

This will be achieved as follows:

  1. You will be able to select which DI framework (if any) you wish to use in the Ktor Project Generator. We hope to support all popular DI frameworks.
  2. The presence of a DI framework will be noted by the Ktor Gradle plugin. It will automatically find all the components managed by that framework. 
  3. The plugin will add new methods to these types, which will enable you to inject them in the simplest possible way.

Our goal is to radically simplify how DI is used within Ktor, without adding any extra complexity. The code generated by the Ktor Gradle plugin will be fully debuggable, and the pipeline architecture will not be modified at all. You will be able to use this new approach in both services and tests.

Hopefully, fans of DI will find this a great improvement, but like DI itself, this will be a completely optional feature. You will still be able to use the DI framework’s native syntax if it suits you better. 

As always we remain committed to Ktor’s founding principles. Every feature we add is aligned with the vision of a no-magic, lightweight solution that is minimalist, simple, flexible, and fast. To help shape the future of Ktor, please join the discussion on the Ktor channel of Kotlinlang Slack (request an invite to Slack).

Continue ReadingKtor 2024 Roadmap DI Update

What is your thought process to decide whether to use ?.let or ?.also

I always struggle to decide whether to use ?.let or ?.also most of the time. For instance, the 2 code snippet will have equivalent behaviour.

Use ?.let

 fun String?.isNullOrTrimEmpty(): Boolean { return this?.trim().isNullOrEmpty() } val theme: Theme by mutableLazy { val sharedPreferences = XXXApplication.instance.getSharedPreferences() val moshi = Moshi.Builder().build() val jsonTheme = sharedPreferences.getString(THEME, null) if (!jsonTheme.isNullOrTrimEmpty()) { jsonTheme?.let { nonNullJsonTheme -> moshi.adapter(Theme::class.java).fromJson(nonNullJsonTheme)?.let { theme -> return@mutableLazy theme } } } return@mutableLazy PREFERRED_THEME } 

Use ?.also

 fun String?.isNullOrTrimEmpty(): Boolean { return this?.trim().isNullOrEmpty() } val theme: Theme by mutableLazy { val sharedPreferences = XXXApplication.instance.getSharedPreferences() val moshi = Moshi.Builder().build() val jsonTheme = sharedPreferences.getString(THEME, null) if (!jsonTheme.isNullOrTrimEmpty()) { jsonTheme?.also { nonNullJsonTheme -> moshi.adapter(Theme::class.java).fromJson(nonNullJsonTheme)?.also { theme -> return@mutableLazy theme } } } return@mutableLazy PREFERRED_THEME } 

By using the above example, may I know which one is the more accurate code snippet?

May I know, what is your thought process to decide whether to use ?.let or ?.also

Thanks.

submitted by /u/yccheok
[link] [comments]

Continue ReadingWhat is your thought process to decide whether to use ?.let or ?.also

Kotlin Beginner – Help Needed

When using functions in Kotlin, I am trying to get one function to calculate from the other as a step by step process. Can anyone give me any ideas as to why I am not getting an output at the end of it.

Current code used:

fun main() {

var result = efficiencyStage4()
println(result)
efficiencyCalculator()
efficiencyStage1()
efficiencyStage2()
efficiencyStage3()
efficiencyStage4()

}
fun efficiencyCalculator() {
println(“Enter Current Efficiency”)
val efficiencyNo = readln()
val efficiencyNoInt = efficiencyNo.toInt()
println(“Enter Total Hours of Production Time a week”)
val totalProductionHrs = readln()
val totalProductionHrsInt = totalProductionHrs.toInt()
println(“Enter Total number of Production Lines”)
val totalProductionLines = readln()
val totalProductionLinesInt = totalProductionLines.toInt()
println(“Enter the number of weeks a year producing”)
val totalWeeks = readln()
val totalWeeksInt = totalWeeks.toInt()
println(“Enter the company turnover for the year”)
val yearlyTurnover = readln()
val yearlyTurnoverInt = yearlyTurnover.toInt()
}

fun efficiencyStage1(totalProductionHrsInt: Int, efficiencyNo: Int, ): Int {
val efficiencyHrs = totalProductionHrsInt / 100 * efficiencyNo
return efficiencyHrs
}

fun efficiencyStage2(efficiencyHrs: Int, totalProductionLinesInt: Int): Int {
val totalEfficiencyHrs = efficiencyHrs * totalProductionLinesInt
return totalEfficiencyHrs
}

fun efficiencyStage3(totalEfficiencyHrs: Int, totalWeeksInt: Int): Int {
val yearlyEfficiencyHrs = totalEfficiencyHrs * totalWeeksInt
return yearlyEfficiencyHrs
}

fun efficiencyStage4(yearlyEfficiencyHrs: Int, yearlyTurnoverInt: Int): Int {
val hourlyinefficiency = yearlyTurnoverInt / yearlyEfficiencyHrs
return hourlyinefficiency
println(yearlyEfficiencyHrs)

I think I may be missing a piece of code that will allow me to display the total yearly efficiency hrs

submitted by /u/jgreen1984
[link] [comments]

Continue ReadingKotlin Beginner – Help Needed

Upload video file to pre-signed S3 URL with partial upload mechanism

I’m currently in need of uploading a large video file, around 500Mb, from an API using a pre-signed S3 URL. However, I want to be able to perform a partial upload and utilize resumable upload functionality so that in case of a connection failure, it can resume uploading from where it left off without starting over.

Have any of you encountered this issue before? Could you please share with ideas me to solve this problem?
Thank you very much.

submitted by /u/mass-101
[link] [comments]

Continue ReadingUpload video file to pre-signed S3 URL with partial upload mechanism

Feedback Request: Implementing a mutableLazy Delegate in Kotlin for Thread-Safe Mutable Properties

I’ve been exploring Kotlin’s lazy functionality and realized it’s primarily designed for immutable variables. However, I needed a similar mechanism for mutable properties. As a result, I devised a mutableLazy delegate pattern that aims to support mutability while preserving thread safety through double-checked locking. Here’s the implementation:

 import kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty fun <T> mutableLazy(initializer: () -> T): MutableLazy<T> { return MutableLazy(initializer) } class MutableLazy<T>(initializer: () -> T) : ReadWriteProperty<Any?, T> { companion object { private object UNINITIALIZED } u/Volatile private var value: Any? = UNINITIALIZED private var initializer: (() -> T)? = initializer private val lock = Any() override fun getValue(thisRef: Any?, property: KProperty<*>): T { val _v1 = value if (_v1 != UNINITIALIZED) { u/Suppress("UNCHECKED_CAST") return _v1 as T } return synchronized(lock) { val _v2 = value if (_v2 != UNINITIALIZED) { u/Suppress("UNCHECKED_CAST") _v2 as T } else { val typedValue = initializer!!() value = typedValue initializer = null // Clear the initializer to allow garbage collection of the lambda typedValue } } } override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { synchronized(lock) { this.value = value } } } 

Usage example:

 object XXXOptions { private const val THEME = "THEME" val theme: Theme by mutableLazy { val sharedPreferences = XXXApplication.instance.getSharedPreferences() val moshi = Moshi.Builder().build() val jsonTheme = sharedPreferences.getString(THEME, null) if (!jsonTheme.isNullOrBlank()) { moshi.adapter(Theme::class.java).fromJson(jsonTheme)?.let { return@mutableLazy it } } return@mutableLazy PREFERRED_THEME } ... } 

I’m reaching out for insights on two aspects:

  1. Design Review: Is the implementation of MutableLazy, particularly the use of double-checked locking for ensuring thread safety, correctly designed? Are there any potential pitfalls or improvements that could be suggested?

  1. Companion Object Necessity: The UNINITIALIZED value is encapsulated within a companion object to signify its unique state. However, given that UNINITIALIZED is already a singleton, is there a strong justification for using a companion object? Could it be omitted, or is there a better practice for handling such a scenario?

I appreciate any feedback or alternative approaches that could enhance this implementation. Thank you!

Thank you.

submitted by /u/yccheok
[link] [comments]

Continue ReadingFeedback Request: Implementing a mutableLazy Delegate in Kotlin for Thread-Safe Mutable Properties

Feedback Request: Implementing a mutableLazy Delegate in Kotlin for Thread-Safe Mutable Properties

I’ve been exploring Kotlin’s lazy functionality and realized it’s primarily designed for immutable variables. However, I needed a similar mechanism for mutable properties. As a result, I devised a mutableLazy delegate pattern that aims to support mutability while preserving thread safety through double-checked locking. Here’s the implementation:

 import kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty fun <T> mutableLazy(initializer: () -> T): MutableLazy<T> { return MutableLazy(initializer) } class MutableLazy<T>(initializer: () -> T) : ReadWriteProperty<Any?, T> { companion object { private object UNINITIALIZED } u/Volatile private var value: Any? = UNINITIALIZED private var initializer: (() -> T)? = initializer private val lock = Any() override fun getValue(thisRef: Any?, property: KProperty<*>): T { val _v1 = value if (_v1 != UNINITIALIZED) { u/Suppress("UNCHECKED_CAST") return _v1 as T } return synchronized(lock) { val _v2 = value if (_v2 != UNINITIALIZED) { u/Suppress("UNCHECKED_CAST") _v2 as T } else { val typedValue = initializer!!() value = typedValue initializer = null // Clear the initializer to allow garbage collection of the lambda typedValue } } } override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { synchronized(lock) { this.value = value } } } 

Usage example:

 object XXXOptions { private const val THEME = "THEME" val theme: Theme by mutableLazy { val sharedPreferences = XXXApplication.instance.getSharedPreferences() val moshi = Moshi.Builder().build() val jsonTheme = sharedPreferences.getString(THEME, null) if (!jsonTheme.isNullOrBlank()) { moshi.adapter(Theme::class.java).fromJson(jsonTheme)?.let { return@mutableLazy it } } return@mutableLazy PREFERRED_THEME } ... } 

I’m reaching out for insights on two aspects:

  1. Design Review: Is the implementation of MutableLazy, particularly the use of double-checked locking for ensuring thread safety, correctly designed? Are there any potential pitfalls or improvements that could be suggested?

  1. Companion Object Necessity: The UNINITIALIZED value is encapsulated within a companion object to signify its unique state. However, given that UNINITIALIZED is already a singleton, is there a strong justification for using a companion object? Could it be omitted, or is there a better practice for handling such a scenario?

I appreciate any feedback or alternative approaches that could enhance this implementation. Thank you!

Thank you.

submitted by /u/yccheok
[link] [comments]

Continue ReadingFeedback Request: Implementing a mutableLazy Delegate in Kotlin for Thread-Safe Mutable Properties

MutableList.indexOf() is not working correctly in Kotlin scratch file

Try to run this code in Kotlin scratch.kts file:

val mutableList = mutableListOf<Int>() mutableList.add(1) mutableList.add(2) mutableList.add(3) val index = mutableList.indexOf(2) println(index) 

It will print -1. If you run it in regular Kotlin file you will get 1

Where can I report this bug to JetBrains?

submitted by /u/Ram_Fold
[link] [comments]

Continue ReadingMutableList.indexOf() is not working correctly in Kotlin scratch file

End of content

No more pages to load