Package com.scivicslab.pojoactor.core
Class ActorRef<T>
java.lang.Object
com.scivicslab.pojoactor.core.ActorRef<T>
- Type Parameters:
T- the type of the actor's underlying object
- All Implemented Interfaces:
AutoCloseable
- Direct Known Subclasses:
IIActorRef
A reference to an actor that provides messaging capabilities and lifecycle management.
This class implements the actor model pattern, allowing asynchronous message passing
between actors using tell() and ask() methods.
- Since:
- 1.0.0
- Author:
- devteam@scivics-lab.com
-
Field Summary
Fields -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescription<R> CompletableFuture<R> Sends a message to actor and returns a CompletableFuture to be completed with the response value.<R> CompletableFuture<R> ask(Function<T, R> action, ExecutorService ws) Sends a message to this actor and returns a response using a specific executor service.<R> CompletableFuture<R> Sends a message to the actor and returns a response, bypassing the mailbox and executing immediately.voidClears all JSON state for this actor.intClears all pending messages from this actor's message queue and WorkStealingPool.voidclose()Destroys the actor and cleans up its resources.<K> ActorRef<K> createChild(String actorName, K object) Creates a child actor under this actor's supervision.booleangetJsonBoolean(String path, boolean defaultValue) Convenience method to get a boolean from the JSON state.intgetJsonInt(String path, int defaultValue) Convenience method to get an integer from the JSON state.getJsonString(String path) Convenience method to get a string from the JSON state.getJsonString(String path, String defaultValue) Convenience method to get a string from the JSON state with default.getName()Returns the name of this actor.Returns the names of all child actors supervised by this actor.Returns the name of this actor's parent, if any.booleanConvenience method to check if a path exists in the JSON state.booleanChecks if this actor has any JSON state.voidinitLogger(String loggerName) Initializes the logger with the specified name.booleanisAlive()Checks if this actor is still alive and able to process messages.json()Returns the JSON state container for this actor, creating it if necessary.Convenience method to put a value into the JSON state.voidsetParentName(String parentName) Sets the parent name for this actor.system()Returns the actor system this actor belongs to.Sends a message to the actor defined by this reference.tell(Consumer<T> action, ExecutorService ws) Sends a message to this actor using a specific executor service.Sends a message to the actor for immediate execution, bypassing the normal message queue.
-
Field Details
-
actorName
-
object
-
actorSystem
-
-
Constructor Details
-
ActorRef
Constructs an ActorRef with the specified name and object.- Parameters:
actorName- the unique name for this actorobject- the object that will handle messages for this actor
-
ActorRef
Constructs an ActorRef with the specified name, object, and actor system.- Parameters:
actorName- the unique name for this actorobject- the object that will handle messages for this actoractorSystem- the actor system this actor belongs to
-
-
Method Details
-
createChild
Creates a child actor under this actor's supervision.- Type Parameters:
K- the type of the child actor's object- Parameters:
actorName- the unique name for the child actorobject- the object for the child actor- Returns:
- a reference to the created child actor
-
getNamesOfChildren
Returns the names of all child actors supervised by this actor.- Returns:
- a set containing the names of child actors
-
getParentName
Returns the name of this actor's parent, if any.- Returns:
- the parent actor's name, or null if this actor has no parent
-
isAlive
public boolean isAlive()Checks if this actor is still alive and able to process messages.- Returns:
- true if the actor is alive, false otherwise
-
setParentName
Sets the parent name for this actor.- Parameters:
parentName- the name of the parent actor
-
system
Returns the actor system this actor belongs to.- Returns:
- the actor system instance
-
getName
Returns the name of this actor.- Returns:
- the actor's unique name
-
initLogger
Initializes the logger with the specified name.- Parameters:
loggerName- the name for the logger
-
tell
Sends a message to the actor defined by this reference. The specified action is executed on the actor's object asynchronously in actor's thread context. This method does not wait for completion of the action, it returns immediately. Messages are processed in the order they are received (FIFO).- Parameters:
action- action to be executed on actor's object.- Returns:
- CompletableFuture that completes when the action finishes execution.
Usage Example:
// Create an actor ActorRef<Counter> counter = system.actorOf("counter", new Counter()); // Send a message to increment the counter CompletableFuture<Void> future = counter.tell(c -> c.increment()); // Send multiple messages (processed in order) counter.tell(c -> c.increment()); counter.tell(c -> c.increment()); counter.tell(c -> System.out.println("Counter value: " + c.getValue())); // Wait for completion if needed future.get(); // Blocks until the action completes
-
tellNow
Sends a message to the actor for immediate execution, bypassing the normal message queue. The specified action is executed immediately on a new virtual thread, without waiting for previously queued messages to complete. This allows for urgent/priority messages that need to be processed right away. Note: This method executes concurrently with regular tell() messages, so proper synchronization should be considered if the actor's state could be accessed simultaneously.- Parameters:
action- action to be executed on actor's object immediately.- Returns:
- CompletableFuture that completes when the immediate action finishes.
Usage Example:
// Create an actor and queue some regular messages ActorRef<Counter> counter = system.actorOf("counter", new Counter()); counter.tell(c -> { Thread.sleep(1000); c.increment(); }); // Long running task counter.tell(c -> c.increment()); // Queued after long task // Send urgent message that executes immediately (concurrently) CompletableFuture<Void> urgent = counter.tellNow(c -> { System.out.println("Emergency: Current value = " + c.getValue()); }); // The urgent message executes immediately, even while long task is running urgent.get(); // Completes quickly // Use case: Emergency shutdown, logging, monitoring counter.tellNow(c -> logger.warning("Actor overloaded!"));
-
ask
Sends a message to actor and returns a CompletableFuture to be completed with the response value. Performs the specified call on the actor's object asynchronously. The call is executed in this actor's thread context, and the future is completed with the result value. Messages are processed in order (FIFO), so this ask() will wait for previously sent tell() messages to complete first. This method returns a CompletableFuture, which is completed with a result once the actor's call completes. If an exception occurs during the actor's call, the exception is passed to the CompletableFuture.- Type Parameters:
R- actor call response class- Parameters:
action- action to be executed on actor's object, return value will be the response- Returns:
- CompletableFuture to be completed with the actor's call result
Usage Example:
// Create an actor ActorRef<Counter> counter = system.actorOf("counter", new Counter()); // Send some tell messages first counter.tell(c -> c.increment()); counter.tell(c -> c.increment()); // Ask for the current value (waits for above messages to complete first) CompletableFuture<Integer> valueFuture = counter.ask(c -> c.getValue()); Integer currentValue = valueFuture.get(); // Should be 2 // Ask for computed result CompletableFuture<String> statusFuture = counter.ask(c -> { return "Counter value is: " + c.getValue(); }); String status = statusFuture.get(); // Chain multiple operations counter.ask(c -> c.getValue()) .thenAccept(value -> System.out.println("Current: " + value));
-
askNow
Sends a message to the actor and returns a response, bypassing the mailbox and executing immediately. Unlike ask(), which queues messages in the actor's message queue, askNow() executes the function immediately on a separate virtual thread, allowing it to run concurrently with queued messages. This method is useful when: - You need to query the actor's state immediately without waiting for queued messages - Concurrent execution with queued messages is desired- Type Parameters:
R- the type of the response- Parameters:
action- the function to execute on this actor's object- Returns:
- a CompletableFuture that completes with the function's result
-
tell
Sends a message to this actor using a specific executor service. The action is executed asynchronously on the provided executor service, and the result is processed in this actor's thread context.- Parameters:
action- the action to execute on this actor's objectws- the executor service to use for executing the action- Returns:
- a CompletableFuture that completes when the action is processed
-
ask
Sends a message to this actor and returns a response using a specific executor service. The action is executed asynchronously on the provided executor service, and the result is processed in this actor's thread context.- Type Parameters:
R- the type of the response- Parameters:
action- the function to execute on this actor's objectws- the executor service to use for executing the action- Returns:
- a CompletableFuture containing the response from the action
-
json
Returns the JSON state container for this actor, creating it if necessary.The JSON state provides a dynamic, XPath-style accessor for storing workflow state that doesn't need compile-time type safety. This is useful for temporary state, debug information, and YAML workflow integration.
Usage Example:
ActorRef<MyActor> actor = system.actorOf("worker", new MyActor()); // Store values using XPath-style paths actor.json().put("workflow.retry", 3); actor.json().put("hosts[0]", "server1.example.com"); // Read values int retry = actor.json().getInt("$.workflow.retry", 0); String host = actor.json().getString("$.hosts[0]");- Returns:
- the JSON state container (never null)
- Since:
- 2.10.0
-
hasJsonState
public boolean hasJsonState()Checks if this actor has any JSON state.- Returns:
- true if JSON state exists and is not empty
- Since:
- 2.10.0
-
putJson
Convenience method to put a value into the JSON state.- Parameters:
path- the XPath-style path (e.g., "workflow.retry" or "$.hosts[0]")value- the value to store- Returns:
- this ActorRef for method chaining
- Since:
- 2.10.0
-
getJsonString
Convenience method to get a string from the JSON state.- Parameters:
path- the XPath-style path- Returns:
- the string value, or null if not found
- Since:
- 2.10.0
-
getJsonString
Convenience method to get a string from the JSON state with default.- Parameters:
path- the XPath-style pathdefaultValue- the default value if not found- Returns:
- the string value, or defaultValue if not found
- Since:
- 2.10.0
-
getJsonInt
Convenience method to get an integer from the JSON state.- Parameters:
path- the XPath-style pathdefaultValue- the default value if not found- Returns:
- the integer value, or defaultValue if not found
- Since:
- 2.10.0
-
getJsonBoolean
Convenience method to get a boolean from the JSON state.- Parameters:
path- the XPath-style pathdefaultValue- the default value if not found- Returns:
- the boolean value, or defaultValue if not found
- Since:
- 2.10.0
-
hasJson
Convenience method to check if a path exists in the JSON state.- Parameters:
path- the XPath-style path- Returns:
- true if the path exists and has a non-null value
- Since:
- 2.10.0
-
clearJsonState
public void clearJsonState()Clears all JSON state for this actor.- Since:
- 2.10.0
-
close
public void close()Destroys the actor and cleans up its resources. Pending messages will be cancelled and the actor will be removed from its system. This method implements the AutoCloseable interface for resource management.- Specified by:
closein interfaceAutoCloseable
-
clearPendingMessages
public int clearPendingMessages()Clears all pending messages from this actor's message queue and WorkStealingPool. This method removes all messages that are currently waiting to be processed by this actor, without affecting other actors in the system. The currently running message will complete normally. Only affects messages sent via tell() and ask() - tellNow() messages are not queued. When using ActorSystem's WorkStealingPool (ControllableWorkStealingPool), this method will also cancel CPU-bound jobs that are waiting in the pool's queue. Jobs that are already executing will continue to completion.- Returns:
- the total number of messages and jobs that were cleared
Usage Example:
// Create an actor and send multiple messages ActorRef<Counter> counter = system.actorOf("counter", new Counter()); // Queue several messages counter.tell(c -> { Thread.sleep(1000); c.increment(); }); // Long running (starts immediately) counter.tell(c -> c.increment()); // Queued counter.tell(c -> c.increment()); // Queued counter.ask(c -> c.getValue()); // Queued // Queue CPU-bound jobs for (int i = 0; i < 100; i++) { counter.tell(c -> c.heavyComputation(), system.getWorkStealingPool()); } // Clear all pending messages and jobs int cleared = counter.clearPendingMessages(); System.out.println("Cleared " + cleared + " messages and jobs"); // Clears both message queue and WorkStealingPool jobs // Use cases: // 1. Cancel batch operations // 2. Reset actor state handling // 3. Emergency stop of pending work // 4. Load balancing (redirect work to other actors) // tellNow() is not affected by clearing counter.tellNow(c -> System.out.println("This executes immediately"));
-