From 1d9d83b15758ddba6e2c0a669ea3b2ad466692d4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 31 May 2017 19:00:41 -0700 Subject: [PATCH] initial version of the ClosureEventSender using std::thread --- interface/src/Application.cpp | 6 ++ interface/src/Application.h | 3 + interface/src/main.cpp | 7 ++ .../src/networking/ClosureEventSender.cpp | 71 +++++++++++++++++++ interface/src/networking/ClosureEventSender.h | 35 +++++++++ libraries/networking/src/AccountManager.cpp | 1 - libraries/networking/src/AccountManager.h | 1 + .../networking/src/UserActivityLogger.cpp | 2 - libraries/networking/src/UserActivityLogger.h | 2 + 9 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 interface/src/networking/ClosureEventSender.cpp create mode 100644 interface/src/networking/ClosureEventSender.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 46c4c0bd4e..297ee943fa 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -144,6 +144,7 @@ #include "InterfaceLogging.h" #include "LODManager.h" #include "ModelPackager.h" +#include "networking/ClosureEventSender.h" #include "networking/HFWebEngineProfile.h" #include "networking/HFTabletWebEngineProfile.h" #include "networking/FileTypeProfile.h" @@ -534,6 +535,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); + DependencyManager::set(); return previousSessionCrashed; } @@ -1568,6 +1570,10 @@ void Application::aboutToQuit() { getActiveDisplayPlugin()->deactivate(); + // use the ClosureEventSender via an std::thread (to not use QThread while the application is going down) + // to send an event that says the user asked for the app to close + _userQuitThread = std::thread { &ClosureEventSender::sendQuitStart, DependencyManager::get() }; + // Hide Running Scripts dialog so that it gets destroyed in an orderly manner; prevents warnings at shutdown. DependencyManager::get()->hide("RunningScripts"); diff --git a/interface/src/Application.h b/interface/src/Application.h index 9cf03f1cef..23673399f6 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -13,6 +13,7 @@ #define hifi_Application_h #include +#include #include #include @@ -680,6 +681,8 @@ private: FileScriptingInterface* _fileDownload; AudioInjector* _snapshotSoundInjector { nullptr }; SharedSoundPointer _snapshotSound; + + std::thread _userQuitThread; }; diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 49517eb38e..68525dfd1e 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -30,6 +30,7 @@ #include "InterfaceLogging.h" #include "UserActivityLogger.h" #include "MainWindow.h" +#include "networking/ClosureEventSender.h" #ifdef HAS_BUGSPLAT #include @@ -267,6 +268,12 @@ int main(int argc, const char* argv[]) { Application::shutdownPlugins(); + if (UserActivityLogger::getInstance().isEnabled()) { + // send a quit finished event here to indicate that this session closed cleanly + std::thread quitCompleteThread { &::ClosureEventSender::sendQuitFinish, DependencyManager::get() }; + quitCompleteThread.join(); + } + qCDebug(interfaceapp, "Normal exit."); #if !defined(DEBUG) && !defined(Q_OS_LINUX) // HACK: exit immediately (don't handle shutdown callbacks) for Release build diff --git a/interface/src/networking/ClosureEventSender.cpp b/interface/src/networking/ClosureEventSender.cpp new file mode 100644 index 0000000000..f514fa17b6 --- /dev/null +++ b/interface/src/networking/ClosureEventSender.cpp @@ -0,0 +1,71 @@ +// +// ClosureEventSender.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 +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ClosureEventSender.h" + +QNetworkRequest createNetworkRequest() { + + QNetworkRequest request; + + QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL; + requestURL.setPath(USER_ACTIVITY_URL); + + request.setUrl(requestURL); + + auto accountManager = DependencyManager::get(); + + 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"); + + return request; +} + +QByteArray postDataForAction(QString action) { + return QString("{\"action\": \"" + action + "\"}").toUtf8(); +} + +QNetworkReply* replyForAction(QString action) { + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + return networkAccessManager.post(createNetworkRequest(), postDataForAction(action)); +} + +void ClosureEventSender::sendQuitStart() { + + QNetworkReply* reply = replyForAction("quit_start"); + + QEventLoop loop; + QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); +} + +void ClosureEventSender::sendQuitFinish() { + QNetworkReply* reply = replyForAction("quit_finish"); + + QEventLoop loop; + QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); +} diff --git a/interface/src/networking/ClosureEventSender.h b/interface/src/networking/ClosureEventSender.h new file mode 100644 index 0000000000..dc726fc386 --- /dev/null +++ b/interface/src/networking/ClosureEventSender.h @@ -0,0 +1,35 @@ +// +// ClosureEventSender.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_ClosureEventSender_h +#define hifi_ClosureEventSender_h + +#include +#include + +#include + +class ClosureEventSender : public Dependency { + SINGLETON_DEPENDENCY + +public: + void setSessionID(QUuid sessionID) { _sessionID = sessionID; } + + void sendQuitStart(); + void sendQuitFinish(); + void sendCrashEvent(); + +private: + QUuid _sessionID; + QString _accessToken; +}; + +#endif // hifi_ClosureEventSender_h diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp index 6266ad0f89..2457d0ac42 100644 --- a/libraries/networking/src/AccountManager.cpp +++ b/libraries/networking/src/AccountManager.cpp @@ -45,7 +45,6 @@ Q_DECLARE_METATYPE(QNetworkAccessManager::Operation) Q_DECLARE_METATYPE(JSONCallbackParameters) const QString ACCOUNTS_GROUP = "accounts"; -static const auto METAVERSE_SESSION_ID_HEADER = QString("HFM-SessionID").toLocal8Bit(); JSONCallbackParameters::JSONCallbackParameters(QObject* jsonCallbackReceiver, const QString& jsonCallbackMethod, QObject* errorCallbackReceiver, const QString& errorCallbackMethod, diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h index dd2216957f..bd452646f6 100644 --- a/libraries/networking/src/AccountManager.h +++ b/libraries/networking/src/AccountManager.h @@ -52,6 +52,7 @@ namespace AccountManagerAuth { Q_DECLARE_METATYPE(AccountManagerAuth::Type); const QByteArray ACCESS_TOKEN_AUTHORIZATION_HEADER = "Authorization"; +const auto METAVERSE_SESSION_ID_HEADER = QString("HFM-SessionID").toLocal8Bit(); using UserAgentGetter = std::function; diff --git a/libraries/networking/src/UserActivityLogger.cpp b/libraries/networking/src/UserActivityLogger.cpp index e2dd110cfd..28117c0933 100644 --- a/libraries/networking/src/UserActivityLogger.cpp +++ b/libraries/networking/src/UserActivityLogger.cpp @@ -20,8 +20,6 @@ #include #include "AddressManager.h" -static const QString USER_ACTIVITY_URL = "/api/v1/user_activities"; - UserActivityLogger& UserActivityLogger::getInstance() { static UserActivityLogger sharedInstance; return sharedInstance; diff --git a/libraries/networking/src/UserActivityLogger.h b/libraries/networking/src/UserActivityLogger.h index b41960a8ad..9fad498b86 100644 --- a/libraries/networking/src/UserActivityLogger.h +++ b/libraries/networking/src/UserActivityLogger.h @@ -22,6 +22,8 @@ #include #include "AddressManager.h" +const QString USER_ACTIVITY_URL = "/api/v1/user_activities"; + class UserActivityLogger : public QObject { Q_OBJECT