You are on page 1of 15

Akka

Anil Dhulipalla

what is Akka?
Akka is an open-source toolkit and runtime to build concurrent, distributed, fault tolerant applications.
Akka provides the following features

Concurrency through Actor Model system


Scales up(concurrency) and out(distributed)
Fault tolerance The supervision strategy helps to recover actors for exceptions.
Event Driven Architecture
Transaction support
Location Transparency
Scala/Java API.

Key Constructs of AKka

Installation
Akka Actor
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-actor_2.10</artifactId>
<version>2.3-M1</version>
</dependency>

Akka Test Kit


<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-testkit_2.10</artifactId>
<version>2.3-M1</version>
</dependency>

Actor Model
Actors instead of Objects
No shared state between actors
Asynchronous message passing

Actors

Fundamental unit of Computation


Behavior React on messages it receives
State- No need for synchronization.
Interaction- interact with other Actors via Messages
Isolated, Lightweight than a thread, Asynchronous, Non-blocking
Messages are kept in mail box and processed in order
Messaging model of an Actor

Define Actor
public class CheckOutChildActor extends UntypedActor {
private static final Logger LOG = Logger.getLogger(CheckOutChildActor.class);
public CheckOutChildActor() throws DatabaseException, ConfigurationException{
this.checkoutBasicService = new CheckoutBasicService();
}
@Override
public void preStart() {
LOG.info("Starting CheckOutChildActor instance hashcode # {} -" + this.hashCode());
}
@Override
public void onReceive(Object o) throws Exception {
try {
if (o instanceof Checkout) {
Checkout checkout = (Checkout) o;
CheckoutDTO checkoutDTO = checkoutBasicService.getCheckout(checkout);
getSender().tell(checkoutDTO, getSelf());
} else {
unhandled(o);
}
} catch (IncompleteCheckoutException e) {
getSender().tell(new Status.Success(e), getSelf());
throw e;
} catch (DatabaseException e) {
getSender().tell(new Status.Failure(e), getSelf());
throw e;
} catch (CustomException e) {
getSender().tell(new Status.Failure(e), getSelf());
throw e;
}catch (Exception e) {
LOG.error("CHILD ERROR",e);
getSender().tell(new Status.Failure(e), getSelf());
throw e;
}
}
@Override
public void postStop() {
LOG.info("Stopping CheckOutChildActor instance hashcode # {} -" + this.hashCode());
}
}

Create and send message


//Creating an Actor system
ActorSystem actorSystem= ActorSystem.create(name, ConfigFactory.load().getConfig(dispatcher));
//Creating top level Actor
ActorRef masterActorRef= actorSystem.actorOf(Props.create(CheckOutChildActor.class).withRouter(new
RoundRobinPool(20)));
//Model-1
//In this model you send a message to the Actor and dont wait for response from it.
masterActorRef.tell(Hello World, getSelf());
//Model-2
final Timeout timeout = new Timeout(Duration.create(120,
TimeUnit.SECONDS));
Future<Object> future = Patterns.ask(masterActorRef, message, timeout);
Object resultObject = Await.result(future, Duration.Inf());

Actor system

can create Hierarchy of actors

//Creating top level Actor


ActorRef masterActorRef=
actorSystem.actorOf(Props.create(CheckOutMast
erActor.class).withRouter(new
RoundRobinPool(20)));
//Creating a child actor in Master Actor
ActorRef childActorRef=
getContext().actorOf(Props.create(CheckOutChi
ldActor.class));

Fault Tolerance in Akka

STOPPED- Terminate the


subordinate actor
RESTARTED-Kill the current actor
instance and instantiate a new actor
instance.
RESUMED-Keep the current state
ESCALATED-Escalate the failure to
its own supervisor.

Fault Tolerance in Akka


public class CheckOutMasterActor extends UntypedActor {
/**
* Supervisor strategy to handle exceptions thrown by child actors
*/
private SupervisorStrategy strategy = new AllForOneStrategy(10,
Duration.Inf(), new Function<Throwable, SupervisorStrategy.Directive>() {
public SupervisorStrategy.Directive apply(Throwable t) {
if (t instanceof IncompleteCheckoutException) {
return SupervisorStrategy.resume();
} else {
return SupervisorStrategy.escalate();
}
}
});
//This method need to be overridden for Supervisor strategy
@Override
public SupervisorStrategy supervisorStrategy() {
return strategy;
}
}

Remote Actor

Actors are location transparent and distributed by design


Actors can be made remote through config
Messages are serialized using java serialization.

Routing
A router routes incoming messages to outbound actors

RoundRobinPool
SmallestMailboxPool
RandomPool
ScatterGatherFirstCompletedPool
BroadcastPool

private ActorRef getMasterActorFromPool() {


if (checkoutMasterActorPool == null) {
propsMaster = Props.create(masterActorClass)
.withRouter(new SmallestMailboxPool(AKKA_MASTER_ROUTER_SIZE));
checkoutMasterActorPool =
AkkaManager.getInstance().getActorSystem().actorOf(propsMaster, "MasterActorPool");
}
return checkoutMasterActorPool;
}

Unit Testing
public class CheckOutChildActorTest extends TestKit {
private static ActorSystem actorSystem = ActorSystem.create("childActorTestKit");
private TestActorRef<CheckOutChildActor> childActorRef;
@Mock
private CheckoutBasicService checkoutBasicService;
@InjectMocks
private CheckOutChildActor checkOutChildActor;
public CheckOutChildActorTest() {
super(actorSystem);
}
@Before
public void setUp() throws Exception {
System.setProperty("user.home", System.getProperty("user.dir") + "/src/test/resources");

childActorRef = TestActorRef.apply(Props.create(CheckOutChildActor.class),
actorSystem);
checkOutChildActor = childActorRef.underlyingActor();
MockitoAnnotations.initMocks(this);
}
@After
public void tearDown() throws Exception {
}
@Test
public void testChildActor() throws Exception {
Checkout checkout = CheckoutGenerator.generateCheckout(2L);
CheckoutDTO checkoutDTO = CheckoutGenerator.generateCheckoutDTO(2L, 2L);

Thank You

You might also like