Skip to content

ConGaLi Technical documentation

Miguel Isasmendi edited this page May 22, 2017 · 15 revisions

HOME > TECHNICAL DOCUMENTATION

This documentation is intended for readers with technical background on IT, although it should be relatively approachable for a non technical eventual reader, but no promises made on keeping on that way :)

The choice for using Node.js relies on his concurrency features that uses the event-loop an thread pools that are handled internally to allow me to ensure that I can run fast throughput service without blocking the stored representation that is held on memory in the domain business manager (DBM) layer. But this decision has to atone the decision for splitting the service, probably leaving the in-memory version of the service on the DBMs. This will be discussed further on the following sections.

The technical documentation reflects the ConGaLi architecture, with his layers:

Having into account that this is a architectural setup that will change in the future, the actual implementation of this server is separated into the following layers that will be explained below:

Architecture

The load balancing on the WebSocket layer could be handled with PM2 and the authentication with JWT/JMS across all servers.

 Handlers Handlers

The handlers layer is responsible of handle all the web socket requests from the client and evaluate if the data received have the structure and the data expected from him. So, next are it's responsibilities:

  • Configure sockets to be able to interact with the server every time it's required to expand or decrease the permissions for that socket
  • Checking user session and permissions to access the operation that has been received.
  • To keep the relation between the socket and the user, and provide mechanisms to ensure socket identity.
  • To rate limit operations on user identity and access time basis
  • To provide mechanisms to re join a game due to server tear down or to client network connection failures.

The main and relevant handlers are:

  • ConnectionHandler
    • Ensures to wire up the sockets connected and delegate the configurations to the rest of the handlers, so they can configure each one of those too.
  • ConwaysGameHandler
    • Configure the sockets to allow game creation and references the proper DBM to delegate further client requests.
  • GeneralCommunicationHandler
    • It's bound to disapear. It provides data retrieval interface to the client. It will be replaced with a REST server.
  • UserSessionConnectionHandler
    • The handler that deals with the rustic authentication layer that will be replaced with JWS/JWT on the not so distant future.

The decision of build this layer lead the rest of the layers to be implemented using the Node.js array of tools. This is not necessarily to be like that forever, but it certainly forced the architecture of the monolithic stage of the app to be that way. The development of this backend server was carried along with the creation of the first client of this implementation, that is a web interface (see ConGaLi-Web-Frontend), this allowed to maintain the whole implementation under the scope of the technologic features and implementation constraints and advantages of ECMAScript 5+.

So, we delayed further decisions about microservices communication and interactions up to the point of having this implementation of the server already working, properly tested so we can rely on that when splitting the server to ensure a speedier recovery on any error or change we could suffer.

The horizontal growth expected to happen on these has is foundations on the decision of allowing a server to handle one or more game instances without taking into account nor being affected by the fact that it could exist other service that will have other instance of a game for the same player. These, actually don't have to interact with each other, so these lack of coupling could be taken as an advantage creating a pool of servers (with a tool such as PM2, for instance), each one can have a single instance or several handler instances running making easier to control port saturation due the Websocket's resource consuming nature. As a consequence, we will need a load balancer as an interface to the clients that will have this criteria, among others, into account to delegate the responsibility to hold a game during all it's life cicle to a particular instance of this server.

Back to top

 Domain Domain

This part is intended to be partly displaced to a separated REST backend implementation that will be the responsible of the domain logic provided as managers of the behavior of each one of the actions required. This will allow a very particular and interesting horizontal growth.

Some of this objects have the responsibility to throw exceptions upon expected miss behaviors that are assumed to be handled in the Handlers layer to be finally sent, if the case merits and require it, to the client.

Back to top

 Business Logic Managers Business Logic Managers

There are two kinds of logic managers that would resemble each one to a different kind of service:

  • General Logic Managers
    • GeneralCommunicationHandler
  • Specific Logic Managers
    • ConwaysGameBusinessLogicManager
    • UserBusinessLogicManager

