Skip to content

Home assignment: multi-server vote application without central database

Notifications You must be signed in to change notification settings

stevenhilder/vote

Repository files navigation

Home assignment

screenshot

  • Overview

    • Back-end developed on CentOS 7.5 with PHP 7.2 (via PHP-FPM and Nginx)
      • Vote storage in POSIX shared memory (with atomic locking to prevent race conditions)
      • Communication between servers using WebSockets
    • Front-end built using Semantic UI with minimal client-side JavaScript
    • Run make to install the project's dependencies and start the WebSocket listener

  • Project structure:

    • nginx.conf - Sample virtual host configuration for Nginx
    • vote-config.json - JSON configuration file (supports customization of vote options and server addresses)
    • public/
      • FrontController.php - Webserver entry point, invokes VoteApplication with global request data
    • src/
      • VoteOption.php - A simple class representing a single vote option
      • VoteConfig.php - Loads configuration file and provides logic for counting votes and returning results
      • VoteApplication.php - Deals with request/response routing and HTML rendering
      • templates/ - HTML templates for rendering responses with support for {{ placeholders }}
    • bin/
      • websocket-server - Invoked automatically by make or make run
      • reset - Clears data from shared memory; invoked automatically by make reset or make clean

PHP dependencies are managed using Composer. The Composer PHAR installer is bundled with this project; running make should install all required files.

Required PHP extensions (all are bundled with PHP, no PECL extensions required):

  • ext/json for parsing JSON configuration file
  • ext/pcre regular expressions used for rendering HTML templates and validating data
  • ext/sysvsem & ext/sysvshm System V IPC semaphores and shared memory

  • Proposed improvements:

    • Use a database as a central source of truth for vote configuration
      • Current solution (configuration files on each webserver) susceptible to fragmentation
      • Either relational or NoSQL could fulfill this requirement
      • Read/write master and read-only slave(s) for load balancing
    • Use a more robust system for vote storage
      • Redis would provide high performance, persistence and single-round-trip atomic integer increment
      • Alternatively, if data of individual votes is desired (eg. timestamp, origin IP address etc.), an event store such as Kafka could provide distributed storage of votes
    • Use a daemon on each webserver to maintain persistent WebSocket connections between servers
      • Current solution reconnects for every results query
      • Daemon could automatically re-establish failed connections
      • Use WAMP subprotocol for standardized PubSub and/or RPC communication over WebSockets or raw TCP sockets
    • Implement client-server WebSocket communication for front-end so that results can update in real time

About

Home assignment: multi-server vote application without central database

Resources

Stars

Watchers

Forks

Languages