SCOOTER

A VLINGO/PLATFORM toolset for implementing Actors and DDD entities/aggregates with persistence, providing a stepwise adoption the our full reactive toolset.

A Gentle Introduction to Async

Admittedly most who refrain from the use of Reactive architectures, programming, and related tools, are generally concerned about the learning curve being too steep. Although a learning curve is indeed required, it's not as steep as most think. Whatever your expectations, we have provided an gentle path toward adopting Reactive. We think these will help you ease in to Reactive.

Blocking Mailbox

If you consider asynchronous actor messaging to be daunting, why not trying synchronous actor messaging?

The primary tool provided is a specialized actor mailbox. You can read more about actors and the role of their mailboxes here and here. The VLINGO/ACTORS tooling supports any number of mailbox plugins. The particular one provided by VLINGO/SCOOTER is a blocking actor mailbox.

import io.vlingo.actors.plugin.mailbox.blocking.BlockingMailbox;

This mailbox works by delivering a message to the target actor immediately rather than leaving the message for another thread to deliver. There is a potential problem with this. When you consider a request-response example, what would happen if the request handling actor and the response handling actor continued indefinitely sending each other messages rather than stopping after one? Correct, an ugly stack overflow would soon happen, or even re-entering an actor on the same thread and potentially modifying its state unexpectedly before the first message delivery has returned.

To prevent this the blocking mailbox does in fact implement a queue, but it protects access to the queue using a compare-and-set operation. This limits the queue polling to only the first arriving enqueuing access. Think of the same thread that delivers to the request actor, next delivering a message to the response actor on the same thread. As described previously, this could cause a number of problems. So, what should be done?

public class BlockingMailbox implements Mailbox {
...
public void send(final Message message) {
if (isClosed()) return;
queue.add(message);
if (isSuspended()) {
return;
}
try {
boolean deliver = true;
while (deliver) {
if (delivering.compareAndSet(false, true)) {
while (deliverAll())
;
delivering.set(false);
}
deliver = false;
}
} catch (Throwable t) {
if (delivering.get()) {
delivering.set(false);
}
throw new RuntimeException(t.getMessage(), t);
}
}
...
}

Consider the above send(Message message) method of the BlockingMailbox. The mailbox invocation that occurs first locks the mailbox queue, but without blocking another attempt to lock. The compare-and-set prevents blocking on any secondary deliveries. So a second, third, forth, etc., delivery on the same thread enqueues the message, and when it sees that access is already reserved it simply returns. When the message deliveries (method invocations) unwind, the original access will see all additional messages enqueued and deliver them. This could go on for a long time without causing issues, as long as the stack is given the opportunity to unwind before the queue causes an out-of-memory condition.

Modeling With Entities

More...

Implementing an ObjectEntity

More...

code examples

Implementing Sourced Entities

More...

code examples

Implementing a StatefulEntity

More...

code examples

Persistence

More...