Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Kotlin core dependencies #2844

Merged
merged 11 commits into from
Mar 6, 2024
10 changes: 5 additions & 5 deletions frontend-common/karma.config.d/custom-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
test: /\.js$/,
use: {loader: 'istanbul-instrumenter-loader'},
// fixme: need to exclude Kotlin dependencies
include: [path.resolve(__dirname, '../save-cloud-save-frontend-common/kotlin/')]
include: [path.resolve(__dirname, '../save-cloud-frontend-common/kotlin/')]
nulls marked this conversation as resolved.
Show resolved Hide resolved
}
)
config.coverageIstanbulReporter = {
Expand All @@ -24,12 +24,12 @@ config.set({
}
},
proxies: {
// serving mockServiceWorker.js.js from location relative to base url
// serving mockServiceWorker.js from location relative to base url
// the file should be included into Karma's `files` to be served by server at all
'/mockServiceWorker.js': '/base/mockServiceWorker.js',
'/mockServiceWorker.js': '/base/node_modules/mockServiceWorker.js',
},
})

// http://karma-runner.github.io/6.3/config/files.html
// 'All of the relative patterns will get resolved using the basePath first.', where basePath is set by KGP to `node_modules`
config.files.push('./mockServiceWorker.js')
// 'All of the relative patterns will get resolved using the basePath first.', where basePath is NOT set by KGP to `node_modules` after migration to 1.9
config.files.push('./node_modules/mockServiceWorker.js')
8 changes: 4 additions & 4 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[versions]
kotlin = "1.9.10"
kotlin = "1.9.22"
jetbrains-annotations = "24.0.1"
save-cli = "0.3.10"
ktor = "2.3.6"
okio = "3.3.0"
serialization = "1.6.0"
kotlinx-datetime = "0.4.1"
kotlinx-coroutines = "1.7.3"
serialization = "1.6.3"
kotlinx-datetime = "0.5.0"
kotlinx-coroutines = "1.8.0"
kotlin-wrappers = "1.0.0-pre.634"
spring-boot = "2.7.17"
spring-cloud = "3.1.9"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ class SaveAgent(
/**
* The current [AgentState] of this agent. Initial value corresponds to the period when agent needs to finish its configuration.
*/
val state = GenericAtomicReference(AgentState.BUSY)
val state = createGenericAtomicReference(AgentState.BUSY)

// fixme (limitation of old MM): can't use atomic reference to Instant here, because when using `Clock.System.now()` as an assigned value
// Kotlin throws `kotlin.native.concurrent.InvalidMutabilityException: mutation attempt of frozen kotlinx.datetime.Instant...`
private val executionStartSeconds = AtomicLong(0L)
private val saveProcessJob: GenericAtomicReference<Job?> = GenericAtomicReference(null)
private val executionStartSeconds = createAtomicLong(0L)
private val saveProcessJob: GenericAtomicReference<Job?> = createGenericAtomicReference(null)
private val backgroundContext = newSingleThreadContext("background")
private val saveProcessContext = newSingleThreadContext("save-process")
private val reportFormat = Json {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import com.saveourtool.save.agent.AgentState
import com.saveourtool.save.agent.SaveAgent
import com.saveourtool.save.core.logging.logWarn
import com.saveourtool.save.core.utils.runIf
import com.saveourtool.save.utils.AtomicLong
import com.saveourtool.save.utils.createAtomicLong
import com.saveourtool.save.utils.failureOrNotOk
import com.saveourtool.save.utils.fs
import com.saveourtool.save.utils.notOk
Expand Down Expand Up @@ -82,7 +82,7 @@ internal suspend fun HttpClient.download(url: String, file: Path): Result<HttpRe
.execute { httpResponse ->
if (httpResponse.status.isSuccess()) {
val channel: ByteReadChannel = httpResponse.body()
val totalBytes = AtomicLong(0L)
val totalBytes = createAtomicLong(0L)
while (!channel.isClosedForRead) {
val packet = channel.readRemaining(DEFAULT_HTTP_BUFFER_SIZE.toLong())
while (!packet.isEmpty) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import kotlinx.datetime.Clock
/**
* Atomic values
*/
expect class AtomicLong(value: Long) {
interface AtomicLong {
/**
* @return value
*/
Expand All @@ -32,12 +32,9 @@ expect class AtomicLong(value: Long) {
}

/**
* Class that holds value and shares atomic reference to the value
*
* @param valueToStore value to store
* Class that holds value and shares atomic reference to the value
*/
@Suppress("USE_DATA_CLASS")
expect class GenericAtomicReference<T>(valueToStore: T) {
interface GenericAtomicReference<T> {
/**
* @return stored value
*/
Expand All @@ -61,8 +58,8 @@ class ExpiringValueWrapper<T : Any>(
private val valueGetter: () -> T,
) {
private val expirationTimeSeconds = expirationTime.toLong(DurationUnit.SECONDS)
private val lastUpdateTimeSeconds = AtomicLong(0)
private val value: GenericAtomicReference<T> = GenericAtomicReference(valueGetter())
private val lastUpdateTimeSeconds = createAtomicLong(0)
private val value: GenericAtomicReference<T> = createGenericAtomicReference(valueGetter())

/**
* @return cached value or refreshes the value and returns it
Expand All @@ -77,6 +74,18 @@ class ExpiringValueWrapper<T : Any>(
}
}

/**
* @param value
* @return [AtomicLong] with initial value [value]
*/
expect fun createAtomicLong(value: Long): AtomicLong

/**
* @param valueToStore
* @return create [GenericAtomicReference] with initial value [valueToStore]
*/
expect fun <T> createGenericAtomicReference(valueToStore: T): GenericAtomicReference<T>

/**
* @param envName
* @return env variable name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,18 @@

package com.saveourtool.save.utils

actual class AtomicLong actual constructor(value: Long) {
actual fun get(): Long = throw NotImplementedError(NOT_IMPLEMENTED_ON_JS)
actual fun createAtomicLong(value: Long): AtomicLong = object : AtomicLong {
override fun get(): Long = throw NotImplementedError(NOT_IMPLEMENTED_ON_JS)

actual fun set(newValue: Long) {
throw NotImplementedError(NOT_IMPLEMENTED_ON_JS)
}
override fun set(newValue: Long) = throw NotImplementedError(NOT_IMPLEMENTED_ON_JS)

actual fun addAndGet(delta: Long): Long = throw NotImplementedError(NOT_IMPLEMENTED_ON_JS)
override fun addAndGet(delta: Long): Long = throw NotImplementedError(NOT_IMPLEMENTED_ON_JS)
}

@Suppress("USE_DATA_CLASS")
actual class GenericAtomicReference<T> actual constructor(valueToStore: T) {
actual fun get(): T = throw NotImplementedError(NOT_IMPLEMENTED_ON_JS)
actual fun set(newValue: T) {
throw NotImplementedError(NOT_IMPLEMENTED_ON_JS)
}
actual fun <T> createGenericAtomicReference(valueToStore: T): GenericAtomicReference<T> = object : GenericAtomicReference<T> {
override fun get(): T = throw NotImplementedError(NOT_IMPLEMENTED_ON_JS)

override fun set(newValue: T) = throw NotImplementedError(NOT_IMPLEMENTED_ON_JS)
}

actual fun getenv(envName: String): String? = throw NotImplementedError(NOT_IMPLEMENTED_ON_JS)
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/**
* Platform utils
*/

@file:Suppress("FILE_NAME_MATCH_CLASS")
/**
* Platform dependent utility methods
Expand All @@ -7,13 +11,19 @@

package com.saveourtool.save.utils

actual typealias AtomicLong = java.util.concurrent.atomic.AtomicLong
actual fun createAtomicLong(value: Long): AtomicLong = object : AtomicLong {
private val holder = java.util.concurrent.atomic.AtomicLong(value)
override fun get(): Long = holder.get()

override fun set(newValue: Long) = holder.set(newValue)

override fun addAndGet(delta: Long): Long = holder.addAndGet(delta)
}

@Suppress("USE_DATA_CLASS")
actual class GenericAtomicReference<T> actual constructor(valueToStore: T) {
actual fun <T> createGenericAtomicReference(valueToStore: T): GenericAtomicReference<T> = object : GenericAtomicReference<T> {
private val holder: java.util.concurrent.atomic.AtomicReference<T> = java.util.concurrent.atomic.AtomicReference(valueToStore)
actual fun get(): T = holder.get()
actual fun set(newValue: T) {
override fun get(): T = holder.get()
override fun set(newValue: T) {
holder.set(newValue)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,22 @@ package com.saveourtool.save.utils
import kotlinx.cinterop.ExperimentalForeignApi
import kotlinx.cinterop.toKString

actual class AtomicLong actual constructor(value: Long) {
private val kotlinAtomicLong = kotlin.native.concurrent.AtomicLong(value)
actual fun createAtomicLong(value: Long): AtomicLong = object : AtomicLong {
private val kotlinAtomicLong = kotlin.concurrent.AtomicLong(value)

actual fun get(): Long = kotlinAtomicLong.value
override fun get(): Long = kotlinAtomicLong.value

actual fun set(newValue: Long) {
override fun set(newValue: Long) {
kotlinAtomicLong.value = newValue
}

actual fun addAndGet(delta: Long): Long = kotlinAtomicLong.addAndGet(delta)
override fun addAndGet(delta: Long): Long = kotlinAtomicLong.addAndGet(delta)
}

@Suppress("USE_DATA_CLASS")
actual class GenericAtomicReference<T> actual constructor(valueToStore: T) {
actual fun <T> createGenericAtomicReference(valueToStore: T): GenericAtomicReference<T> = object : GenericAtomicReference<T> {
private val holder: kotlin.concurrent.AtomicReference<T> = kotlin.concurrent.AtomicReference(valueToStore)
actual fun get(): T = holder.value
actual fun set(newValue: T) {
override fun get(): T = holder.value
override fun set(newValue: T) {
holder.value = newValue
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import io.ktor.utils.io.core.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlin.experimental.ExperimentalNativeApi
import kotlin.test.*

class ServerTest {
Expand All @@ -27,6 +28,7 @@ class ServerTest {
server.stop()
}

@OptIn(ExperimentalNativeApi::class)
@Test
fun testServerStartup() {
httpClient().use { client ->
Expand Down
8 changes: 4 additions & 4 deletions save-frontend/karma.config.d/custom-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ config.set({
}
},
proxies: {
// serving mockServiceWorker.js.js from location relative to base url
// serving mockServiceWorker.js from location relative to base url
// the file should be included into Karma's `files` to be served by server at all
'/mockServiceWorker.js': '/base/mockServiceWorker.js',
'/mockServiceWorker.js': '/base/node_modules/mockServiceWorker.js',
},
})

// http://karma-runner.github.io/6.3/config/files.html
// 'All of the relative patterns will get resolved using the basePath first.', where basePath is set by KGP to `node_modules`
config.files.push('./mockServiceWorker.js')
// 'All of the relative patterns will get resolved using the basePath first.', where basePath is NOT set by KGP to `node_modules` after migration to 1.9
config.files.push('./node_modules/mockServiceWorker.js')
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
@file:Suppress("FILE_NAME_MATCH_CLASS", "HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE")
@file:JsModule("@react-sigma/layout-circular")
@file:JsNonModule

package com.saveourtool.save.frontend.externals.graph.sigma.layouts

import react.*

/**
* @param settings
* @return [LayoutInstance] with positions and assign functions
*/
@JsName("useLayoutCircular")
@JsModule("@react-sigma/layout-circular")
@JsNonModule
@JsExport
external fun useLayoutCircular(settings: dynamic = definedExternally): LayoutInstance
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
@file:Suppress("FILE_NAME_MATCH_CLASS", "HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE")
@file:JsModule("@react-sigma/layout-forceatlas2")
@file:JsNonModule

package com.saveourtool.save.frontend.externals.graph.sigma.layouts

import react.*

/**
* @param settings
* @return [LayoutInstance] with positions and assign functions
*/
@JsName("useLayoutForceAtlas2")
@JsModule("@react-sigma/layout-forceatlas2")
@JsNonModule
@JsExport
external fun useLayoutForceAtlas2(settings: dynamic = definedExternally): LayoutInstance
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
@file:Suppress("FILE_NAME_MATCH_CLASS", "HEADER_MISSING_IN_NON_SINGLE_CLASS_FILE")
@file:JsModule("@react-sigma/layout-random")
@file:JsNonModule

package com.saveourtool.save.frontend.externals.graph.sigma.layouts

import react.*

/**
* @param settings
* @return [LayoutInstance] with positions and assign functions
*/
@JsName("useLayoutRandom")
@JsModule("@react-sigma/layout-random")
@JsNonModule
@JsExport
external fun useLayoutRandom(settings: dynamic = definedExternally): LayoutInstance
Loading