feat: add TEST_EXPRESSION command with request-reply infrastructure
Adds CompletableFuture-based request-reply mechanism for commands that need synchronous results. CommandReply record in core, pendingReplies map in AgentRegistryService, test-expression endpoint on config controller with 5s timeout. CommandAckRequest extended with optional data field. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -30,6 +31,7 @@ public class AgentRegistryService {
|
||||
|
||||
private final ConcurrentHashMap<String, AgentInfo> agents = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<String, ConcurrentLinkedQueue<AgentCommand>> commands = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<String, CompletableFuture<CommandReply>> pendingReplies = new ConcurrentHashMap<>();
|
||||
|
||||
private volatile AgentEventListener eventListener;
|
||||
|
||||
@@ -279,6 +281,31 @@ public class AgentRegistryService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a command that expects a synchronous reply from the agent.
|
||||
* Returns a CompletableFuture that will be completed when the agent ACKs the command.
|
||||
* Auto-cleans up from the pending map on completion or timeout.
|
||||
*/
|
||||
public CompletableFuture<CommandReply> addCommandWithReply(String agentId, CommandType type, String payload) {
|
||||
AgentCommand command = addCommand(agentId, type, payload);
|
||||
CompletableFuture<CommandReply> future = new CompletableFuture<>();
|
||||
pendingReplies.put(command.id(), future);
|
||||
future.whenComplete((result, ex) -> pendingReplies.remove(command.id()));
|
||||
return future;
|
||||
}
|
||||
|
||||
/**
|
||||
* Complete a pending reply future for a command.
|
||||
* Called when an agent ACKs a command that was registered via {@link #addCommandWithReply}.
|
||||
* No-op if no pending future exists for the given command ID.
|
||||
*/
|
||||
public void completeReply(String commandId, String status, String message, String data) {
|
||||
CompletableFuture<CommandReply> future = pendingReplies.remove(commandId);
|
||||
if (future != null) {
|
||||
future.complete(new CommandReply(status, message, data));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the event listener for command notifications.
|
||||
* The SSE layer in the app module implements this interface.
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.cameleer3.server.core.agent;
|
||||
|
||||
/**
|
||||
* Represents the reply data from an agent command acknowledgment.
|
||||
* Used for synchronous request-reply command patterns (e.g. TEST_EXPRESSION).
|
||||
*
|
||||
* @param status "SUCCESS" or "FAILURE"
|
||||
* @param message human-readable description of the result
|
||||
* @param data optional structured JSON data returned by the agent
|
||||
*/
|
||||
public record CommandReply(String status, String message, String data) {}
|
||||
@@ -7,5 +7,6 @@ public enum CommandType {
|
||||
CONFIG_UPDATE,
|
||||
DEEP_TRACE,
|
||||
REPLAY,
|
||||
SET_TRACED_PROCESSORS
|
||||
SET_TRACED_PROCESSORS,
|
||||
TEST_EXPRESSION
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user