All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.lemfi.kest.cadence.executor.WorkflowExecution.kt Maven / Gradle / Ivy

There is a newer version: 0.8.1
Show newest version
package com.github.lemfi.kest.cadence.executor

import com.github.lemfi.kest.core.model.Execution
import com.uber.cadence.client.WorkflowClient
import com.uber.cadence.client.WorkflowOptions
import com.uber.cadence.common.RetryOptions
import com.uber.cadence.context.ContextPropagator
import com.uber.cadence.worker.Worker
import com.uber.cadence.worker.WorkerOptions
import org.opentest4j.AssertionFailedError
import java.time.Duration
import kotlin.reflect.KFunction
import kotlin.reflect.javaType

class WorkflowExecution(
        private val cadenceHost: String,
        private val cadencePort: Int,
        private val cadenceDomain: String,
        private val tasklist: String,

        private val workflow: KFunction,
        private val params: Array?,

        private val activities: List>?,
        private val contextPropagators: List?,

        override val withResult: RESULT.()->Unit = {},

        ): Execution() {

    @ExperimentalStdlibApi
    @Suppress("unchecked_cast")
    override fun execute(): RESULT {

        val workflowClass = Class.forName(workflow.parameters[0].type::javaType.get().typeName)

        activities
                ?.map { it.second }
                ?.toSet()
                ?.let {
                    it.forEach { tasklist ->
                        Worker.Factory(cadenceHost, cadencePort, cadenceDomain).apply {
                            val worker = newWorker(tasklist, WorkerOptions
                                    .Builder()
                                    .setReportActivityFailureRetryOptions(RetryOptions.Builder()
                                            .setInitialInterval(Duration.ofSeconds(5))
                                            .setExpiration(Duration.ofSeconds(30))
                                            .setMaximumInterval(Duration.ofSeconds(10))
                                            .setMaximumAttempts(2)
                                            .build())
                                    .build())

                            worker.registerActivitiesImplementations(*activities.filter { it.second == tasklist }.map { it.first }.toTypedArray())

                        }.start()
                    }
                }


        val parameterTypes = workflow.parameters.subList(1, workflow.parameters.size).also {
            if ((params?.size
                            ?: 0) != it.size) throw AssertionFailedError("Wrong number of parameter for activity, expected [${it.map { it.type }.joinToString(", ")}] got ${params?.toList()}")
        }.map { Class.forName(it.type::javaType.get().typeName) }.takeIf { it.isNotEmpty() }

        val method = parameterTypes?.let { workflowClass.getMethod(workflow.name, *parameterTypes.toTypedArray()) }
                ?: workflowClass.getMethod(workflow.name)

        return WorkflowClient.newInstance(cadenceHost, cadencePort, cadenceDomain)
                .newWorkflowStub(workflowClass, WorkflowOptions.Builder()
                        .setExecutionStartToCloseTimeout(Duration.ofMinutes(3))
                        .apply {
                            contextPropagators?.let {
                                setContextPropagators(it)
                            }
                        }
                        .setTaskList(tasklist)
                        .build()).let {

                    if (params != null) {
                        method.invoke(it, *params)
                    } else {
                        method.invoke(it)
                    }
                } as RESULT
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy