mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-02-28 01:21:13 +01:00
Squashed commit of the following:
commit 62d59620d26bc97c7d689e9af57cd8bff654c79e Author: Julian Lam <julian@designcreateplay.com> Date: Wed Nov 4 11:04:27 2015 -0500 tweaked 503 template commit 15a61cbc239c9d654691d91cdadce59e13d97586 Author: Julian Lam <julian@designcreateplay.com> Date: Wed Nov 4 10:58:19 2015 -0500 added text about reloading being required if threshold values are changed commit 3fe87699332ef0628b4db31f4afef245802a7bc0 Author: Julian Lam <julian@designcreateplay.com> Date: Wed Nov 4 10:53:35 2015 -0500 added ACP settings for toobusy commit f6a9964baff051072052e6ef99da9e1ffba014df Author: Julian Lam <julian@designcreateplay.com> Date: Wed Nov 4 08:53:53 2015 -0500 removed unused 503a template commit e6d444736baf4c676f8461d30a5504c6e45df163 Author: Julian Lam <julian@designcreateplay.com> Date: Wed Nov 4 02:01:11 2015 -0500 updated code to send static 503 instead of maintenance-style page commit 11089ae2bb833e068b01ee77ee745d9fd5344805 Author: Julian Lam <julian@designcreateplay.com> Date: Wed Nov 4 01:18:45 2015 -0500 added toobusy support so the Node process doesn't fall over at high load
This commit is contained in:
@@ -68,6 +68,7 @@
|
||||
"socketio-wildcard": "~0.1.1",
|
||||
"string": "^3.0.0",
|
||||
"templates.js": "0.3.0",
|
||||
"toobusy-js": "^0.4.2",
|
||||
"uglify-js": "^2.4.24",
|
||||
"underscore": "~1.8.3",
|
||||
"underscore.deep": "^0.5.1",
|
||||
|
||||
160
public/503.html
Normal file
160
public/503.html
Normal file
@@ -0,0 +1,160 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Excessive Load Warning</title>
|
||||
<link href='http://fonts.googleapis.com/css?family=Ubuntu:400,500,700' rel='stylesheet' type='text/css'>
|
||||
<style type="text/css">
|
||||
body {
|
||||
background: #00A9EA;
|
||||
color: white;
|
||||
font-family: 'Ubuntu', sans-serif;
|
||||
text-align: center;
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-moz-transform-style: preserve-3d;
|
||||
transform-style: preserve-3d;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 250px;
|
||||
color: #fff;
|
||||
opacity: 0.5;
|
||||
margin: 10px;
|
||||
cursor: pointer;
|
||||
-moz-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
p strong {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.center {
|
||||
position: relative;
|
||||
top: 50%;
|
||||
-webkit-transform: translateY(50%);
|
||||
-ms-transform: translateY(50%);
|
||||
transform: translateY(50%);
|
||||
}
|
||||
|
||||
@-webkit-keyframes bounce {
|
||||
0%, 20%, 53%, 80%, 100% {
|
||||
-webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
||||
transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
||||
-webkit-transform: translate3d(0,0,0);
|
||||
transform: translate3d(0,0,0);
|
||||
}
|
||||
|
||||
40%, 43% {
|
||||
-webkit-transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||
transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||
-webkit-transform: translate3d(0, -30px, 0);
|
||||
transform: translate3d(0, -30px, 0);
|
||||
}
|
||||
|
||||
70% {
|
||||
-webkit-transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||
transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||
-webkit-transform: translate3d(0, -15px, 0);
|
||||
transform: translate3d(0, -15px, 0);
|
||||
}
|
||||
|
||||
90% {
|
||||
-webkit-transform: translate3d(0,-4px,0);
|
||||
transform: translate3d(0,-4px,0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes bounce {
|
||||
0%, 20%, 53%, 80%, 100% {
|
||||
-webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
||||
transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
||||
-webkit-transform: translate3d(0,0,0);
|
||||
transform: translate3d(0,0,0);
|
||||
}
|
||||
|
||||
40%, 43% {
|
||||
-webkit-transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||
transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||
-webkit-transform: translate3d(0, -30px, 0);
|
||||
transform: translate3d(0, -30px, 0);
|
||||
}
|
||||
|
||||
70% {
|
||||
-webkit-transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||
transition-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||
-webkit-transform: translate3d(0, -15px, 0);
|
||||
transform: translate3d(0, -15px, 0);
|
||||
}
|
||||
|
||||
90% {
|
||||
-webkit-transform: translate3d(0,-4px,0);
|
||||
transform: translate3d(0,-4px,0);
|
||||
}
|
||||
}
|
||||
|
||||
.bounce {
|
||||
-webkit-animation-name: bounce;
|
||||
animation-name: bounce;
|
||||
-webkit-transform-origin: center bottom;
|
||||
-ms-transform-origin: center bottom;
|
||||
transform-origin: center bottom;
|
||||
}
|
||||
|
||||
.animated {
|
||||
-webkit-animation-duration: 1s;
|
||||
animation-duration: 1s;
|
||||
-webkit-animation-fill-mode: both;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
.animated.infinite {
|
||||
-webkit-animation-iteration-count: infinite;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
.animated.hinge {
|
||||
-webkit-animation-duration: 2s;
|
||||
animation-duration: 2s;
|
||||
}
|
||||
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
window.onload = function() {
|
||||
var count = 0,
|
||||
bounce = document.getElementById('click-me');
|
||||
bounce.onclick = function() {
|
||||
count++;
|
||||
bounce.className = '';
|
||||
setTimeout(function() {
|
||||
bounce.className = 'animated bounce';
|
||||
}, 50);
|
||||
|
||||
if (count > 5) {
|
||||
document.getElementById('hide').className = '';
|
||||
}
|
||||
};
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
<div class="center">
|
||||
<h1 id="click-me" class="animated bounce">503</h1>
|
||||
<p>
|
||||
<strong>This forum is temporarily unavailable due to excessive load.</strong> <br />
|
||||
We shouldn't be down for long. Please check back shortly. Sorry for the inconvenience!
|
||||
</p>
|
||||
<p id="hide" class="hide">
|
||||
<small>Alright. You can stop clicking... it's not going to make the site come back sooner!</small>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -42,5 +42,7 @@
|
||||
"account/watched": "Topics watched by %1",
|
||||
|
||||
"maintenance.text": "%1 is currently undergoing maintenance. Please come back another time.",
|
||||
"maintenance.messageIntro": "Additionally, the administrator has left this message:"
|
||||
"maintenance.messageIntro": "Additionally, the administrator has left this message:",
|
||||
|
||||
"throttled.text": "%1 is currently unavailable due to excessive load. Please come back another time."
|
||||
}
|
||||
@@ -11,13 +11,13 @@ var app,
|
||||
validator = require('validator'),
|
||||
nconf = require('nconf'),
|
||||
ensureLoggedIn = require('connect-ensure-login'),
|
||||
toobusy = require('toobusy-js'),
|
||||
|
||||
plugins = require('../plugins'),
|
||||
meta = require('../meta'),
|
||||
user = require('../user'),
|
||||
groups = require('../groups'),
|
||||
|
||||
|
||||
analytics = require('../analytics'),
|
||||
|
||||
controllers = {
|
||||
@@ -25,6 +25,9 @@ var app,
|
||||
helpers: require('../controllers/helpers')
|
||||
};
|
||||
|
||||
toobusy.maxLag(parseInt(meta.config.eventLoopLagThreshold, 10) || 70);
|
||||
toobusy.interval(parseInt(meta.config.eventLoopInterval, 10) || 500);
|
||||
|
||||
middleware.authenticate = function(req, res, next) {
|
||||
if (req.user) {
|
||||
return next();
|
||||
@@ -217,6 +220,13 @@ middleware.privateUploads = function(req, res, next) {
|
||||
next();
|
||||
};
|
||||
|
||||
middleware.busyCheck = function(req, res, next) {
|
||||
if (toobusy()) {
|
||||
res.type('text/html').sendFile(path.join(__dirname, '../../public/503.html'));
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = function(webserver) {
|
||||
app = webserver;
|
||||
|
||||
@@ -5,7 +5,7 @@ var helpers = {};
|
||||
helpers.setupPageRoute = function(router, name, middleware, middlewares, controller) {
|
||||
middlewares = middlewares.concat([middleware.pageView, middleware.pluginHooks]);
|
||||
|
||||
router.get(name, middleware.buildHeader, middlewares, controller);
|
||||
router.get(name, middleware.busyCheck, middleware.buildHeader, middlewares, controller);
|
||||
router.get('/api' + name, middlewares, controller);
|
||||
};
|
||||
|
||||
|
||||
@@ -41,4 +41,33 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-2 col-xs-12 settings-header">Traffic Management</div>
|
||||
<div class="col-sm-10 col-xs-12">
|
||||
<p class="help-block">
|
||||
NodeBB deploys equipped with a module that automatically denies requests in high-traffic
|
||||
situations. You can tune these settings here, although the defaults are a good starting
|
||||
point.
|
||||
</p>
|
||||
<form>
|
||||
<div class="form-group">
|
||||
<label for="eventLoopLagThreshold">Event Loop Lag Threshold (in milliseconds)</label>
|
||||
<input class="form-control" id="eventLoopLagThreshold" type="number" data-field="eventLoopLagThreshold" placeholder="Default: 70" step="10" value="70" />
|
||||
<p class="help-block">
|
||||
Lowering this value decreases wait times for page loads, but will also show the
|
||||
"excessive load" message to more users. (Reload required)
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="eventLoopInterval">Check Interval (in milliseconds)</label>
|
||||
<input class="form-control" id="eventLoopInterval" type="number" data-field="eventLoopInterval" placeholder="Default: 500" value="500" step="50" />
|
||||
<p class="help-block">
|
||||
Lowering this value causes NodeBB to become more sensitive to spikes in load, but
|
||||
may also cause the check to become too sensitive. (Reload required)
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- IMPORT admin/settings/footer.tpl -->
|
||||
Reference in New Issue
Block a user