Interface CallableByActionName
- All Known Implementing Classes:
AccumulatorIIAR,DynamicActorLoaderActor,IIActorRef,InterpreterIIAR,RemoteActorRef,ReusableSubWorkflowCaller,Scheduler,SchedulerIIAR,SubWorkflowCaller
This interface enables flexible, data-driven execution of actor methods using string-based action names, eliminating the need for compile-time coupling to specific method signatures. This design is particularly valuable for:
- Workflow execution: Actions defined in YAML/JSON can invoke actor methods
- Distributed systems: Action names and arguments can be serialized and sent across network
- Plugin systems: Dynamic plugins can expose capabilities without reflection
- Configuration-driven behavior: Change behavior by modifying external configuration
Design Philosophy
Unlike traditional reflection-based approaches where method information is discovered at runtime, this interface requires plugin authors to explicitly declare and implement their action handling. This provides several advantages:
- No reflection overhead after initial load
- Clear contract for supported actions
- String-based serialization for distributed systems
- Better GraalVM Native Image compatibility (action handling code is explicit)
Usage Example
Simple Plugin
public class MathPlugin implements CallableByActionName {
private int lastResult = 0;
@Override
public ActionResult callByActionName(String actionName, String args) {
switch (actionName) {
case "add":
String[] parts = args.split(",");
int a = Integer.parseInt(parts[0]);
int b = Integer.parseInt(parts[1]);
lastResult = a + b;
return new ActionResult(true, String.valueOf(lastResult));
case "multiply":
parts = args.split(",");
a = Integer.parseInt(parts[0]);
b = Integer.parseInt(parts[1]);
lastResult = a * b;
return new ActionResult(true, String.valueOf(lastResult));
case "getLastResult":
return new ActionResult(true, String.valueOf(lastResult));
default:
return new ActionResult(false, "Unknown action: " + actionName);
}
}
}
With Actor System
ActorSystem system = new ActorSystem("system", 4);
ActorRef<MathPlugin> mathActor = system.actorOf("math", new MathPlugin());
// Direct invocation (type-safe)
mathActor.tell(m -> m.add(5, 3));
// String-based invocation (for workflows, distributed systems)
mathActor.tell(m -> m.callByActionName("add", "5,3"));
YAML Workflow Example
# workflow.yaml
actions:
- [math, add, "5,3"]
- [math, multiply, "4,2"]
- [math, getLastResult, ""]
Distributed System Support
The string-based nature of this interface makes it ideal for distributed actor systems. Actions can be serialized and sent across network boundaries:
// JSON message sent to remote node
{
"targetNode": "node2",
"actor": "math",
"action": "add",
"args": "5,3"
}
Comparison with Reflection Approach
| Aspect | CallableByActionName | Reflection |
|---|---|---|
| Performance | Fast (switch statement) | Slower (method lookup) |
| Native Image | Compatible | Requires configuration |
| Serialization | Built-in (strings) | Complex |
| Plugin Author Effort | Must implement interface | No code needed |
| Discovery | Explicit declaration | Automatic |
- Since:
- 2.0.0, 2.0.0
- Author:
- devteam@scivics-lab.com
- See Also:
-
Method Summary
Modifier and TypeMethodDescriptioncallByActionName(String actionName, String args) Executes an action identified by its name with the given arguments.
-
Method Details
-
callByActionName
Executes an action identified by its name with the given arguments.Implementations should parse the
argsstring according to their own conventions. Common approaches include:- Comma-separated values:
"5,3" - JSON:
"{\"a\":5,\"b\":3}" - Key-value pairs:
"a=5,b=3"
The method should return an
ActionResultindicating success or failure, along with any result data serialized as a string.- Parameters:
actionName- the name of the action to executeargs- string arguments to pass to the action (format defined by implementation)- Returns:
- an
ActionResultindicating success or failure and any result data
- Comma-separated values:
-