Active objects provide an OO facade on top of actors, allowing you to avoid dealing directly with the actor machinery,
having to match messages, wait for results and send replies.

h2. Actors with a friendly facade
{code}
import groovyx.gpars.activeobject.ActiveObject
import groovyx.gpars.activeobject.ActiveMethod

@ActiveObject
class Decryptor {
    @ActiveMethod
    def decrypt(String encryptedText) {
        return encryptedText.reverse()
    }

    @ActiveMethod
    def decrypt(Integer encryptedNumber) {
        return -1*encryptedNumber + 142
    }
}

final Decryptor decryptor = new Decryptor()
def part1 = decryptor.decrypt(' noitcA ni yvoorG')
def part2 = decryptor.decrypt(140)
def part3 = decryptor.decrypt('noitide dn')

print part1.get()
print part2.get()
println part3.get()
{code}

You mark active objects with the _@ActiveObject_ annotation. This will ensure a hidden actor instance is created for each instance of your class.
Now you can mark methods with the _@ActiveMethod_ annotation indicating that you want the method to be invoked asynchronously
by the target object's internal actor.
An optional boolean _blocking_ parameter to the _@ActiveMethod_ annotation specifies, whether the caller should block until a result is available
or whether instead the caller should only receive a _promise_ for a future result in a form of a _DataflowVariable_ and so the caller is not blocked waiting.

{note}
By default, all active methods are set to be *non-blocking* . However, methods, which declare their return type explicitly, must be configured
as blocking, otherwise the compiler will report an error. Only _def_ , _void_ and _DataflowVariable_ are allowed return types for non-blocking methods.
{note}

Under the covers, GPars will translate your method call to *a message being sent to the internal actor* . The actor will eventually handle that message by invoking the desired method
on behalf of the caller and once finished a reply will be sent back to the caller.
Non-blocking methods return promises for results, aka _DataflowVariables_ .

h3. But blocking means we're not really asynchronous, are we?

Indeed, if you mark your active methods as _blocking_ , the caller will be blocked waiting for the result, just like when doing normal plain method invocation.
All we've achieved is being thread-safe inside the Active object from concurrent access. Something the _synchronized_ keyword could give you as well.
So it is the *non-blocking* methods that should drive your decision towards using active objects. Blocking methods will then provide the usual synchronous semantics yet give the consistency guarantees
across concurrent method invocations. The blocking methods are then still very useful when used in combination with non-blocking ones.

{code}
import groovyx.gpars.activeobject.ActiveMethod
import groovyx.gpars.activeobject.ActiveObject
import groovyx.gpars.dataflow.DataflowVariable

@ActiveObject
class Decryptor {
    @ActiveMethod(blocking=true)
    String decrypt(String encryptedText) {
        encryptedText.reverse()
    }

    @ActiveMethod(blocking=true)
    Integer decrypt(Integer encryptedNumber) {
        -1*encryptedNumber + 142
    }
}

final Decryptor decryptor = new Decryptor()
print decryptor.decrypt(' noitcA ni yvoorG')
print decryptor.decrypt(140)
println decryptor.decrypt('noitide dn')
{code}

h3. Non-blocking semantics

Now calling the non-blocking active method will return as soon as the actor has been sent a message.
The caller is now allowed to do whatever he likes, while the actor is taking care of the calculation.
The state of the calculation can be polled using the _bound_ property on the promise.
Calling the _get()_ method on the returned promise will block the caller until a value is available.
The call to _get()_ will eventually return a value or throw an exception, depending on the outcome of the actual calculation.

{note}
The _get()_ method has also a variant with a timeout parameter, if you want to avoid the risk of waiting indefinitely.
{note}

h4. Annotation rules

There are a few rules to follow when annotating your objects:
# The _ActiveMethod_ annotations are only accepted in classes annotated as _ActiveObject_
# Only instance (non-static) methods can be annotated as _ActiveMethod_
# You can override active methods with non-active ones and vice versa
# Subclasses of active objects can declare additional active methods, provided they are themselves annotated as _ActiveObject_
# Combining concurrent use of active and non-active methods may result in race conditions. Ideally design your active objects as completely encapsulated classes with all non-private methods marked as active

h3. Inheritance

The _@ActiveObject_ annotation can appear on any class in an inheritance hierarchy. The actor field will only be created in top-most annotated class in the hierarchy, the subclasses will reuse the field.

{code}
import groovyx.gpars.activeobject.ActiveObject
import groovyx.gpars.activeobject.ActiveMethod
import groovyx.gpars.dataflow.DataflowVariable

@ActiveObject
class A {
    @ActiveMethod
    def fooA(value) {
        ...
    }
}

class B extends A {
}

@ActiveObject
class C extends B {
    @ActiveMethod
    def fooC(value1, value2) {
        ...
    }
}
{code}

In our example the actor field will be generated into class _A_ . Class _C_ has to be annotated with _@ActiveObject_ since it holds
the _@ActiveMethod_ annotation on method _fooC()_ , while class _B_ does not need the annotation, since none of its methods is active.

h3. Groups

Just like actors can be grouped around thread pools, active objects can be configured to use threads from particular parallel groups.
{code}
@ActiveObject("group1")
class MyActiveObject {
    ...
}
{code}

The _value_ parameter to the _@ActiveObject_ annotation specifies a name of parallel group to bind the internal actor to.
Only threads from the specified group will be used to run internal actors of instances of the class.
The groups, however, need to be created and registered prior to creation of any of the active object instances belonging to that group.
If not specified explicitly, an active object will use the default actor group - _Actors.defaultActorPGroup_ .

{code}
final DefaultPGroup group = new DefaultPGroup(10)
ActiveObjectRegistry.instance.register("group1", group)
{code}

h3. Alternative names for the internal actor

You will probably only rarely run into name collisions with the default name for the active object's internal actor field.
May you need to change the default name _internalActiveObjectActor_ , use the _actorName_ parameter to the _@ActiveObject_ annotation.

{code}
@ActiveObject(actorName = "alternativeActorName")
class MyActiveObject {
    ...
}
{code}

{note}
Alternative names for internal actors as well as their desired groups cannot be overriden in subclasses.
Make sure you only specify these values in the top-most active objects in your inheritance hierarchy. Obviously, the top most active object
is still allowed to subclass other classes, just none of the predecessors must be an active object.
{note}
