mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 19:59:28 +02:00
Merge pull request #10592 from birarda/close-report
Send a close event to API on shutdown
This commit is contained in:
commit
0d96f82888
8 changed files with 156 additions and 4 deletions
|
@ -11,6 +11,9 @@
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#include <gl/Config.h>
|
#include <gl/Config.h>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtx/component_wise.hpp>
|
#include <glm/gtx/component_wise.hpp>
|
||||||
|
@ -144,6 +147,7 @@
|
||||||
#include "InterfaceLogging.h"
|
#include "InterfaceLogging.h"
|
||||||
#include "LODManager.h"
|
#include "LODManager.h"
|
||||||
#include "ModelPackager.h"
|
#include "ModelPackager.h"
|
||||||
|
#include "networking/CloseEventSender.h"
|
||||||
#include "networking/HFWebEngineProfile.h"
|
#include "networking/HFWebEngineProfile.h"
|
||||||
#include "networking/HFTabletWebEngineProfile.h"
|
#include "networking/HFTabletWebEngineProfile.h"
|
||||||
#include "networking/FileTypeProfile.h"
|
#include "networking/FileTypeProfile.h"
|
||||||
|
@ -534,6 +538,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
|
||||||
DependencyManager::set<AvatarBookmarks>();
|
DependencyManager::set<AvatarBookmarks>();
|
||||||
DependencyManager::set<LocationBookmarks>();
|
DependencyManager::set<LocationBookmarks>();
|
||||||
DependencyManager::set<Snapshot>();
|
DependencyManager::set<Snapshot>();
|
||||||
|
DependencyManager::set<CloseEventSender>();
|
||||||
|
|
||||||
return previousSessionCrashed;
|
return previousSessionCrashed;
|
||||||
}
|
}
|
||||||
|
@ -1570,6 +1575,14 @@ void Application::aboutToQuit() {
|
||||||
|
|
||||||
getActiveDisplayPlugin()->deactivate();
|
getActiveDisplayPlugin()->deactivate();
|
||||||
|
|
||||||
|
// use the CloseEventSender via a QThread to send an event that says the user asked for the app to close
|
||||||
|
auto closeEventSender = DependencyManager::get<CloseEventSender>();
|
||||||
|
QThread* closureEventThread = new QThread(this);
|
||||||
|
closeEventSender->moveToThread(closureEventThread);
|
||||||
|
// sendQuitEventAsync will bail immediately if the UserActivityLogger is not enabled
|
||||||
|
connect(closureEventThread, &QThread::started, closeEventSender.data(), &CloseEventSender::sendQuitEventAsync);
|
||||||
|
closureEventThread->start();
|
||||||
|
|
||||||
// Hide Running Scripts dialog so that it gets destroyed in an orderly manner; prevents warnings at shutdown.
|
// Hide Running Scripts dialog so that it gets destroyed in an orderly manner; prevents warnings at shutdown.
|
||||||
DependencyManager::get<OffscreenUi>()->hide("RunningScripts");
|
DependencyManager::get<OffscreenUi>()->hide("RunningScripts");
|
||||||
|
|
||||||
|
@ -1738,6 +1751,15 @@ Application::~Application() {
|
||||||
|
|
||||||
_window->deleteLater();
|
_window->deleteLater();
|
||||||
|
|
||||||
|
// make sure that the quit event has finished sending before we take the application down
|
||||||
|
auto closeEventSender = DependencyManager::get<CloseEventSender>();
|
||||||
|
while (!closeEventSender->hasFinishedQuitEvent() && !closeEventSender->hasTimedOutQuitEvent()) {
|
||||||
|
// sleep a little so we're not spinning at 100%
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||||
|
}
|
||||||
|
// quit the thread used by the closure event sender
|
||||||
|
closeEventSender->thread()->quit();
|
||||||
|
|
||||||
// Can't log to file passed this point, FileLogger about to be deleted
|
// Can't log to file passed this point, FileLogger about to be deleted
|
||||||
qInstallMessageHandler(LogHandler::verboseMessageHandler);
|
qInstallMessageHandler(LogHandler::verboseMessageHandler);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include <SandboxUtils.h>
|
#include <SandboxUtils.h>
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
|
|
||||||
|
|
||||||
#include "AddressManager.h"
|
#include "AddressManager.h"
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "InterfaceLogging.h"
|
#include "InterfaceLogging.h"
|
||||||
|
|
90
interface/src/networking/CloseEventSender.cpp
Normal file
90
interface/src/networking/CloseEventSender.cpp
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
//
|
||||||
|
// CloseEventSender.cpp
|
||||||
|
// interface/src/networking
|
||||||
|
//
|
||||||
|
// Created by Stephen Birarda on 5/31/17.
|
||||||
|
// Copyright 2017 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <QtCore/QDateTime>
|
||||||
|
#include <QtCore/QEventLoop>
|
||||||
|
#include <QtCore/QJsonDocument>
|
||||||
|
#include <QtNetwork/QNetworkReply>
|
||||||
|
|
||||||
|
#include <AccountManager.h>
|
||||||
|
#include <NetworkAccessManager.h>
|
||||||
|
#include <NetworkingConstants.h>
|
||||||
|
#include <NetworkLogging.h>
|
||||||
|
#include <UserActivityLogger.h>
|
||||||
|
#include <UUID.h>
|
||||||
|
|
||||||
|
#include "CloseEventSender.h"
|
||||||
|
|
||||||
|
QNetworkRequest createNetworkRequest() {
|
||||||
|
|
||||||
|
QNetworkRequest request;
|
||||||
|
|
||||||
|
QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL;
|
||||||
|
requestURL.setPath(USER_ACTIVITY_URL);
|
||||||
|
|
||||||
|
request.setUrl(requestURL);
|
||||||
|
|
||||||
|
auto accountManager = DependencyManager::get<AccountManager>();
|
||||||
|
|
||||||
|
if (accountManager->hasValidAccessToken()) {
|
||||||
|
request.setRawHeader(ACCESS_TOKEN_AUTHORIZATION_HEADER,
|
||||||
|
accountManager->getAccountInfo().getAccessToken().authorizationHeaderValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
request.setRawHeader(METAVERSE_SESSION_ID_HEADER,
|
||||||
|
uuidStringWithoutCurlyBraces(accountManager->getSessionID()).toLocal8Bit());
|
||||||
|
|
||||||
|
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||||
|
|
||||||
|
request.setPriority(QNetworkRequest::HighPriority);
|
||||||
|
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray postDataForAction(QString action) {
|
||||||
|
return QString("{\"action_name\": \"" + action + "\"}").toUtf8();
|
||||||
|
}
|
||||||
|
|
||||||
|
QNetworkReply* replyForAction(QString action) {
|
||||||
|
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||||
|
return networkAccessManager.post(createNetworkRequest(), postDataForAction(action));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CloseEventSender::sendQuitEventAsync() {
|
||||||
|
if (UserActivityLogger::getInstance().isEnabled()) {
|
||||||
|
QNetworkReply* reply = replyForAction("quit");
|
||||||
|
connect(reply, &QNetworkReply::finished, this, &CloseEventSender::handleQuitEventFinished);
|
||||||
|
_quitEventStartTimestamp = QDateTime::currentMSecsSinceEpoch();
|
||||||
|
} else {
|
||||||
|
_hasFinishedQuitEvent = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CloseEventSender::handleQuitEventFinished() {
|
||||||
|
_hasFinishedQuitEvent = true;
|
||||||
|
|
||||||
|
auto reply = qobject_cast<QNetworkReply*>(sender());
|
||||||
|
if (reply->error() == QNetworkReply::NoError) {
|
||||||
|
qCDebug(networking) << "Quit event sent successfully";
|
||||||
|
} else {
|
||||||
|
qCDebug(networking) << "Failed to send quit event -" << reply->errorString();
|
||||||
|
}
|
||||||
|
|
||||||
|
reply->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CloseEventSender::hasTimedOutQuitEvent() {
|
||||||
|
const int CLOSURE_EVENT_TIMEOUT_MS = 5000;
|
||||||
|
return _quitEventStartTimestamp != 0
|
||||||
|
&& QDateTime::currentMSecsSinceEpoch() - _quitEventStartTimestamp > CLOSURE_EVENT_TIMEOUT_MS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
41
interface/src/networking/CloseEventSender.h
Normal file
41
interface/src/networking/CloseEventSender.h
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
//
|
||||||
|
// CloseEventSender.h
|
||||||
|
// interface/src/networking
|
||||||
|
//
|
||||||
|
// Created by Stephen Birarda on 5/31/17.
|
||||||
|
// Copyright 2017 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_CloseEventSender_h
|
||||||
|
#define hifi_CloseEventSender_h
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <QtCore/QUuid>
|
||||||
|
|
||||||
|
#include <DependencyManager.h>
|
||||||
|
|
||||||
|
class CloseEventSender : public QObject, public Dependency {
|
||||||
|
Q_OBJECT
|
||||||
|
SINGLETON_DEPENDENCY
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool hasTimedOutQuitEvent();
|
||||||
|
bool hasFinishedQuitEvent() { return _hasFinishedQuitEvent; }
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void sendQuitEventAsync();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void handleQuitEventFinished();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::atomic<bool> _hasFinishedQuitEvent { false };
|
||||||
|
std::atomic<int64_t> _quitEventStartTimestamp;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_CloseEventSender_h
|
|
@ -45,7 +45,6 @@ Q_DECLARE_METATYPE(QNetworkAccessManager::Operation)
|
||||||
Q_DECLARE_METATYPE(JSONCallbackParameters)
|
Q_DECLARE_METATYPE(JSONCallbackParameters)
|
||||||
|
|
||||||
const QString ACCOUNTS_GROUP = "accounts";
|
const QString ACCOUNTS_GROUP = "accounts";
|
||||||
static const auto METAVERSE_SESSION_ID_HEADER = QString("HFM-SessionID").toLocal8Bit();
|
|
||||||
|
|
||||||
JSONCallbackParameters::JSONCallbackParameters(QObject* jsonCallbackReceiver, const QString& jsonCallbackMethod,
|
JSONCallbackParameters::JSONCallbackParameters(QObject* jsonCallbackReceiver, const QString& jsonCallbackMethod,
|
||||||
QObject* errorCallbackReceiver, const QString& errorCallbackMethod,
|
QObject* errorCallbackReceiver, const QString& errorCallbackMethod,
|
||||||
|
|
|
@ -52,6 +52,7 @@ namespace AccountManagerAuth {
|
||||||
Q_DECLARE_METATYPE(AccountManagerAuth::Type);
|
Q_DECLARE_METATYPE(AccountManagerAuth::Type);
|
||||||
|
|
||||||
const QByteArray ACCESS_TOKEN_AUTHORIZATION_HEADER = "Authorization";
|
const QByteArray ACCESS_TOKEN_AUTHORIZATION_HEADER = "Authorization";
|
||||||
|
const auto METAVERSE_SESSION_ID_HEADER = QString("HFM-SessionID").toLocal8Bit();
|
||||||
|
|
||||||
using UserAgentGetter = std::function<QString()>;
|
using UserAgentGetter = std::function<QString()>;
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
#include <DependencyManager.h>
|
#include <DependencyManager.h>
|
||||||
#include "AddressManager.h"
|
#include "AddressManager.h"
|
||||||
|
|
||||||
static const QString USER_ACTIVITY_URL = "/api/v1/user_activities";
|
|
||||||
|
|
||||||
UserActivityLogger& UserActivityLogger::getInstance() {
|
UserActivityLogger& UserActivityLogger::getInstance() {
|
||||||
static UserActivityLogger sharedInstance;
|
static UserActivityLogger sharedInstance;
|
||||||
return sharedInstance;
|
return sharedInstance;
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
#include <SettingHandle.h>
|
#include <SettingHandle.h>
|
||||||
#include "AddressManager.h"
|
#include "AddressManager.h"
|
||||||
|
|
||||||
|
const QString USER_ACTIVITY_URL = "/api/v1/user_activities";
|
||||||
|
|
||||||
class UserActivityLogger : public QObject {
|
class UserActivityLogger : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue