GithubHelp home page GithubHelp logo

imaxopoly / sports-event-timer Goto Github PK

View Code? Open in Web Editor NEW
1.0 2.0 1.0 3.72 MB

Race event simulation in ReactJS and Golang using react-redux and react-saga.

License: The Unlicense

Batchfile 0.14% Go 28.16% JavaScript 66.63% HTML 1.07% CSS 4.00%
golang httprouter reactjs es6 react-redux react-saga

sports-event-timer's Introduction

GitHub license Go Report Card DeepScan grade Build Status

Sports Event Timing

Sports Event Timing

Sports Event Timing' demonstrates the simulation of a race among dummy participants, both server-sided and client-sided.

The simulation is a choice that can be run either solely on the client-side, concurrently using reactjs redux-sagas OR entirely on the server side where reactjs ensures to update the client-side accordingly.

App Demo

Race Preface

Every athlete carries a chip with a unique identifier. There are two set time points in the race, both of which also carrying unique chip identifiers, individually trigger a signal to the server side, indicating the athlete has reached said time point.

Client Side Simulation

In case of the client side simulation, the client fetches dummy race participants, and dummy time points. Concurrently, the sagas then simulate the athletes running on the track, where whenever any given athlete trips over a given time point, the following information is sent to the server:

  1. Athlete Chip Identifier
  2. Time taken for the athlete to reach that time point
  3. Time Point Chip Identifier

The server then acnkowledges the request using REST endpoints and then stores the information in the database.

Server Side Simulation

On the other hand, for the server side simulation, the server executes a goroutine-based race among athletes, stores their data in the database and makes that data available for client side fetching via REST endpoints. The server also uses similar mechanics to detect athlete chip identifiers and time point chip identifiers.

Prerequisites

1. Go development environment and;
2. NPM/Yarn;
3. GCC 64 bit for inbuilt sqlite3 database support; 
   preferrably: https://sourceforge.net/projects/mingw-w64/

Installing

On a Windows machine, project can be built using the build.bat file. Subsequently, it will create a dist folder that will contain the production ReactJS files as well as the backend binary. Please ensure 64 bit gcc(required for sqlite3) is available at command prompt.

1. Clone the project in the src folder of your GOPATH
2. Change directory into the project root
3. Ensure that the project directory is called 'sports-event-timing' 
   and follows the following folder structure: 'GOPATH/src/sports-event-timing/source/backend'
3. Run ./build.bat

Alternatively, production files can also be generated separately(backend and frontend). Again, please ensure 64 bit gcc(required for sqlite3) is available at command prompt. Steps as follows:

1. Clone the project in your GOPATH or download the repository as zip and extract it in your GOPATH.
2. Ensure that the project directory is called 'sports-event-timing' 
   and follows the following folder structure: 'GOPATH/src/sports-event-timing/source/backend'
3. Change directory into the %project root%/source/backend folder.
4. Run go build to get the built executable.
5. Change directory into the %project root%/source/frontend folder.
6. Run 'npm install' or just 'yarn'(project uses yarn) to install dependencies.
7. Run 'npm run build' or 'yarn build' to generate production files that will be placed inside %project root%/dist/ folder.
8. Make sure the server executable is in the same folder as all other distribution files i. e. same folder as index.html

Backend REST API Overview

The backend uses the package httprouter as its main mux to server REST Endpoints.

By default, the server port is 8082

Server Simulated Race EndPoints

endpoint method description
/server/race-simulation/start GET Starts of the Race Event
/server/race-simulation/stop GET Stops the Race Event
/server/race-simulation/fetch/live-standings GET Returns the list of athletes with their race-relevant attributes in a live race
/server/race-simulation/fetch/last-standings GET Returns the list of athletes with their race-relevant attributes from the last race whereby, a race is currently not live

Sample Calls

Start Race

Request:

curl 'http://localhost:8082/server/race-simulation/start'

Response:

