Skip to content

Latest commit

 

History

History
181 lines (121 loc) · 6.12 KB

README.md

File metadata and controls

181 lines (121 loc) · 6.12 KB

Hamerkop

A console-based application that simulates Social Networks behaviours

Table of Contents

Features

You can post messages:

@bob -> It's a lovely weather today!

bob: It's a lovely weather today!

@alice -> perfect day for hiking

alice: perfect day for hiking

Read users' posts:

@bob

what did you guys think about the trailer for The Last Jedi? (2 seconds ago)
it's a lovely weather today! (5 minutes ago)

Follow users and see their feed:

@bob follows alice

bob is now following alice

@bob wall

bob: what did you guys think about the trailer for The Last Jedi? (2 seconds ago)
alice: perfect day for hiking (51 seconds ago)
bob: it's a lovely weather today! (1 minute ago)

Running the application

To run the application, simply clone this repository and run the command ./hamerkop from the project directory:

$ ./hamerkop

Welcome to Hamerkop, a Social Network simulation.
Type :help to see the list of available commands.

Structure

Hamerkop was built with simplicity and scalability in mind, trying to merge the requirements with possibility for future extension. The requirements met are:

  1. Console-based
  2. In-memory storage
  3. Local (all users will use the same terminal)
  4. No pre-defined list of users
  5. Create users upon first post command
  6. Four available commands: post, read, follow, wall

Along with the four required commands, a help command was provided, so users can see what commands are available and how they work.

The project was divided in three main modules: Main, Env, Commands

The Main Module is responsible for fetching the user input and return the result from the input evaluation. It also contains the list of available commands. Future commands can be added by updating this list.

Env Module's main responsibility is to evaluate the user input and find a Command which can execute it.

The Commands Module holds the Action Runners, that is, the functions that will apply the user commands, such as display a list of posts or store a new post/user.

Storage

As the application is completely run in-memory, a record was created, named Env such as follows:

data Env
  = Env
    { cmds :: Commands
    , users :: Users
    , eTime :: UTCTime }

This record holds the list of available Commands, the list of Users and the time of the latest user-entered command.

Scalability

Although the lack of a Database Management System (DBMS) has a huge negative impact in terms of scalability, the project focused on other aspects, such as the easiness of adding new commands, as well as the possibility of adding System Commands.

To implement the Commands structure, I took as inspiration the method applied in the Stack project. Therefore, each Command in Hamerkop is a record of a name, description and an ActionRunner. Using this structure, new commands can be added by simply updating the Commands list and implementing its specific ActionRunner, eliminating the need to change other functions.

Moreover, when the user enters a command, its input is parsed to an Action. The type of Action will depend on the user input:

  1. if the input starts with @, such as @bob -> hello, it is parsed to UserAct
  2. if the input starts with :, such as :help, it is parsed to SysAct

This structure was designed so that more commands can be added in the future, without syntax conflicts. Examples of future commands are:

<@user> unfollow <user>

<@user> remove <post>

:users displays the list of stored users

:remove <user>

:new <user> creates a new user without posts

IO / Environment

The running environment, represented by the data record Env, is evaluated and executed in terms of a State Monad. Each time the user enters a command, the application will:

  1. Update the Environment's date/time;
  2. Evaluate the Action in the current Enviroment;
  3. Return the result of the evaluation along with the updated Environment;

Tests

The tests were written in HSpec as part of the development process. Although tests were written for some edge cases, such as reading posts from an unexisting user, the majority of the tests considered only successful scenarios, as requested in the Code Challenge description. Still, common unsuccessful scenarios were handled with proper messages. For example:

:remove bob

Command remove not found.

@bob wall

Oops! bob's wall seems empty.

Further Improvements

A list of further improvements can be drawn from the current stage of the project:

  1. Introduce unfollow command;
  2. Introduce remove <post> command;
  3. Add Unique Identifiers to Users and Posts, so that future commands can operate on them;
  4. With more commands added, split Commands module so that each module handles only one Command;
  5. Use the YAML package to create test stubs;
  6. Use QuickCheck to generate edge case scenarios for tests.

The introduction of a DBMS was left out of the list because persisting the user data is not part of the current goal of the project.