Skip to content

Commit

Permalink
Implement execution delegation
Browse files Browse the repository at this point in the history
  • Loading branch information
ertugrulkaragoz1 committed Jun 28, 2024
1 parent f8df1c8 commit ea7e295
Show file tree
Hide file tree
Showing 11 changed files with 191 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ import com.trendyol.transmission.transformer.Transformer
import com.trendyol.transmission.transformer.dataholder.buildDataHolder
import com.trendyol.transmission.transformer.handler.buildGenericEffectHandler
import com.trendyol.transmission.transformer.request.buildComputationContract
import com.trendyol.transmission.transformer.request.buildExecutionContract
import com.trendyol.transmission.transformer.request.computation.registerComputation
import com.trendyol.transmission.transformer.request.execution.registerExecution
import com.trendyol.transmission.ui.ColorPickerUiState
import com.trendyol.transmission.ui.OutputUiState
import com.trendyol.transmission.ui.theme.Pink80
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.delay
import javax.inject.Inject
Expand All @@ -35,6 +38,10 @@ class OutputTransformer @Inject constructor(
val result = Random.nextInt(5, 15) * Random.nextInt(5, 15)
OutputCalculationResult("result is $result with ($writtenOutput) and $data")
}
registerExecution(outputExecutionContract) {
delay(4.seconds)
communicationScope.publish(ColorPickerEffect.BackgroundColorUpdate(Pink80))
}
}

override val effectHandler = buildGenericEffectHandler { effect ->
Expand All @@ -52,6 +59,7 @@ class OutputTransformer @Inject constructor(
effect = ColorPickerEffect.BackgroundColorUpdate(holder2.getValue().backgroundColor),
to = ColorPickerTransformer::class
)
execute(outputExecutionContract)
publish(effect = RouterEffect(holder.getValue()))
}