They differ in the fact that the Specific Logic Managers intention is to work on events that affects heavily on the domain objects stored and the game logic, which is not the case for the General Logic Managers.

Business Logic Managers have the responsibility to take into account the following criteria:

  • Propagate or generate their own AppException instances.
  • Validate general expected argument criteria
  • Provide a semantically clear interface to support the operations required for the layers exposed to a system outside the boundaries of a handler or a simple REST server.

Specific Logic Managers are a concept tied to extinction as soon we could implement his provided services into a plain REST server, that will interact with the client, but will share the same authentication validation than the rest of the services.

Business Logic Managers is a concept that will remain on time handling the different users game implementations and are intended to work and store the in-memory cached version of the game to allow the rapid response on the game, and decoupling the storage of it's games making this layer resilient even without any Storage layer server up, giving the architecture time to get these servers up and allowing the possibility of a smooth recovery.

It's very important to point out that the decision to use Javascript, allowed me to think in a model to store the game grid having a very small footprint, but that's a decision that will be explained further on the Model section.

Back to top

 Model Model

The domain objects are the representation of the core objects whose interaction leads the ulterior motif of the system. The granularity of the domain and the degree of the cohesion they have, needs to be addressed and responsibilities has to be delegated even through different microservices. This decision has to take into account that the whole purpose of this system is to be as close as a real-time application could be given the average infrastructure it has. Such analysis is still undergoing at the moment of writing, but the main direction of the design is already taken.

The design principles that lead the design was also heavily affected by memory constraints, among others, that are such that lead to a particular implementation of each one of the Models. Given that constraints, the actual models are:

  • CellsGrid
  • CellsTemplateDefinition
  • ContextUnawareCell
  • ConwaysGame
  • TemplateGroup
  • User

 Cells Grid Cells Grid

The design of this Model had to take into account that it have to be as light weight as possible taking the most of the possible scarce resources available. Having said that, the design taken had the following principles in mind:

  • The grid required information such as the boundaries of a grid and name identification, among others.
  • Giving the memory contraints, the amount of cells stored has to be minimal, giving the responsibility to calculate iterate over the living cells to the grid, among others. Also, it lead to deprive each Cell representation to know it's neighbors, leaving that to the Cells grid to figure out.
  • It will have the responsibility of generate upon request a new generation of cells abiding, of course, to the domain rules to do so.

 Cells Template Definition Cells Template Definition

The design of this Model is intended to represent a grouping form of points that can be used with a given offset, and can represent a well know cells configuration on a cells grid.

 Context Unaware Cell ContextUnawareCell

The design of this Model is intended to represent a given point in a cell, and a given color. It doesn't know he's neighbors at all, that's CellsGrid responsibility.

 Conway's Game ConwaysGame

The design of this Model is intended to represent collection of grids that all share the users on the grid. It's done in this way to allow having several grids that may have different properties than the others.

Is important to notice that given resources constraints, we will need to estimate when a grid should not be created on a server to ensure that we will have enough memory to fulfill the game purpose, that's why the feature of changing the size of the cells grids in a game is not provided.

 Template Group TemplateGroup

The design of this Model is intended to represent named group of cells templates. As simple as that :)

 User User

The design of this Model is intended to represent an User in the system, but without storing the information that will be relevant for all the instances of game around. The color is a special case of that, even if we have a common color for an User we may need to change that for a particular game instance given that other user may have the same color. We may disambiguate names using the id, but with color we can't do that.

Back to top

 Handlers Storage

The storage layer may be the less solid implementation in the system right now. This is given the time constraints for building this application. Nevertheless, the debate on how should the persistence of the data be handled is incipient. The choices will be clearly associated to the selected architecture and division of the responsibilities on different microservices.

At the moment of writing, the StorageDAO stores Models in data structures on memory. Implementation that's more flexible to the current development process, but needs to be improved on the mid term, at most.

Back to top