Coder Social home page Coder Social logo

theatre-booking-akka-example's Introduction

Theatre Booking Example

This is an example application that manages the ticketing and capacity for movie theatres. The purpose of this application is to demonstrate different features provided by the Akka toolkit (Clustering, Sharding, HTTP) in order to build a robust and scalable system.

Functionality

This application provides a very simple API which allows you to book tickets for a Movie Theatre that has a fixed capacity. Using Actors and Cluster Sharding, it is able to prevent users from over-booking a movie theatre.

Theatres are fixed to a seating capacity of 50.

Here's an example of how to book 10 tickets for the star-wars movie theatre:

POST localhost:8080/theatres/star-wars/tickets/10

If all goes well, the expected response will be an HTTP 201 Created with a body of 10 indicating that 10 tickets have been booked.

If you try and book more than the seating capacity of the theatre. For example:

POST localhost:8080/theatres/star-wars/tickets/80

You will receive an HTTP 403 response with a body telling you Not Enough Seats

When the theatre is at capacity (i.e. all tickets have been booked) and you try to book some more:

POST localhost:8080/theatres/star-wars/tickets/1

You will receive an HTTP 403 response with a body telling you Theatre is at capacity.

Deployment

Locally

Start Docker-Mirror on port 9001 and mount the Docker socket and file containing the IP of the host:

docker run --name docker-mirror -p 9001:9000 \
 -v /var/run/docker.sock:/var/run/docker.sock \
 -v /Users/cfernandes/hostip:/etc/hostip \
 loyaltyone/docker-mirror:0.1.2

Confirm the service is running using curl localhost:9001/health

Create a local release of the application using sbt docker:publishLocal which will create an image called theatre-example:<current-version>.

Run the compose file for the dependencies (ZooKeeper): docker-compose up

Make note of the network it uses using docker network ls

Run the application on the same Docker network as the dependencies to take advantage of Docker's DNS capability:

docker run -it --network=theatreexample_theatre -p 9999:2551 -p 8080:8080 \
 -e APP_PORT=2551 -e ZOOKEEPER_URIS="zookeeper:2181" \
 theatre-example:0.4

Check whether the application works:

curl -X POST localhost:8080/theatres/star-wars/tickets/10

You should receive a response 10

AWS EC2 Container Service (ECS)

See the ECS Deployment instructions

Cluster Sharding

Akka Cluster Sharding

The main idea of Akka Cluster Sharding, is to shard live actors across the cluster. Each actor is assigned an entity ID. This ID is unique within the cluster. It usually represents the identifier for the domain entity that the actor is modeling. You provide a function that will extract that entity ID from the message being sent.

case class MovieTheatreEnvelope(id: String, command: MovieTheatre.Command)

val extractEntityId: ShardRegion.ExtractEntityId = {
  case e: MovieTheatreEnvelope => (e.id, e.command)
}

In the application, we choose the theatre name to be the entity ID and shard Movie Theatre Actors based on this ID.

You also provide a function that takes the message and computes the ID for the shard on which the actor will reside.

// numberOfShards is taken from the application.conf
def extractShardId(numberOfShards: Int): ShardRegion.ExtractShardId = {
  case e: MovieTheatreEnvelope => (Math.abs(e.id.hashCode) % numberOfShards).toString
  case ShardRegion.StartEntity(id) => (id.toLong           % numberOfShards).toString
}

When a message is sent, the aforementioned functions are applied to locate the appropriate shard using the shard ID, and then to locate the actor within that shard using the entity ID.

image

Each entity shown here represents a Movie Theatre Actor.

This makes it possible for you to locate the unique instance of that actor within the cluster. In the event that no actor currently exists, the actor will be created.

The sharding mechanism will ensure that only one instance of each actor (singleton semantics) exists in the cluster at any time.

Shards are distributed across the cluster in what are known as shard regions. These regions act as hosts for the shards. Each node that participates in sharding will host a single shard region for each type of sharded actor. Each region can in turn host multiple shards. All entities within a shard region are represented by the same type of actor.

image

Each individual shard can host many entities. These entities are distributed across the shards according to the computation of the shard ID that you provided.

Internally, a shard coordinator is used to manage where the shards are located. The coordinator informs shard regions as to the location of individual shards. Those shard regions can in turn be used to send a message to the entities hosted by the shards. This coordinator is implemented as a cluster singleton. However, its interaction within the actual message flow is minimized. It only participates in the messaging if the location of the shard is not known.

image

In this case, the shard region can communicate with the shard coordinator to locate the shard. That information is then cached. Going forward, messages can be sent directly without the need to communicate with the coordinator.

Here is the general flow when communicating with a shard region to accesses sharded Movie Theatre Entity Actors:

image

image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.