Skip to content
This repository has been archived by the owner on May 3, 2019. It is now read-only.

Commit

Permalink
Improve SingleInstance application
Browse files Browse the repository at this point in the history
Watch for lost lock file and lost local server socket file

Fix #161
  • Loading branch information
ColinDuquesnoy committed Dec 9, 2017
1 parent da456fc commit 8787eec
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 3 deletions.
32 changes: 29 additions & 3 deletions lib/MellowPlayer/Infrastructure/Application/SingleInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,16 @@ SingleInstance::SingleInstance(const std::shared_ptr<IApplication>& application,
commandLineArguments_(commandLineArguments),
localServerFactory_(localServerFactory),
localSocketFactory_(localSocketFactory),
lockFile_(QDir::tempPath() + QDir::separator() + qApp->applicationName() + ".lock"),
lockFilePath_(QDir::tempPath() + QDir::separator() + qApp->applicationName() + ".lock"),
lockFile_(lockFilePath_),
isPrimary_(false)
{
lockFile_.setStaleLockTime(0);
}

void SingleInstance::initialize()
{
LOG_DEBUG(logger_, "lock file: " << QDir::tempPath() + QDir::separator() + qApp->applicationName() + ".lock")
LOG_DEBUG(logger_, "lock file: " << lockFilePath_)
if (lockFile_.tryLock(100)) {
LOG_DEBUG(logger_, "Initializing primary application");
isPrimary_ = true;
Expand All @@ -62,10 +63,16 @@ bool SingleInstance::isPrimary() const
int SingleInstance::runPrimaryApplication()
{
LOG_DEBUG(logger_, "Running primary application");



localServer_ = localServerFactory_.create(qApp->applicationName());
connect(localServer_.get(), &ILocalServer::newConnection, this, &SingleInstance::onSecondaryApplicationConnected);
localServer_->listen();

connect(&pollStateTimer_, &QTimer::timeout, this, &SingleInstance::pollState);
pollStateTimer_.setInterval(1000);
pollStateTimer_.start();

auto retCode = ApplicationDecorator::run();
localServer_->close();
lockFile_.unlock();
Expand Down Expand Up @@ -139,3 +146,22 @@ QString SingleInstance::requestedAcion() const
return toggleFavoriteAction_;
return restoreWindowAction_;
}

void SingleInstance::pollState()
{
QFileInfo lockFile(lockFilePath_);
if (!lockFile.exists()) {
LOG_WARN(logger_, "lock file disappeared, trying to restore lock");
if (lockFile_.tryLock(100))
LOG_INFO(logger_, "lock restored");
}

QFileInfo serverFile(localServer_->serverSocketFilePath());
if (!serverFile.exists()) {
LOG_WARN(logger_, "server file diseappeared, trying to restore local server");
localServer_->close();
if (localServer_->listen())
LOG_INFO(logger_, "local server restored");;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "ApplicationDecorator.hpp"
#include <QtCore/QLockFile>
#include <boost-di-extensions/Factory.hpp>
#include <QTimer>

namespace MellowPlayer::Domain
{
Expand All @@ -19,6 +20,7 @@ namespace MellowPlayer::Infrastructure

class SingleInstance: public ApplicationDecorator
{
Q_OBJECT
public:
SingleInstance(const std::shared_ptr<IApplication>& application,
IQtApplication& qtApplication,
Expand All @@ -32,6 +34,9 @@ namespace MellowPlayer::Infrastructure

bool isPrimary() const;

private slots:
void pollState();

private:
int runPrimaryApplication();
void onSecondaryApplicationConnected();
Expand All @@ -50,8 +55,10 @@ namespace MellowPlayer::Infrastructure
IFactory<ILocalSocket>& localSocketFactory_;
std::unique_ptr<ILocalServer> localServer_;
std::unique_ptr<ILocalSocket> localSocket_;
QString lockFilePath_;
QLockFile lockFile_;
bool isPrimary_;
QTimer pollStateTimer_;

static const QString playPauseAction_;
static const QString nextAction_;
Expand Down
5 changes: 5 additions & 0 deletions lib/MellowPlayer/Infrastructure/Network/LocalServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,8 @@ unique_ptr<ILocalSocket> LocalServer::nextPendingConnection()
localSocket->setQLocalSocket(qLocalSocket);
return localSocket;
}

QString LocalServer::serverSocketFilePath() const
{
return qLocalServer_.fullServerName();
}
2 changes: 2 additions & 0 deletions lib/MellowPlayer/Infrastructure/Network/LocalServer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace MellowPlayer::Infrastructure
virtual void close() = 0;
virtual bool listen() = 0;
virtual std::unique_ptr<ILocalSocket> nextPendingConnection() = 0;
virtual QString serverSocketFilePath() const = 0;

signals:
void newConnection();
Expand All @@ -29,6 +30,7 @@ namespace MellowPlayer::Infrastructure
void close() override;
bool listen() override;
std::unique_ptr<ILocalSocket> nextPendingConnection() override;
QString serverSocketFilePath() const;

private:
IFactory<ILocalSocket>& localSocketFactory_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ namespace MellowPlayer::Presentation
public:
ListeningHistoryViewModel(Domain::ListeningHistory& listeningHistory, IContextProperties& contextProperties);

using ContextProperty::initialize;
void initialize();
ListeningHistoryProxyListModel* model();
Q_INVOKABLE void disableService(const QString& serviceName, bool disable);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ namespace MellowPlayer::Presentation
Infrastructure::ICommandLineArguments& commandLineArguments,
Domain::IUserScriptFactory& userScriptFactory,
IContextProperties& contextProperties);

using ContextProperty::initialize;
void initialize();

Q_INVOKABLE void reload();
Expand Down

0 comments on commit 8787eec

Please sign in to comment.