feat: let initiators withdraw running process instances

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
0264408
2026-09-11 16:39:17 +08:00
co-authored by Cursor
parent 946c9d3c52
commit 87b449e45c
15 changed files with 213 additions and 4 deletions
@@ -3,6 +3,7 @@ package com.jetlumen.ordo.spring;
import com.jetlumen.ordo.api.OrdoEngine;
import com.jetlumen.ordo.api.ProcessDefinition;
import com.jetlumen.ordo.api.ProcessDefinitionParser;
import com.jetlumen.ordo.api.exception.DefinitionInUseException;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.io.Resource;
@@ -48,7 +49,11 @@ public final class OrdoDefinitionLoader implements ApplicationRunner {
} catch (RuntimeException e) {
throw new IllegalStateException("failed to parse ordo definition from " + describe(resource), e);
}
engine.replace(definition);
try {
engine.replace(definition);
} catch (DefinitionInUseException ignored) {
// keep the stored graph while RUNNING instances still reference it
}
}
}
@@ -111,6 +111,24 @@ class OrdoJdbcAutoConfigurationTest {
});
}
@Test
void keepsStoredDefinitionWhenReloadFindsRunningInstances() {
withDataSourceRunner.run(context -> {
OrdoEngine engine = context.getBean(OrdoEngine.class);
engine.replace(ProcessDefinition.linear("leave-request-routed", "stale", List.of(
ApprovalStep.single("lead", "Lead approval", "lee"))));
engine.start("leave-request-routed", "alice");
context.getBean(OrdoDefinitionLoader.class).load();
ProcessDefinition definition = context.getBean(ProcessDefinitionRepository.class)
.findById("leave-request-routed")
.orElseThrow();
assertThat(definition.name()).isEqualTo("stale");
assertThat(definition.steps()).hasSize(1);
});
}
@Test
void honoursUserDefinedRoutingCondition() {
withDataSourceRunner.withUserConfiguration(CustomRoutingConditionConfig.class)