Add safe shudown
- SIGINT is intercepted and force-quits the 2nd time - Live countdown on Web UI - Countdown ignored if all clients disconnect - Clean exit function
This commit is contained in:
parent
7a89d45e48
commit
eb7d91ffbc
7 changed files with 111 additions and 1 deletions
|
@ -19,6 +19,7 @@
|
|||
</div>
|
||||
<div id="footer"></div>
|
||||
<div id="status"></div>
|
||||
<div id="countdown"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/ssh/webssh2.bundle.js" defer></script>
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -246,6 +246,30 @@ body, html {
|
|||
text-align: left;
|
||||
z-index: 100;
|
||||
}
|
||||
#countdown {
|
||||
display: none;
|
||||
color: rgb(240, 240, 240);
|
||||
background-color: rgb(50, 50, 50);
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
border-color: white;
|
||||
border-style: none solid none solid;
|
||||
border-width: 1px;
|
||||
text-align: left;
|
||||
z-index: 100;
|
||||
}
|
||||
#countdown.active {
|
||||
display: inline-block;
|
||||
animation: countdown infinite alternate 200ms;
|
||||
}
|
||||
@keyframes countdown {
|
||||
from {
|
||||
background-color: rgb(255, 255, 0);
|
||||
}
|
||||
to {
|
||||
background-color: inherit;
|
||||
}
|
||||
}
|
||||
#menu {
|
||||
display: inline-block;
|
||||
font-size: 16px;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
</div>
|
||||
<div id="footer"></div>
|
||||
<div id="status"></div>
|
||||
<div id="countdown"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/ssh/webssh2.bundle.js" defer></script>
|
||||
|
|
|
@ -75,6 +75,30 @@ body, html {
|
|||
text-align: left;
|
||||
z-index: 100;
|
||||
}
|
||||
#countdown {
|
||||
display: none;
|
||||
color: rgb(240, 240, 240);
|
||||
background-color: rgb(50, 50, 50);
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
border-color: white;
|
||||
border-style: none solid none solid;
|
||||
border-width: 1px;
|
||||
text-align: left;
|
||||
z-index: 100;
|
||||
}
|
||||
#countdown.active {
|
||||
display: inline-block;
|
||||
animation: countdown infinite alternate 200ms;
|
||||
}
|
||||
@keyframes countdown {
|
||||
from {
|
||||
background-color: rgb(255, 255, 0);
|
||||
}
|
||||
to {
|
||||
background-color: inherit;
|
||||
}
|
||||
}
|
||||
#menu {
|
||||
display: inline-block;
|
||||
font-size: 16px;
|
||||
|
|
|
@ -26,6 +26,7 @@ var status = document.getElementById('status')
|
|||
var header = document.getElementById('header')
|
||||
var dropupContent = document.getElementById('dropupContent')
|
||||
var footer = document.getElementById('footer')
|
||||
var countdown = document.getElementById('countdown')
|
||||
var fitAddon = new FitAddon()
|
||||
var terminalContainer = document.getElementById('terminal-container')
|
||||
term.loadAddon(fitAddon)
|
||||
|
@ -136,6 +137,7 @@ socket.on('disconnect', function (err) {
|
|||
'WEBSOCKET SERVER DISCONNECTED: ' + err
|
||||
}
|
||||
socket.io.reconnection(false)
|
||||
countdown.classList.remove('active')
|
||||
})
|
||||
|
||||
socket.on('error', function (err) {
|
||||
|
@ -149,6 +151,18 @@ socket.on('reauth', function () {
|
|||
(allowreauth) && reauthSession()
|
||||
})
|
||||
|
||||
// safe shutdown
|
||||
var hasCountdownStarted = false
|
||||
|
||||
socket.on('shutdownCountdownUpdate', function (remainingSeconds) {
|
||||
if (!hasCountdownStarted) {
|
||||
countdown.classList.add('active')
|
||||
hasCountdownStarted = true
|
||||
}
|
||||
|
||||
countdown.innerText = 'Shutting down in ' + remainingSeconds + 's'
|
||||
})
|
||||
|
||||
term.onTitleChange(function (title) {
|
||||
document.title = title
|
||||
})
|
||||
|
|
|
@ -199,4 +199,50 @@ io.use(function (socket, next) {
|
|||
// bring up socket
|
||||
io.on('connection', socket)
|
||||
|
||||
// safe shutdown
|
||||
var shutdownMode = false
|
||||
var shutdownInterval = 0
|
||||
var connectionCount = 0
|
||||
|
||||
io.on('connection', function (socket) {
|
||||
connectionCount++
|
||||
|
||||
socket.on('disconnect', function () {
|
||||
if ((--connectionCount <= 0) && shutdownMode) {
|
||||
stop('All clients disconnected')
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
process.on('SIGINT', function () {
|
||||
if (shutdownMode) stop('Safe shutdown aborted, force quitting')
|
||||
else if (connectionCount > 0) {
|
||||
var remainingSeconds = 300
|
||||
shutdownMode = true
|
||||
|
||||
var message = (connectionCount === 1) ? ' client is still connected'
|
||||
: ' clients are still connected'
|
||||
console.error(connectionCount + message)
|
||||
console.error('Starting a ' + remainingSeconds + ' seconds countdown')
|
||||
console.error('Press Ctrl+C again to force quit')
|
||||
|
||||
shutdownInterval = setInterval(function () {
|
||||
if ((remainingSeconds--) <= 0) {
|
||||
stop('Countdown is over')
|
||||
} else {
|
||||
io.sockets.emit('shutdownCountdownUpdate', remainingSeconds)
|
||||
}
|
||||
}, 1000)
|
||||
} else stop()
|
||||
})
|
||||
|
||||
// clean stop
|
||||
function stop (reason) {
|
||||
shutdownMode = false
|
||||
if (reason) console.log('Stopping: ' + reason)
|
||||
if (shutdownInterval) clearInterval(shutdownInterval)
|
||||
io.close()
|
||||
server.close()
|
||||
}
|
||||
|
||||
module.exports = { server: server, config: config }
|
||||
|
|
Loading…
Reference in a new issue