Previously on Andrea’s blog: in the first part of this post I spoke about setting up a database for the project I did for the interview at BBC (GitHub repo) and about the tables I created (and how to use Evolutions).
Now it is time for a DAO (Data Access Object – Wikipedia). Let’s say that the idea would be to separate at least concepts related the different actors (admin, voter, presenter). But to have a fast and easy way to see everything (anyway, I had time constraints) I put all the access methods in a single class, DbAccess. Of course I separated the different calls anyway, but I did it by creating three different classes that were exposing the protected methods of DbAccess. The classes are AdminDB, PresenterDB and VoterDB. Another not really nice thing I did was to put the data model in the DbAccess companion object, I may have defined it in a separate file, to decouple it from the DAO.
The methods in the DAO perform some obvious query. It may be worth noticing that the DAO gets a Database from Play Framework to access the database (being a trait it has no constructor, so you have to override it in the classes extending it). You can create a connection, but remember to close it when finished, or you can use the method withConnection that closes it for you at the end of the block (meaning you cannot use the resultset outside the block).
In the very first version of the code, controllers were receiving a Database from Guice, they were creating the needed DAO (ehmmmm… for being honest, a DAO should give access only to a single table… MVC is usually counting on a Service layer to handle models from controllers and ask to one or more DAOs the data from the tables) and they were serving requests. This works pretty good, but it has a drawback: all the requests are served as they arrive, but what if we have one billion requests for votes and the presenter asks for visualising the stats? Having only a maximum of 10 connections in the pool for H2, the database can be really busy. The second version of this architecture was based on Akka Actors, so that we could create a cluster of 9 actors for voters and a single actor for the presenter: actors are handling one request per time, so by limiting in this very inefficient way, we at least preserved one connection for the presenter.
To introduce actors we had to instruct Guice to create our actors with a specific name. This is done by defining an AbstractModule (please remember that, if it is not called Module and belongs to the root package you have to add its definition in the config file), its syntax is easy to understand. Please notice that we could do that like this because all the parameters needed for our Actors (for example AdminActor) are already known by Guice (in the example, the DB provided by Play Framework). Guice has a nice way to generate factories that let you create objects with some parameters that are injected and others that have to be provide, but I didn’t use that, so if you need them follow this link.
Actors are nice cause they receive messages and they act based on them. And with Play you can ask (ask pattern) an actor for a reply and send it asynchronously to the invoker.
For today this is enough. I left to speak about the frontend and the websocket. Follow the last chapter.