Distraught Web Server
I was distraught!!
Distraught is a wrapper around a Node.js Express server that exposes an HTTPServer for web requests, a CronServer for functions that need to be called at set intervals, and a WorkerServer to handle long requests.
Assumptions
- You have a webserver running Node.js
- Postgresql as the datastore
- Redis as the caching layer and sockets
- RabbitMQ for worker jobs
Libraries
- ExpressJS
- Mariner - Vanilla SQL Database Migrations
- Heretic - Queueing / Dequeueing Jobs
- Google Cloud Storage - File Storage
- Sentry - Error Handling
- Cron - For Timed Jobs
- Axios - For API Requests
- Sendgrid - Sending Emails
- Twilio - Text Messaging
- Socket.IO - Websockets
- Swagger - API Documentation
Expected Migrations / Tables In Order To Use WorkerServer
This does require some migrations to be ran, however this server does -not- run the migrations on startup. If you are using Distraught for the first time, please run the following migration:
( id SERIAL NOT NULL PRIMARY KEY, queue_name text NOT NULL, status text DEFAULT 'pending', payload jsonb, attempt_logs jsonb[] DEFAULT '{}', max_attempts int NOT NULL DEFAULT 1, created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now(), last_attempted_at timestamptz); heretic_jobs (queue_name); heretic_jobs (status); () RETURNS TRIGGER AS $$BEGIN NEW.updated_at = now(); RETURN NEW;END;$$ LANGUAGE 'plpgsql'; BEFORE UPDATE ON heretic_jobs FOR EACH ROW EXECUTE PROCEDURE heretic_updated_at_timestamp();
Processes
The framework is setup to run three processes: web, crons, and workers.
- Web
- Will boot up the Express server
- Crons
- These are processes that run in the background at set intervals
- Workers
- Workers are background processes that may take quite a bit of time to complete, so they are enqueued to a RabbitMQ server via Heretic, a simple RabbitMQ interface
Logging
- Supports sending all server logs to Logentries if a
LOGENTRIES_TOKEN
is present. - Supports sending uncaught/unhandled errors to Sentry if a
SENTRY_DSN
is present.
Logging Errors
const logErr = ; ;
Server Monitoring
In httpserver
, if you specify enableStatusMonitor: true
, a /status
page will be accessible on the same port that the Express server is running that memory usage, CPU usage, response time, requests per second, and number of responses by status code using express-status-monitor
Database
- Utilizes Knex to handle your queries
Setting Up Your Connections
const d = ; d;
Querying The Database
const db toCamelCase createOne = ; { return db ;} { return ;}
HTTPServer
const httpServer init = ; ; const homeController = ; const server = ; serverapp; /* WEB ROUTES */serverapp; authController; serverstart;
Templates
By default, HTTPServer will render pug templates, but you can change the view engine to whatever you want during instantiation.
Adding/Changing View Engines
const httpServer = ; const server = ; serverapp;
Swagger
To enable Swagger:
const server = ;
Example of Creating API/Config Folders and Using the Swagger Editor Swagger - Getting Started
WorkerServer
// Make sure the Heretic database migration has run const init workerServer MINUTE heretic chalk log = ; ; { ; return Promise ;} { hereticdefault; ;} { const debug = processenvWORKER_DEBUG; const workers = ; workersstart;}; ;;
Enqueueing jobs
; hereticdefault;
Crons
const cronServer log chalk = ; exports { ;};
Caching
Caching Individual Functions
Getting value from cache by key, or setting it via a function
const init cache MINUTE = ; ; const getValueFn = { return ; }; // Can be a scalar, function returning a scalar, or function returning a Promise const ttl = MINUTE * 3; { return cachedefault ; } await ; // Cache missed await ; // Cache hit
Invalidating Keys
The below example will remove all-users
from the cache
const cache = ; cachedefault;
Thanks
Thanks to Hackathon Starter for a lot of inspiration