Expand All @@ -64,5 +72,7 @@ class OutputTransformer @Inject constructor(
companion object {
val outputCalculationContract =
buildComputationContract<OutputCalculationResult>("OutputCalculationResult")
val outputExecutionContract =
buildExecutionContract("outputExecutionContract")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,4 @@ class ColorPickerTransformerTest {
assertTrue { effectStream.last().effect is ColorPickerEffect.SelectedColorUpdate }
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import kotlinx.coroutines.launch
internal class TestRouter(
private val registry: RegistryScopeImpl,
private val transformer: Transformer,
private val dispatcher: CoroutineDispatcher
dispatcher: CoroutineDispatcher
) {
private val testScope = CoroutineScope(dispatcher)

Expand Down Expand Up @@ -83,8 +83,8 @@ internal class TestRouter(
is Query.Computation -> processComputationQuery(query)
is Query.Data -> processDataQuery(query)
is Query.ComputationWithArgs<*> -> processComputationQueryWithArgs(query)
is Query.Execution -> TODO()
is Query.ExecutionWithArgs<*> -> TODO()
is Query.Execution -> {}
is Query.ExecutionWithArgs<*> -> {}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import com.trendyol.transmission.transformer.request.Contract
import com.trendyol.transmission.transformer.request.Query
import com.trendyol.transmission.transformer.request.QueryResult
import com.trendyol.transmission.transformer.request.RequestHandler
import com.trendyol.transmission.transformer.request.computation.ComputationOwner
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
import kotlinx.coroutines.channels.Channel
Expand Down Expand Up @@ -45,8 +44,8 @@ internal class RequestDelegate(
is Query.Computation -> processComputationQuery(query)
is Query.Data -> processDataQuery(query)
is Query.ComputationWithArgs<*> -> processComputationQueryWithArgs(query)
is Query.Execution -> TODO()
is Query.ExecutionWithArgs<*> -> TODO()
is Query.Execution -> processExecution(query)
is Query.ExecutionWithArgs<*> -> processExecutionWithArgs(query)
}
}

Expand Down Expand Up @@ -116,6 +115,23 @@ internal class RequestDelegate(
}
}

private fun processExecution(
query: Query.Execution
) = queryScope.launch {
val executionHolder = routerRef.transformerSet
.find { it.storage.hasExecution(query.key) }
executionHolder?.storage?.getExecutionByKey(query.key)
?.execute(executionHolder.communicationScope)
}

private fun <A : Any> processExecutionWithArgs(query: Query.ExecutionWithArgs<A>) =
queryScope.launch {
val executionHolder = routerRef.transformerSet
.find { it.storage.hasExecution(query.key) }
executionHolder?.storage?.getExecutionByKey<A>(query.key)
?.execute(executionHolder.communicationScope, query.args)
}

override suspend fun <C : Contract.Data<D>, D : Transmission.Data> getData(contract: C): D? {
outGoingQuery.trySend(
Query.Data(sender = routerRef.routerName, key = contract.key)
Expand Down Expand Up @@ -162,15 +178,25 @@ internal class RequestDelegate(
.first().data
}

override suspend fun <C : Contract.Execution> execute(contract: C, invalidate: Boolean) {
TODO("Not yet implemented")
override suspend fun <C : Contract.Execution> execute(contract: C) {
outGoingQuery.trySend(
Query.Execution(
sender = routerRef.routerName,
key = contract.key,
)
)
}

override suspend fun <C : Contract.ExecutionWithArgs<A>, A : Any> execute(
contract: C,
args: A,
invalidate: Boolean
args: A
) {
TODO("Not yet implemented")
outGoingQuery.trySend(
Query.ExecutionWithArgs(
sender = routerRef.routerName,
key = contract.key,
args = args,
)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,14 @@ internal class CommunicationScopeBuilder(
return requestDelegate.interactor.compute(contract, args, invalidate)
}

override suspend fun <C : Contract.Execution> execute(contract: C, invalidate: Boolean) {
TODO("Not yet implemented")
override suspend fun <C : Contract.Execution> execute(contract: C) {
requestDelegate.interactor.execute(contract)
}

override suspend fun <C : Contract.ExecutionWithArgs<A>, A : Any> execute(
contract: C,
args: A,
invalidate: Boolean
args: A
) {
TODO("Not yet implemented")
requestDelegate.interactor.execute(contract, args)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.trendyol.transmission.Transmission
import com.trendyol.transmission.identifier
import com.trendyol.transmission.transformer.dataholder.HolderState
import com.trendyol.transmission.transformer.request.computation.ComputationOwner
import com.trendyol.transmission.transformer.request.execution.ExecutionOwner
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update

Expand All @@ -17,6 +18,9 @@ internal class TransformerStorage {
private val internalComputationMap: MutableMap<String, ComputationOwner> =
mutableMapOf()

private val internalExecutionMap: MutableMap<String, ExecutionOwner> =
mutableMapOf()

fun isHolderStateInitialized(): Boolean {
return internalTransmissionHolderSet is HolderState.Initialized
}
Expand All @@ -34,7 +38,6 @@ internal class TransformerStorage {
}

fun updateHolderDataReferenceToTrack(dataHolderToTrack: String) {

internalTransmissionHolderSet = when (internalTransmissionHolderSet) {
is HolderState.Initialized -> {
val currentSet = (internalTransmissionHolderSet as HolderState.Initialized).valueSet
Expand All @@ -57,18 +60,37 @@ internal class TransformerStorage {
internalComputationMap[key] = delegate
}

fun registerExecution(key: String, delegate: ExecutionOwner) {
require(!internalExecutionMap.containsKey(key)) {
"Multiple executions with the same key is not allowed: $key"
}
internalExecutionMap[key] = delegate
}

fun hasComputation(type: String): Boolean {
return internalComputationMap.containsKey(type)
}

fun hasExecution(type: String): Boolean {
return internalExecutionMap.containsKey(type)
}

fun getComputationByKey(type: String): ComputationOwner.Default? {
return internalComputationMap[type] as? ComputationOwner.Default
}

fun<A: Any> getComputationByKey(type: String): ComputationOwner.WithArgs<A>? {
fun getExecutionByKey(type: String): ExecutionOwner.Default? {
return internalExecutionMap[type] as? ExecutionOwner.Default
}

fun <A : Any> getComputationByKey(type: String): ComputationOwner.WithArgs<A>? {
return internalComputationMap[type] as? ComputationOwner.WithArgs<A>
}

fun <A : Any> getExecutionByKey(type: String): ExecutionOwner.WithArgs<A>? {
return internalExecutionMap[type] as? ExecutionOwner.WithArgs<A>
}

fun getHolderDataByKey(key: String): Transmission.Data? {
return holderDataReference.value[key]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,26 @@ internal class TransformerRequestDelegate(scope: CoroutineScope, identifier: Str
.first().data
}

override suspend fun <C : Contract.Execution> execute(contract: C, invalidate: Boolean) {
TODO("Not yet implemented")
override suspend fun <C : Contract.Execution> execute(contract: C) {
outGoingQuery.trySend(
Query.Execution(
sender = identifier,
key = contract.key,
)
)
}

override suspend fun <C : Contract.ExecutionWithArgs<A>, A : Any> execute(
contract: C,
args: A,
invalidate: Boolean
args: A
) {
TODO("Not yet implemented")
outGoingQuery.trySend(
Query.ExecutionWithArgs(
sender = identifier,
key = contract.key,
args = args,
)
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.trendyol.transmission.transformer.request.execution

import com.trendyol.transmission.transformer.Transformer
import com.trendyol.transmission.transformer.request.RequestHandler

class ExecutionBuilder {

fun buildWith(
key: String,
transformer: Transformer,
execution: suspend RequestHandler.() -> Unit
) {
transformer.storage.registerExecution(
key = key,
delegate = ExecutionDelegate(execution)
)
}

fun <A : Any> buildWith(
key: String,
transformer: Transformer,
execution: suspend RequestHandler.(args: A) -> Unit
) {
transformer.storage.registerExecution(
key = key,
delegate = ExecutionDelegateWithArgs(execution)
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.trendyol.transmission.transformer.request.execution

import com.trendyol.transmission.transformer.request.RequestHandler

internal class ExecutionDelegate(
private val execution: suspend RequestHandler.() -> Unit,
) : ExecutionOwner.Default {

override suspend fun execute(scope: RequestHandler) {
execution.invoke(scope)
}
}

internal class ExecutionDelegateWithArgs<A : Any>(
private val execution: suspend RequestHandler.(args: A) -> Unit,
) : ExecutionOwner.WithArgs<A> {

override suspend fun execute(scope: RequestHandler, args: A) {
execution(scope, args)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.trendyol.transmission.transformer.request.execution

import com.trendyol.transmission.Transmission
import com.trendyol.transmission.transformer.Transformer
import com.trendyol.transmission.transformer.request.Contract
import com.trendyol.transmission.transformer.request.RequestHandler

/**
* Throws [IllegalArgumentException] when multiple executions with the same key
* are defined inside the [Transformer].
*
* Adds a execution to [Transformer] to be queried that returns Unit.
* Can be queried using [RequestHandler.execute]
* @param execution execution to get the result [Transmission.Data]
*/
fun <C : Contract.Execution> Transformer.registerExecution(
contract: C,
execution: suspend RequestHandler.() -> Unit,
) {
ExecutionBuilder().buildWith(contract.key, this, execution)
}

/**
* Throws [IllegalArgumentException] when multiple executions with the same key
* are defined inside the [Transformer].
*
* Adds a execution to [Transformer] to be queried. This execution accepts any class as Argument
* that returns Unit.
* Can be queried using [RequestHandler.execute]
* @param execution execution to get the result [Transmission.Data]
*/
fun <C : Contract.ExecutionWithArgs<A>, A : Any> Transformer.registerExecution(
contract: C,
execution: suspend RequestHandler.(args: A) -> Unit,
) {
ExecutionBuilder().buildWith(contract.key, this, execution)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.trendyol.transmission.transformer.request.execution

import com.trendyol.transmission.transformer.request.RequestHandler

internal sealed interface ExecutionOwner {

interface WithArgs<A : Any> : ExecutionOwner {
suspend fun execute(scope: RequestHandler, args: A)
}

interface Default : ExecutionOwner {
suspend fun execute(scope: RequestHandler)
}
}

0 comments on commit ea7e295

Please sign in to comment.