-
- 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
- Back-end developed on CentOS 7.5 with PHP 7.2 (via PHP-FPM and Nginx)
-
- 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
ormake run
- reset - Clears data from shared memory; invoked automatically by
make reset
ormake clean
- websocket-server - Invoked automatically by
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
-
- 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
- Use a database as a central source of truth for vote configuration