Skip to content

Commit 2c22f0e

Browse files
committed
Use MySQL Pool and add error handling for offline DB
1 parent 687c272 commit 2c22f0e

5 files changed

Lines changed: 90 additions & 6 deletions

File tree

app.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const _ = require('lodash');
1515
const logger = require('./utils').logger;
1616
const syslog = require('./utils').syslog;
1717
const settings = require('./utils').settings;
18+
const dbStatus = require('./utils').dbStatus;
1819

1920
const User = require('./models/User');
2021
const Tier = require('./models/Tier');
@@ -97,6 +98,10 @@ app.use(bodyParser.urlencoded({ limit: '5mb', extended: false }));
9798
app.use(express.static(path.join(__dirname, 'public')));
9899

99100
app.use('*', (req, res, next) => {
101+
if (!dbStatus()) {
102+
return res.render('epicfail', {basehref: settings.general.basehref, messages: null, title: 'Uh oh, something bad has happened'});
103+
}
104+
100105
// Skip if user is accessing api
101106
if (req.params[0].slice(0, 5) === '/api/') next();
102107
else {

models/db.js

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
const mysql = require('mysql');
22
const settings = require('../utils').settings;
33
const logger = require('../utils').logger;
4+
const dbStatus = require('../utils').dbStatus;
45

56
let db = settings.db.prod;
67

78
if (process.env.spec === "true") {
89
db = settings.db.spec
910
}
1011

11-
var connection = mysql.createPool({
12+
var pool = mysql.createPool({
1213
connectionLimit: 10,
1314
host: db.host,
1415
socketPath: db.socketPath,
@@ -20,15 +21,68 @@ var connection = mysql.createPool({
2021

2122
module.exports.init = function(cb) {
2223

23-
connection.on('connection', connection => {
24+
pool.on('connection', connection => {
2425
logger('[db]: connected as id ' + connection.threadId);
2526
cb();
2627
});
2728

29+
pool.getConnection((err, connection) => {
30+
if (err) {
31+
return dbStatus(false);
32+
}
33+
connection.query('SELECT 1', [], () => {
34+
dbStatus(true);
35+
connection.release();
36+
});
37+
});
38+
2839
// Keep connection alive
2940
setInterval(() => {
30-
connection.query('SELECT 1');
41+
pool.getConnection((err, connection) => {
42+
if (err) {
43+
return dbStatus(false);
44+
}
45+
connection.query('SELECT 1', [], () => {
46+
dbStatus(true);
47+
connection.release();
48+
});
49+
});
3150
}, db.keepAliveInterval);
3251
};
3352

34-
module.exports.connection = connection;
53+
module.exports.connection = {
54+
query: function () {
55+
let queryArgs = Array.prototype.slice.call(arguments),
56+
events = [],
57+
eventNameIndex = {};
58+
59+
pool.getConnection((err, conn) => {
60+
if (err) {
61+
if (eventNameIndex.error) {
62+
eventNameIndex.error();
63+
}
64+
}
65+
if (conn) {
66+
let q = conn.query.apply(conn, queryArgs);
67+
q.on('end', () => {
68+
conn.release();
69+
});
70+
71+
events.forEach(args => {
72+
q.on.apply(q, args);
73+
});
74+
}
75+
});
76+
77+
return {
78+
on: function (eventName, callback) {
79+
events.push(Array.prototype.slice.call(arguments));
80+
eventNameIndex[eventName] = callback;
81+
return this;
82+
}
83+
};
84+
},
85+
escape: val => pool.escape(val)
86+
};
87+
88+
//module.exports.connection = connection;

server.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const db = require('./models/db').init(() => {
2222
});
2323

2424
server.listen(app.get('port'));
25-
server.on('error', error => {
25+
server.once('error', error => {
2626
let bind = app.get('port');
2727
switch (error.code) {
2828
case 'EACCES':
@@ -38,7 +38,7 @@ const db = require('./models/db').init(() => {
3838
}
3939
});
4040

41-
server.on('listening', () => {
41+
server.once('listening', () => {
4242
let addr = server.address();
4343
let bind = typeof addr === 'string'
4444
? 'pipe ' + addr

utils.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ const stripe = require("stripe")(settings.stripe.secretKey);
88
redis.config('SET', 'maxmemory', settings.general.redisMaxMemory);
99
redis.on('error', err => module.exports.logger(err) && module.exports.syslog(err));
1010

11+
let dbOnline = true;
12+
1113
module.exports = {
1214
pad(n, width, z) {
1315
z = z || '0';
@@ -79,6 +81,13 @@ module.exports = {
7981
missingProps(obj, expected) {
8082
return !expected.every(prop => prop in obj && obj[prop] !== undefined);
8183
},
84+
dbStatus(status) {
85+
if (status === undefined) {
86+
return dbOnline;
87+
} else {
88+
dbOnline = status;
89+
}
90+
},
8291
redis,
8392
stripe,
8493
settings

views/pages/epicfail.ejs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<% include ../snippets/header %>
5+
<link rel="stylesheet" href="css/demoEditor.css">
6+
</head>
7+
<body>
8+
<div class="main">
9+
<section class="hero">
10+
<h3>Uh oh, something has gone wrong.</h3>
11+
<h5 id="subtitle">Please try your request again later. If the problem still persists, please send us a tweet <a href="http://twitter.com/randomapi" class="green">@RandomAPI</a>. Thanks!</h5>
12+
</section>
13+
</div>
14+
<% include ../snippets/footer %>
15+
</body>
16+
</html>

0 commit comments

Comments
 (0)