cul-2016 / quiz

11 stars 4 forks source link

Quodl

Build Status codecov.io Dependency Status devDependency Status

This project uses Node version 6.9.x, PostgreSQL version 9.5.x and Redis 3.2.x.

Quick Start

/ config.env /

#!/bin/bash
unset PORT
export DATABASE_USER=<db_user>
export DATABASE_PASSWORD=<db_password>
export DATABASE_HOST=<aws_db_host>
export DATABASE_PORT=5432
export DATABASE_NAME=<db_name>
export TEMPLATE_DIRECTORY=./server/templates
export SENDER_EMAIL_ADDRESS=quiz.cityuni@gmail.com
export AWS_REGION=us-west-2
export AWS_ACCESS_KEY_ID=<aws_access_key>
export AWS_SECRET_ACCESS_KEY=<aws_secret_access_key>
export SERVER_ROUTE=http://localhost:9000
export JWT_SECRET=<secret>
export FORUM_URL=http://localhost:4567
export STUDY_PLANNER_URL=http://localhost:5000

and run source local.env

Testing

Overview

The app has a staging version and a production version.

Staging version:

Production version:

AWS Database

The live database is a postgresql instance, hosted on aws (rds). The class of the instance is db.t2.small during the week, and, using an aws lambda, is downgraded to db.t2.micro at the weekend, when the app will see the least use.

The upgrade/downgrade class and schedule can be edited on aws:

Backups are automated to happen daily between 22:00 and 22:30. This window can be changed, but backups do not cause any significant downtime (a few seconds at most).

To manually modify the instance specifications, select the instance on the aws rds page, and choose modify from the instance actions. Any changes made here will occur during the maintenance window (Saturday 3:00am - 3:30am, but changeable) unless Apply Immediately is selected.

Directory Structure

├── server
    ├── lib        # Helper functions for the server handlers logic
    ├── plugins    # Server plugins
    ├── templates  # Email templates see [dwyl/sendemail](https://github.com/dwyl/sendemail)
    |
    ├── server.js  # Main Server logic
    └── start.js   # Starts the server
├── src
    ├── js         # [Typical redux file structure](https://jaysoo.ca/2016/02/28/organizing-redux-application/)
        ├── actions
        ├── reducers
        ├── routes
        ├── container
        ├── components
        |
        ├── index.js   # Entry point
        ├── root.js
        ├── socket.js  # Implementation of socket.io
        └── store.js
    ├── scss           # To start the server
    └── utils          # Dev server configuration
├── test
    ├── front
    └── back
├── public # Files served by server
    ├── bundle.js  # Webpack bundle of the `src/js/index.js` entry point
    ├── index.html
    └── ...
├── package.json
├── README.md
└── ...

General information

Account Types

Super Admin

Client

Lecturers

Students

State hydration

onEnter hooks

src/root.js contains the routes for the different views.

Each route makes use of React Router's onEnter hooks. Functions that run onEnter can be found in src/js/lib/onEnterHooks.js

All routes run an authenticate function, with the exception of the IndexRoute and the two routes that deal with user sign up.

Routes for the ModuleContainer and StudentModuleContainer views also run fetchModule.

Redux store listeners

Redux allows you to listen for state changes and run functions.

These listeners are located in src/js/lib/subscriptions.js.

fetchDashboard is registered when the Dashboard component is mounted. It executes when state.user.is_lecturer !== undefined

joinWebsocketRoom is registered when the Module and StudentModule components are mounted. It executes when state.module.module_id !== undefined.

Quiz flow

Go to a module's page - you automatically enter that module's socket room.
Lecturer invites students to a particular quiz
sendQuizInvite is run, which runs emitSendQuizInvite
emitSendQuizInvite emits the send_quiz_invite socket event on an interval
receive_quiz_invite is received by students
Button to the live-quiz page is activated (because isQuizOpen)
Lecturer starts the quiz
startQuiz is run, which runs sendNextQuestion
emitSendNextQuestion emits the send_next_question socket event
receive_next_question is received by students

Load Testing

We are using artillery for load testing the application. You'll find three files in the root directory with the prefix of loadtest.

Here are the list of steps that you'll need to take for stress Testing

  1. install artillery with npm i -g artillery
  2. get cookie from the app. You'll need to login to each version of the app as student@city.ac.uk and then use the cookie.
  3. Paste this cookie in the related loadtest file. You will need to replace the following text get cookie from headers in the live app for user student@city.ac.uk and paste it here with your new cookie
  4. run the following command to run the loadtests and pipe the results into a .txt file artillery run loadtest-{version}.yml > loadtest-{version}.txt
  5. Once the loadtesting is complete you can view the results in the .txt file.

Our findings on the load testing

Staging

The staging version of the app is hosted on basic heroku with no paid options. (free postgres w/ option of 10 max concurrent connections). We reach saturation point in phase 6 of the load testing where it starts to throw errors when it reaches ~60 concurrent users

Live

The live version of the app is hosted on 1 dyno @ $25. We reached a saturation point somewhere between 320 - 500 concurrent users where it started to throw errors. This is approximately a six fold increase.

LTI Integration

Quodl is available to be used as an external tool in Moodle through LTI.

For details on how to set this up, see the LTI Integration guide

Privacy Statement

The in-app privacy statement for Quodl has been updated in line with GDPR as per issue #716.
If further changes are required, these can be easily made by updating the following file: src/js/components/privacy-message.js.