You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardexpand all lines: src/main/groovy/groovyx/gpars/actor/AbstractPooledActor.java
+76-60
Original file line number
Diff line number
Diff line change
@@ -28,91 +28,105 @@
28
28
importjava.util.concurrent.TimeUnit;
29
29
30
30
/**
31
-
* AbstractPooledActor provides the default implementation of a stateful actor. Refer to DynamicDispatchActor or ReactiveActor for examples of stateless actors.
32
-
* It represents a standalone active object (actor),
33
-
* which reacts asynchronously to messages sent to it from outside through the send() method, which preserving its internal implicit state.
34
-
* Each Actor has its own message queue and a thread pool shared with other Actors by means of an instance
35
-
* of the PGroup, which they have in common.
36
-
* The PGroup instance is responsible for the pool creation, management and shutdown.
37
-
* All work performed by an Actor is divided into chunks, which are sequentially submitted as independent tasks
38
-
* to the thread pool for processing.
39
-
* Whenever an Actor looks for a new message through the react() method, the actor gets detached
40
-
* from the thread, making the thread available for other actors. Thanks to the ability to dynamically attach and detach
41
-
* threads to actors, Actors can scale far beyond the limits of the underlying platform on number of concurrently
42
-
* available threads.
43
-
* The receive() method can be used to read a message from the queue without giving up the thread. If no message is available,
44
-
* the call to receive() blocks until a message arrives or the supplied timeout expires.
45
-
* The loop() method allows to repeatedly invoke a closure and yet perform each of the iterations sequentially
46
-
* in different thread from the thread pool.
47
-
* To support continuations correctly the react() and loop() methods never return.
31
+
* {@code AbstractPooledActor} provides the default implementation of a stateful actor. Refer to {@code
32
+
* DynamicDispatchActor} or {@code ReactiveActor} for examples of stateless actors. {@code
33
+
* AbstractPooledActor} represents a standalone active object (actor), which reacts asynchronously to
34
+
* messages sent to it from outside through the {@code send} method, which preserving its internal implicit
35
+
* state. Each {@code Actor} has its own message queue and a thread pool shared with other {@code Actor}s
36
+
* by means of an instance of the {@code PGroup}, which they have in common. The {@code PGroup} instance is
37
+
* responsible for the pool creation, management and shutdown. All work performed by an {@code Actor} is
38
+
* divided into chunks, which are sequentially submitted as independent tasks to the thread pool for
39
+
* processing. Whenever an {@code Actor} looks for a new message through the {@code react} method, the
40
+
* actor gets detached from the thread, making the thread available for other actors. Thanks to the ability
41
+
* to dynamically attach and detach threads to actors, {@code Actors} can scale far beyond the limits of the
42
+
* underlying platform on number of concurrently available threads. The {@code receive} method can be used
43
+
* to read a message from the queue without giving up the thread. If no message is available, the call to
44
+
* {@code receive} blocks until a message arrives or the supplied timeout expires. The {@code loop} method
45
+
* allows to repeatedly invoke a closure and yet perform each of the iterations sequentially in different
46
+
* thread from the thread pool. To support continuations correctly the {@code react} and {@code loop}
47
+
* methods never return.
48
+
*
48
49
* <pre>
49
50
* import static groovyx.gpars.actor.Actors.actor
50
-
* <p/>
51
+
*
51
52
* def actor = actor {
52
53
* loop {
53
-
* react {message ->
54
+
* react {message ->
54
55
* println message
55
56
* }
56
-
* //this line will never be reached
57
+
* // This line will never be reached.
57
58
* }
58
-
* //this line will never be reached
59
+
* // This line will never be reached.
59
60
* }.start()
60
-
* <p/>
61
+
*
61
62
* actor.send 'Hi!'
62
63
* </pre>
64
+
* <p>
63
65
* This requires the code to be structured accordingly.
64
-
* <p/>
66
+
* </p>
65
67
* <pre>
66
68
* def adder = actor {
67
69
* loop {
68
-
* react {a ->
69
-
* react {b ->
70
+
* react {a ->
71
+
* react {b ->
70
72
* println a+b
71
-
* replyIfExists a+b //sends reply, if b was sent by a PooledActor
73
+
* replyIfExists a+b // Sends reply, if b was sent by a PooledActor.
72
74
* }
73
75
* }
74
-
* //this line will never be reached
76
+
* // This line will never be reached.
75
77
* }
76
-
* //this line will never be reached
78
+
* // This line will never be reached.
77
79
* }.start()
78
80
* </pre>
79
-
* The closures passed to the react() method can call reply() or replyIfExists(), which will send a message back to
80
-
* the originator of the currently processed message. The replyIfExists() method unlike the reply() method will not fail
81
-
* if the original message wasn't sent by an actor nor if the original sender actor is no longer running.
82
-
* The reply() and replyIfExists() methods are also dynamically added to the processed messages.
81
+
* <p>
82
+
* The closures passed to the {@code react} method can call {@code reply} or {@code replyIfExists}, which
83
+
* will send a message back to the originator of the currently processed message. The {@code replyIfExists}
84
+
* method unlike the {@code reply} method will not fail if the original message wasn't sent by an actor nor
85
+
* if the original sender actor is no longer running. The {@code reply} and {@code replyIfExists} methods
86
+
* are also dynamically added to the processed messages.
87
+
* </p>
83
88
* <pre>
84
-
* react {a ->
85
-
* react {b ->
89
+
* react {a ->
90
+
* react {b ->
86
91
* reply 'message' //sent to senders of a as well as b
87
92
* a.reply 'private message' //sent to the sender of a only
88
93
* }
89
94
* }
90
95
* </pre>
91
-
* <p/>
92
-
* The react() method accepts timeouts as well.
96
+
* <p>
97
+
* The {@code react} method accepts timeouts as well.
98
+
* </p>
93
99
* <pre>
94
100
* react(10, TimeUnit.MINUTES) {
95
101
* println 'Received message: ' + it
96
102
* }
97
103
* </pre>
98
-
* If no message arrives within the given timeout, the onTimeout() lifecycle handler is invoked, if exists,
99
-
* and the Actor.TIMEOUT message is returned.
100
-
* Each Actor has at any point in time at most one active instance of ActorAction associated, which abstracts
101
-
* the current chunk of actor's work to perform. Once a thread is assigned to the ActorAction, it moves the actor forward
102
-
* till loop() or react() is called. These methods schedule another ActorAction for processing and throw dedicated exception
103
-
* to terminate the current ActorAction.
104
-
* <p/>
105
-
* Each Actor can define lifecycle observing methods, which will be called by the Actor's background thread whenever a certain lifecycle event occurs.
104
+
*<p>
105
+
* If no message arrives within the given timeout, the {@code onTimeout} lifecycle handler is invoked, if
106
+
* exists, and the {@code Actor.TIMEOUT} message is returned. Each {@code Actor} has at any point in time
107
+
* at most one active instance of {@code ActorAction} associated, which abstracts the current chunk of
108
+
* actor's work to perform. Once a thread is assigned to the {@code ActorAction}, it moves the actor forward
109
+
* till {@code loop} or {@code react} is called. These methods schedule another {@code ActorAction} for
110
+
* processing and throw dedicated exception to terminate the current {@code ActorAction}.
111
+
* </p>
112
+
* <p>
113
+
* Each Actor can define lifecycle observing methods, which will be called by the Actor's background thread
114
+
* whenever a certain lifecycle event occurs.
115
+
* </p>
106
116
* <ul>
107
-
* <li>afterStart() - called immediately after the Actor's background thread has been started, before the act() method is called the first time.</li>
108
-
* <li>afterStop(List undeliveredMessages) - called right after the actor is stopped, passing in all the messages from the queue.</li>
109
-
* <li>onInterrupt(InterruptedException e) - called when a react() method timeouts. The actor will be terminated.
110
-
* <li>onTimeout() - called when the actor's thread gets interrupted. Thread interruption will result in the stopping the actor in any case.</li>
111
-
* <li>onException(Throwable e) - called when an exception occurs in the actor's thread. Throwing an exception from this method will stop the actor.</li>
117
+
* <li>{@code afterStart()} - called immediately after the {@code Actor}'s background thread has been
118
+
* started, before the {@code act} method is called the first time.</li>
119
+
* <li>{@code afterStop(List undeliveredMessages)} - called right after the actor is stopped, passing in all
120
+
* the messages from the queue.</li>
121
+
* <li>{@code onInterrupt(InterruptedException e)} - called when a {@code react} method timeouts. The actor
122
+
* will be terminated.</li>
123
+
* <li>{@code onTimeout()} - called when the actor's thread gets interrupted. Thread interruption will
124
+
* result in the stopping the actor in any case.</li>
125
+
* <li>{@code onException(Throwable e)} - called when an exception occurs in the actor's thread. Throwing an
126
+
* exception from this method will stop the actor.</li>
112
127
* </ul>
113
128
*
114
129
* @author Vaclav Pech, Alex Tkachman, Dierk Koenig
0 commit comments