loolwsd: notify clients before recycling wsd

Change-Id: Ib2733a6af1c27fe39c54f5c3bc6f5bd3acb72a2b
Reviewed-on: https://gerrit.libreoffice.org/31298
Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
Tested-by: Ashod Nakashian <ashnakash@gmail.com>
This commit is contained in:
Ashod Nakashian 2016-11-27 19:11:30 -05:00 committed by Ashod Nakashian
parent c0f9ccee42
commit 2b9ea3d4a6
3 changed files with 73 additions and 6 deletions

View file

@ -195,6 +195,36 @@ L.Socket = L.Class.extend({
else if (textMsg === 'shuttingdown') {
msg = _('Server is shutting down for maintenance (auto-saving)');
}
else if (textMsg === 'recycling') {
msg = _('Server is recycling and will be available shortly');
this._map._active = false;
// Prevent reconnecting the world at the same time.
var min = 5000;
var max = 10000;
var timeoutMs = Math.floor(Math.random() * (max - min) + min);
socket = this;
map = this._map;
vex.timer = setInterval(function() {
if (socket.connected()) {
// We're connected: cancel timer and dialog.
clearTimeout(vex.timer);
if (vex.dialogID > 0) {
var id = vex.dialogID;
vex.dialogID = -1;
vex.close(id);
}
return;
}
try {
socket.initialize(map);
} catch (error) {
}
}, timeoutMs);
}
// Close any open dialogs first.
if (vex.dialogID > 0) {

View file

@ -175,6 +175,10 @@ static std::atomic<int> OutstandingForks(1); // Forkit always spawns 1.
static std::map<std::string, std::shared_ptr<DocumentBroker>> DocBrokers;
static std::mutex DocBrokersMutex;
/// Used when shutting down to notify them all that the server is recycling.
static std::vector<std::shared_ptr<LOOLWebSocket>> ClientWebSockets;
static std::mutex ClientWebSocketsMutex;
#if ENABLE_DEBUG
static int careerSpanSeconds = 0;
#endif
@ -983,6 +987,13 @@ private:
}
}
if (SigUtil::isShuttingDown())
{
std::lock_guard<std::mutex> lock(ClientWebSocketsMutex);
LOG_TRC("Capturing Client WS for [" << id << "]");
ClientWebSockets.push_back(ws);
}
LOOLWSD::dumpEventTrace(docBroker->getJailId(), id, "EndSession: " + uri);
LOG_INF("Finishing GET request handler for session [" << id << "].");
}
@ -1011,11 +1022,14 @@ private:
}
else
{
// something wrong, with internal exceptions
LOG_TRC("Abnormal close handshake.");
session->closeFrame();
// FIXME: handle exception thrown from here ? ...
ws->shutdown(WebSocket::WS_ENDPOINT_GOING_AWAY);
if (!SigUtil::isShuttingDown())
{
// something wrong, with internal exceptions
LOG_TRC("Abnormal close handshake.");
session->closeFrame();
// FIXME: handle exception thrown from here ? ...
ws->shutdown(WebSocket::WS_ENDPOINT_GOING_AWAY);
}
}
LOG_INF("Finished GET request handler for session [" << id << "].");
@ -2149,6 +2163,27 @@ int LOOLWSD::main(const std::vector<std::string>& /*args*/)
FileUtil::removeFile(path, true);
}
if (SigUtil::isShuttingDown())
{
// At this point there should be no other thread, but...
std::lock_guard<std::mutex> lock(ClientWebSocketsMutex);
LOG_INF("Notifying clients that we are recycling.");
static const std::string msg("close: recycling");
for (auto& ws : ClientWebSockets)
{
try
{
ws->sendFrame(msg.data(), msg.size());
ws->shutdown(WebSocket::WS_ENDPOINT_GOING_AWAY);
}
catch (const std::exception& ex)
{
LOG_ERR("Error while notifying client of recycle: " << ex.what());
}
}
}
// Finally, we no longer need SSL.
if (LOOLWSD::isSSLEnabled())
{

View file

@ -248,11 +248,13 @@ close: <reason>
ability to kill all other sessions if EnableOwnerTermination flag in WOPI
CheckFileInfo is 'true' (assumed to be 'false' by default).
* shuttingdown - Sent when the server is going down in a graceful fashion.
The server doesn't disconnect from clients yet, but starts
saving document and tearing down internals.
* recycling - The last message sent from the server when it is gracefully
shutting down to let clients know they can try connecting
after a short interval.
getchildid: id=<id>