Skip to content

Commit

Permalink
Fix hashing step ids in loops
Browse files Browse the repository at this point in the history
Per https://github.com/inngest/inngest/blob/main/docs/SDK_SPEC.md#512-ids-and-hashing,
add `:n` starting with `:1` for repeated instances of a step id

Mostly similar to inngest-js implementation
https://github.com/inngest/inngest-js/blob/79069e1a3d700624ce49b323922c113fc952bcc6/packages/inngest/src/components/execution/v1.ts#L819-L831

The inngest-js SDK currently optionally warns of parallel indexing, but
this isn't in scope for beta so I left it out
  • Loading branch information
albertchae committed Sep 6, 2024
1 parent 593f8db commit 10f39be
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.inngest.springbootdemo.testfunctions;

import com.inngest.FunctionContext;
import com.inngest.InngestFunction;
import com.inngest.InngestFunctionConfigBuilder;
import com.inngest.Step;
import org.jetbrains.annotations.NotNull;

public class LoopFunction extends InngestFunction {

@NotNull
@Override
public InngestFunctionConfigBuilder config(InngestFunctionConfigBuilder builder) {
return builder
.id("loop-fn")
.name("Loop Function")
.triggerEvent("test/loop");
}


@Override
public Integer execute(FunctionContext ctx, Step step) {
int runningCount = 10;
for (int i = 0; i < 5; i++) {
int effectivelyFinalVariableForLambda = runningCount;
runningCount = step.run("add-ten", () -> effectivelyFinalVariableForLambda + 10, Integer.class);
}

return runningCount;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ protected HashMap<String, InngestFunction> functions() {
addInngestFunction(functions, new InvokeFailureFunction());
addInngestFunction(functions, new TryCatchRunFunction());
addInngestFunction(functions, new ThrottledFunction());
addInngestFunction(functions, new LoopFunction());

return functions;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.inngest.springbootdemo;

import com.inngest.Inngest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.parallel.Execution;
import org.junit.jupiter.api.parallel.ExecutionMode;
import org.springframework.beans.factory.annotation.Autowired;

import static org.junit.jupiter.api.Assertions.assertEquals;

@IntegrationTest
@Execution(ExecutionMode.CONCURRENT)
class LoopFunctionIntegrationTest {
@Autowired
private DevServerComponent devServer;

@Autowired
private Inngest client;

@Test
void testStepsInLoopExecuteCorrectly() throws Exception {
String loopEvent = InngestFunctionTestHelpers.sendEvent(client, "test/loop").first();
Thread.sleep(2000);

RunEntry<Object> loopRun = devServer.runsByEvent(loopEvent).first();
assertEquals("Completed", loopRun.getStatus());

assertEquals(60, loopRun.getOutput());
}
}
25 changes: 24 additions & 1 deletion inngest/src/main/kotlin/com/inngest/State.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,17 @@ class StateNotFound : Throwable("State not found for id")
class State(
private val payloadJson: String,
) {
private val stepIds = mutableSetOf<String>()

fun getHashFromId(id: String): String {
val bytes = id.toByteArray(Charsets.UTF_8)
val idToHash: String =
if (id in stepIds) {
findNextAvailableStepId(id)
} else {
id
}
stepIds.add(idToHash)
val bytes = idToHash.toByteArray(Charsets.UTF_8)
val digest = MessageDigest.getInstance("SHA-1")
val hashedBytes = digest.digest(bytes)
val sb = StringBuilder()
Expand All @@ -20,6 +29,20 @@ class State(
return sb.toString()
}

private fun findNextAvailableStepId(id: String): String {
var stepNumber = 1
var possibleStepId: String
while (true) {
possibleStepId = "$id:$stepNumber"
if (possibleStepId !in stepIds) {
break
}
stepNumber++
}

return possibleStepId
}

inline fun <reified T> getState(
hashedId: String,
fieldName: String = "data",
Expand Down

0 comments on commit 10f39be

Please sign in to comment.