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

INN-3321 - Config options builder #54

Merged
merged 13 commits into from
Jul 22, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,42 @@ package com.inngest.testserver
import com.inngest.*
import java.time.Duration


@FunctionConfig(id = "ProcessAlbum", name = "ProcessAlbum")
@FunctionEventTrigger(event = "delivery/process.requested")
class ProcessAlbum : InngestFunction() {

override fun config(builder: InngestFunctionConfigBuilder): InngestFunctionConfigBuilder {
return builder
.name("Process Album!")
.triggerEvent("delivery/process.requested")
.triggerCron("5 0 * 8 *")
.trigger(
InngestFunctionTriggers.Cron("5 0 * 8 *"))
.batchEvents(30, Duration.ofSeconds(10))
}

override fun execute(
ctx: FunctionContext,
step: Step,
): LinkedHashMap<String, Any> {

// NOTE - App ID is set on the serve level
val res = step.invoke<Map<String, Any>>(
"restore-album",
"ktor-dev",
"RestoreFromGlacier",
mapOf("some-arg" to "awesome"),
null,
// val list = ctx.events.map { e -> e.data.get("something") }
// println(list);


for (evt in ctx.events) {
// println(evt);
// NOTE - App ID is set on the serve level
val res = step.invoke<Map<String, Any>>(
"restore-album-${evt.data.get("albumId")}",
"ktor-dev",
"RestoreFromGlacier",
evt.data,
null,
)
}

// throw NonRetriableError("Could not restore")
return linkedMapOf("hello" to true)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,16 @@ package com.inngest.testserver
import com.inngest.*
import java.time.Duration

@FunctionConfig(id = "RestoreFromGlacier", name = "RestoreFromGlacier")
@FunctionEventTrigger(event = "delivery/restore.requested")
//@FunctionConfig(id = "RestoreFromGlacier", name = "RestoreFromGlacier")
class RestoreFromGlacier : InngestFunction() {

override fun config(builder: InngestFunctionConfigBuilder): InngestFunctionConfigBuilder {
return builder
.id("RestoreFromGlacier")
.name("Restore from Glacier")
.trigger(InngestFunctionTriggers.Event("delivery/restore.requested"))
}

override fun execute(
ctx: FunctionContext,
step: Step,
Expand Down
19 changes: 15 additions & 4 deletions inngest/src/main/kotlin/com/inngest/Comm.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ data class ExecutionContext(
val env: String,
)

internal data class RegistrationRequestPayload(
internal data class RegistrationRequestPayload @JvmOverloads constructor(
val appName: String,
val deployType: String = "ping",
val framework: String,
Expand Down Expand Up @@ -60,8 +60,6 @@ class CommHandler(
functionId: String,
requestBody: String,
): CommResponse {
println(requestBody)

try {
val payload = Klaxon().parse<ExecutionRequestPayload>(requestBody)
// TODO - check that payload is not null and throw error
Expand Down Expand Up @@ -112,6 +110,19 @@ class CommHandler(
return mapper.writeValueAsString(requestBody)
}

private fun serializePayload(payload: Any?): String {
try {
return Klaxon()
.fieldConverter(KlaxonDuration::class, durationConverter)
.toJsonString(payload)
} catch (e: Exception) {
println(e);
return """{ "message": "failed serialization" }"""
}

}


private fun getFunctionConfigs(origin: String): List<InternalFunctionConfig> {
val configs: MutableList<InternalFunctionConfig> = mutableListOf()
functions.forEach { entry -> configs.add(entry.value.getFunctionConfig(getServeUrl(origin), client)) }
Expand Down Expand Up @@ -149,7 +160,7 @@ class CommHandler(

fun introspect(origin: String): String {
val requestPayload = getRegistrationRequestPayload(origin)
return parseRequestBody(requestPayload)
return serializePayload(requestPayload)
}

private fun getRegistrationRequestPayload(origin: String): RegistrationRequestPayload {
Expand Down
1 change: 1 addition & 0 deletions inngest/src/main/kotlin/com/inngest/Event.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.inngest

data class Event(
val id: String,
val name: String,
val data: LinkedHashMap<String, Any>,
val user: LinkedHashMap<String, Any>? = null,
Expand Down
61 changes: 21 additions & 40 deletions inngest/src/main/kotlin/com/inngest/Function.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import java.util.function.BiFunction
// IDEA: Use data classes
internal data class InternalFunctionOptions(
val id: String,
val name: String,
val config: Map<String, Any>,
val triggers: Array<InternalFunctionTrigger>,
)

internal data class InternalFunctionTrigger
internal open class InternalFunctionTrigger
@JvmOverloads
constructor(
@Json(serializeNull = false) val event: String? = null,
Expand Down Expand Up @@ -77,12 +77,18 @@ data class StepConfig(
val runtime: HashMap<String, String> = hashMapOf("type" to "http"),
)

internal data class InternalFunctionConfig(
class InternalFunctionConfig @JvmOverloads constructor(
val id: String,
val name: String,
val triggers: Array<InternalFunctionTrigger>,
val name: String?,
val triggers: MutableList<InngestFunctionTrigger>,
@Json(serializeNull = false)
val batchEvents: BatchEvents?,
val steps: Map<String, StepConfig>,
)
) {
}
// NOTE - This should probably be called serialized or formatted config
// as it's only used to format the config for register requests
//typealias InternalFunctionConfig = Map<String, Any>

/**
* The context for the current function run
Expand Down Expand Up @@ -110,21 +116,21 @@ data class SendEventPayload(val event_ids: Array<String>)

internal interface Function {
fun id(): String

fun config(): InternalFunctionConfig
}


// TODO: make this implement the Function interface
internal open class InternalInngestFunction(
val config: InternalFunctionOptions,
private val configBuilder: InngestFunctionConfigBuilder,
val handler: (ctx: FunctionContext, step: Step) -> Any?,
) {
constructor(config: InternalFunctionOptions, handler: BiFunction<FunctionContext, Step, out Any>) : this(
config,
constructor(configBuilder: InngestFunctionConfigBuilder, handler: BiFunction<FunctionContext, Step, out Any>) : this(
configBuilder,
handler.toKotlin(),
)

fun id() = config.id
// fun id() = config.get("id")
fun id() = configBuilder.id

// TODO - Validate options and trigger

Expand All @@ -137,7 +143,7 @@ internal open class InternalInngestFunction(
val step = Step(state, client)

// DEBUG
println(state)
// println(state)

try {
val data = handler(ctx, step)
Expand Down Expand Up @@ -218,32 +224,7 @@ internal open class InternalInngestFunction(
}

fun getFunctionConfig(serveUrl: String, client: Inngest): InternalFunctionConfig {
// TODO use URL objects instead of strings so we can fetch things like scheme
val scheme = serveUrl.split("://")[0]
return InternalFunctionConfig(
id = String.format("%s-%s", client.appId, config.id),
name = config.name,
triggers = config.triggers,
steps =
mapOf(
"step" to
StepConfig(
id = "step",
name = "step",
retries =
mapOf(
// TODO - Pull from FunctionOptions
"attempts" to 3,
),
runtime =
hashMapOf(
"type" to scheme,
// TODO - Create correct URL
"url" to
"$serveUrl?fnId=${config.id}&stepId=step",
),
),
),
)
// TODO use URL objects for serveUrl instead of strings so we can fetch things like scheme
return configBuilder.build(client.appId, serveUrl)
}
}
4 changes: 3 additions & 1 deletion inngest/src/main/kotlin/com/inngest/HttpClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ internal class HttpClient(private val clientConfig: RequestConfig) {
payload: Any,
config: RequestConfig? = null,
): okhttp3.Request {
val jsonRequestBody = Klaxon().toJsonString(payload)
val jsonRequestBody = Klaxon()
.fieldConverter(KlaxonDuration::class, durationConverter)
.toJsonString(payload)
val body = jsonRequestBody.toRequestBody(jsonMediaType)

val clientHeaders = clientConfig.headers ?: emptyMap()
Expand Down
33 changes: 22 additions & 11 deletions inngest/src/main/kotlin/com/inngest/InngestFunction.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package com.inngest

import com.beust.klaxon.Converter
import com.beust.klaxon.Json
import com.beust.klaxon.JsonValue
import com.beust.klaxon.KlaxonException
import java.time.Duration

@Target(AnnotationTarget.CLASS)
@MustBeDocumented
Expand Down Expand Up @@ -29,7 +33,16 @@ annotation class FunctionIfTrigger(
@Json(serializeNull = false) val `if`: String,
)


abstract class InngestFunction {

// abstract val id: String;


open fun config(builder: InngestFunctionConfigBuilder): InngestFunctionConfigBuilder {
return builder
}

abstract fun execute(
ctx: FunctionContext,
step: Step,
Expand All @@ -45,18 +58,13 @@ abstract class InngestFunction {
}

internal fun toInngestFunction(): InternalInngestFunction {
if (config == null || config !is FunctionConfig) {
throw Exception("FunctionConfig annotation is required to setup an InngestFunction")
}
// if (config == null || config !is FunctionConfig) {
// throw Exception("FunctionConfig annotation is required to setup an InngestFunction")
// }
val triggers = buildEventTriggers() + buildCronTriggers() + buildIfTriggers()
val fnConfig =
InternalFunctionOptions(
id = config.id,
name = config.name,
triggers = triggers.toTypedArray(),
)

return InternalInngestFunction(fnConfig, this::execute)
val builder = InngestFunctionConfigBuilder()
val configBuilder = this.config(builder)
return InternalInngestFunction(configBuilder, this::execute)
}

// TODO: DRY this
Expand All @@ -72,3 +80,6 @@ abstract class InngestFunction {
this::class.annotations.filter { it.annotationClass == FunctionIfTrigger::class }
.map { InternalFunctionTrigger(event = (it as FunctionIfTrigger).`if`) }
}



Loading
Loading