{"responseMessage":"starting race","athletes":[{"startNumber":1,"fullName":"Manish Singh","identifier":"bbk15uu8auq2p50gu1i0","timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1},{"startNumber":2,"fullName":"Madhushree Singh","identifier":"bbk15uu8auq2p50gu1ig","timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1},{"startNumber":3,"fullName":"Siim Kaspar Uustalu","identifier":"bbk15uu8auq2p50gu1j0","timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1},{"startNumber":4,"fullName":"Eliisabeth Käbin","identifier":"bbk15uu8auq2p50gu1jg","timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1},{"startNumber":5,"fullName":"Ahti Liin","identifier":"bbk15uu8auq2p50gu1k0","timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1}]}

Stop Race

Request:

curl 'http://localhost:8082/server/race-simulation/stop'

Response:

{"responseMessage":"stopping race"}

Get live Athlete values in a live Race

Request:

curl 'http://localhost:8082/server/race-simulation/fetch/live-standings'

Response:

{"responseMessage":"race is in process, showing live data","athletes":[{"startNumber":1,"fullName":"Manish Singh","identifier":"bbk15uu8auq2p50gu1i0","timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1},{"startNumber":2,"fullName":"Madhushree Singh","identifier":"bbk15uu8auq2p50gu1ig","timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1},{"startNumber":3,"fullName":"Siim Kaspar Uustalu","identifier":"bbk15uu8auq2p50gu1j0","timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1},{"startNumber":4,"fullName":"Eliisabeth Käbin","identifier":"bbk15uu8auq2p50gu1jg","timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1},{"startNumber":5,"fullName":"Ahti Liin","identifier":"bbk15uu8auq2p50gu1k0","timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1}]}

Get Athlete values in a from the last Race

Request:

curl 'http://localhost:8082/server/race-simulation/fetch/last-standings'

Response:

{"responseMessage":"race is currently not in process, showing last race data","athletes":[{"startNumber":1,"fullName":"Manish Singh","identifier":"bbk15uu8auq2p50gu1i0","location":209,"timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1},{"startNumber":2,"fullName":"Madhushree Singh","identifier":"bbk15uu8auq2p50gu1ig","location":203,"timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1},{"startNumber":3,"fullName":"Siim Kaspar Uustalu","identifier":"bbk15uu8auq2p50gu1j0","location":226,"timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1},{"startNumber":4,"fullName":"Eliisabeth Käbin","identifier":"bbk15uu8auq2p50gu1jg","location":201,"timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1},{"startNumber":5,"fullName":"Ahti Liin","identifier":"bbk15uu8auq2p50gu1k0","location":201,"timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1}]}

Client Simulated Race EndPoints

endpoint method description
/client/race-simulation/start GET Starts of the Race Event
/client/race-simulation/stop GET Stops the Race Event
/client/race-simulation/fetch/current-standings GET Returns the list of athletes with their race-relevant attributes in a live race
/client/race-simulation/push/current-standings POST Accepts athlete attributes which it then stores in the database in a live race

Sample Calls

Start Race

Request:

curl 'http://localhost:8082/client/race-simulation/start'

Response:

{"responseMessage":"starting race","athletes":[{"startNumber":1,"fullName":"Manish Singh","identifier":"bbk0q968auq2p50gu1b0","timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1},{"startNumber":2,"fullName":"Madhushree Singh","identifier":"bbk0q968auq2p50gu1bg","timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1},{"startNumber":3,"fullName":"Siim Kaspar Uustalu","identifier":"bbk0q968auq2p50gu1c0","timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1},{"startNumber":4,"fullName":"Eliisabeth Käbin","identifier":"bbk0q968auq2p50gu1cg","timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1},{"startNumber":5,"fullName":"Ahti Liin","identifier":"bbk0q968auq2p50gu1d0","timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1}],"timePoints":[{"name":"Corridor Timepoint","location":800,"identifier":"bbk0q968auq2p50gu1dg"},{"name":"Finish Line Timepoint","location":1000,"identifier":"bbk0q968auq2p50gu1e0"}]}

Stop Race

Request:

curl 'http://localhost:8082/client/race-simulation/stop'

Response:

{"responseMessage":"stopping race"}

Fetch Current Athletes in the Race

Request:

curl 'http://localhost:8082/client/race-simulation/fetch/current-standings'

Response:

{"responseMessage":"race is in process, showing live data","athletes":[{"startNumber":1,"fullName":"Manish Singh","identifier":"bbk15hu8auq2p50gu1eg","timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1},{"startNumber":2,"fullName":"Madhushree Singh","identifier":"bbk15hu8auq2p50gu1f0","timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1},{"startNumber":3,"fullName":"Siim Kaspar Uustalu","identifier":"bbk15hu8auq2p50gu1fg","timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1},{"startNumber":4,"fullName":"Eliisabeth Käbin","identifier":"bbk15hu8auq2p50gu1g0","timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1},{"startNumber":5,"fullName":"Ahti Liin","identifier":"bbk15hu8auq2p50gu1gg","timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1}]}

Push updated Athletes values from Client to Server

Request:

curl 'http://localhost:8082/client/race-simulation/push/current-standings' --data-binary '{"requestCommand":"commit feed","athletes":[{"timeElapsed":33614,"identifier":"bbk0ntm8auq2p50gu17g","timePointIdentifier":"bbk0ntm8auq2p50gu1a0"}]}'

Response:

{"responseMessage":"race is in process, data was committed, showing committed data","athletes":[{"startNumber":1,"fullName":"Manish Singh","identifier":"bbk0ntm8auq2p50gu17g","inFinishCorridor":true,"timeTakenToReachFinishCorridor":33614,"timeTakenToFinish":-1},{"startNumber":2,"fullName":"Madhushree Singh","identifier":"bbk0ntm8auq2p50gu180","timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1},{"startNumber":3,"fullName":"Siim Kaspar Uustalu","identifier":"bbk0ntm8auq2p50gu18g","timeTakenToReachFinishCorridor":-1,"timeTakenToFinish":-1},{"startNumber":4,"fullName":"Eliisabeth Käbin","identifier":"bbk0ntm8auq2p50gu190","inFinishCorridor":true,"timeTakenToReachFinishCorridor":33485,"timeTakenToFinish":-1},{"startNumber":5,"fullName":"Ahti Liin","identifier":"bbk0ntm8auq2p50gu19g","inFinishCorridor":true,"timeTakenToReachFinishCorridor":33647,"timeTakenToFinish":-1}]}

  • Notes:

Ideally, the response message should be in the format of 'success' or 'fail' and should use status codes more effectively to better adhere to REST EndPoint standards. The backend uses defensive analysis to ascertain the condition of the race event before responding to the client. The client side, might however, lack coping mechanisms to accurately reflect the backend's status responses. This is true at the time of writing.

1, May, 2018


FrontEnd Overview

The frontend is based on ReactJS, using Redux for state-management and Redux Saga as a side-effects middleware.

Bootstrap is used as the CSS framework of choice and SCSS is used to modify the theme.

Click here to see the component diagram of the application structure.

  • Notes:

CSS modules in combination with SCSS files that allow for global CSS/SCSS dependencies(or from node_modules) to stay intact would have been a much proficient set up, not found in this project. Usage of FlipMove external dependency seems to be bad with performance, however, ideal for this project, compared to my slide animation attempt using react-transition-group, but definitely something to retry.

1, May, 2018

Database Overview

The current database used is sqlite 3. For the database, GORM is used as an ORM to allow quick replacement of database software without requiring to re-write code.

These are the following tables created:

athlete_db_models

contains columns: 
full_name                               string
start_number                            int
chip_identifier                         string
in_finish_corridor                      boolean
has_finished                            boolean
location                                int
time_taken_to_reach_finish_corridor     int
time_taken_to_finish                    int

timepoint_db_models

contains columns: 
name                                    string
location                                int
chip_identifier                         string

The database file itself(called 'RaceEventDB.db') is located in the 'dist' folder if using production build.

To-do

  • Thorough Unit-Testing.
  • Replace mutexes in backend with pure channel-based solution.
  • Stories on frontend.

Built With

  • httprouter - The backend router used
  • react - The frontend javascript library used
  • redux - State Management
  • redux-saga - To handle side-effects and other asynchronous tasks
  • sqlite3 - Relational drop-in database for quick demo

Author

License

This project is licensed under The Unlicence License - see the LICENSE file for details

sports-event-timer's People

Contributors

imaxopoly avatar kryptodev avatar

Stargazers

 avatar

Watchers

 avatar  avatar

Forkers

dontbugmie

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.