AKKA Programming (Create an Auction Simulator using AKKA).

Rukmal Senavirathne
3 min readDec 29, 2024

--

What is AKKA?

AKKA is used for building distributed, highly concurrent, and fault-tolerant applications. AKKA is written in Scala and works in Java too. AKKA uses the Actor Model. The Actor Model is the core of AKKA. The Actor model is a framework for creating distributed and concurrent applications.

Actors are fundamental units in the Actor Model.

The actor is responsible for,

  • Communicates with other actors using asynchronous messages.
  • Encapsulate state and behaviors.
  • It ensures thread-safe using it only processes one message at a time.

Actors are isolated from each other actors and they do not share memory, then it avoids concurrency issues like deadlocks and race conditions.

How did the AKKA name come?

The name of AKKA is chosen by the creator of AKKA Jonas Boner is Swedish. That name came from AKKA massif, which is a mountain range in Sweden. Choosing a mountain name symbolizes stability, durability, and reliability.

How does it manage concurrency?

  1. Message Passing

Each actor communicates via immutable messages, Messages are passing asynchronously, then actors do not need to wait to response.

2. Single thread execution

Each actor processes one message at a time.

3. No shared state

Actors maintain their own state.

4. Non-blocking operations

Asynchronous message pass avoids blocking.

I have created an example application for demonstrating AKKA programming features. It is an auction simulator.

It has two main components

  1. AuctionManager

The Auction Manager manages and coordinates auctions, forwards bids to the specific auction that the bid relates to, and it manages the auction lifetime.

2. AuctionActor

Auction Actor manages a single auction. It tracks the highest bid, the bidder associated to the highest bid.

Let’s see how this encapsulates state and behaviors.

State

highestBid has the risk of getting concurrent issues. Then it is private and can only be modified in onPlaceBid which is actor’s private method.

private double highestBid;

Behaviors

Actors behaviors are how actor reacts to messages that come to actors.

onPlaceBid — Check the current bid is higher than the highest bid, it updates the highest bid and winner.

    private Behavior<AuctionCommand> onPlaceBid(PlaceBid bid) {
if (bid.amount > highestBid) {
highestBid = bid.amount;
winner = bid.bidder;
context.getLog().info("New highest bid: {} by {}", highestBid, bid.bidder);
} else {
context.getLog().info("Bid by {} is too low: {}", bid.bidder, bid.amount);
}
return Behaviors.same();
}

onEndAuction — It displays the final result and stops the Actor.

    private Behavior<AuctionCommand> onEndAuction(EndAuction command) {
context.getLog().info("Auction '{}' ended with highest bid: {} winner is : {}", auctionId, highestBid, winner);
return Behaviors.stopped();
}

All states and Behaviors are private, and they can only be modified using the Actor itself. That is how it encapsulates states and behaviors.

In AuctionManager,

It handles multiple auctions. Following are the messages it handles.

  1. OnCreateAuction — Creates a new AuctionActor for specific auction
    private Behavior<AuctionManagerCommand> onCreateAuction(CreateAuction command) {
ActorRef<AuctionCommand> auction = context.spawn(
AuctionActor.create(command.auctionId, command.initialPrice),
command.auctionId
);
auctions.put(command.auctionId, auction);
context.getLog().info("Auction '{}' created with initial price: {}", command.auctionId, command.initialPrice);
context.getSystem().scheduler().scheduleOnce(
Duration.ofSeconds(command.durationInSeconds),
() -> context.getSelf().tell(new EndAuctionForManager(command.auctionId)),
context.getExecutionContext()
);
return Behaviors.same();
}

2. OnForwardBid — Forwards PlaceBid message to appropriate auction.

    private Behavior<AuctionManagerCommand> onForwardBid(ForwardBid command) {
ActorRef<AuctionCommand> auction = auctions.get(command.auctionId);
if (auction != null) {
auction.tell(new PlaceBid(command.placeBid.bidder, command.placeBid.amount));
context.getLog().info("Forwarded bid from '{}' to auction '{}'", command.placeBid.bidder, command.auctionId);
} else {
context.getLog().info("Auction '{}' not found.", command.auctionId);
}
return Behaviors.same();
}

3. OnEndAuctionForManager — send EndAuction message to appropriate auction.

    private Behavior<AuctionManagerCommand> onEndAuctionForManager(EndAuctionForManager command) {
ActorRef<AuctionCommand> auction = auctions.get(command.auctionId);
if (auction != null) {
auction.tell(new EndAuction());
context.getLog().info("Ended auction '{}'", command.auctionId);
auctions.remove(command.auctionId); // Optionally remove the auction after ending it
} else {
context.getLog().info("Auction '{}' not found for ending.", command.auctionId);
}
return Behaviors.same();
}

Summary

In this example actors communicate via asynchronous messages, actors encapsulate their state and behaviors to ensure thread-safe. Using AKKA it simplifies Concurrency and Modularity.

You can find the full example in this GitHub repository Click.

--

--

Rukmal Senavirathne
Rukmal Senavirathne

Written by Rukmal Senavirathne

Senior Software Engineer at GTN. Graduated from the Department of Computer Science and Engineering at the University of Moratuwa.

No responses yet