summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2015-07-20 21:58:14 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2015-07-23 17:37:53 +0200
commitbe5a340912f0a568115aee4ffb41b1a4da805f60 (patch)
treee45a473267511a9687216928126539041798886b
parent166aa563ad41c4566c02cff583df612e328d1520 (diff)
downloadsink-be5a340912f0a568115aee4ffb41b1a4da805f60.tar.gz
sink-be5a340912f0a568115aee4ffb41b1a4da805f60.zip
Call callbacks for already completed commands before aborting
-rw-r--r--common/resourceaccess.cpp49
-rw-r--r--common/resourceaccess.h2
2 files changed, 37 insertions, 14 deletions
diff --git a/common/resourceaccess.cpp b/common/resourceaccess.cpp
index c05d06c..bdebd56 100644
--- a/common/resourceaccess.cpp
+++ b/common/resourceaccess.cpp
@@ -72,6 +72,9 @@ public:
72 Private(const QByteArray &name, const QByteArray &instanceIdentifier, ResourceAccess *ra); 72 Private(const QByteArray &name, const QByteArray &instanceIdentifier, ResourceAccess *ra);
73 KAsync::Job<void> tryToConnect(); 73 KAsync::Job<void> tryToConnect();
74 KAsync::Job<void> initializeSocket(); 74 KAsync::Job<void> initializeSocket();
75 void abortPendingOperations();
76 void callCallbacks();
77
75 QByteArray resourceName; 78 QByteArray resourceName;
76 QByteArray resourceInstanceIdentifier; 79 QByteArray resourceInstanceIdentifier;
77 QSharedPointer<QLocalSocket> socket; 80 QSharedPointer<QLocalSocket> socket;
@@ -80,6 +83,7 @@ public:
80 QVector<QSharedPointer<QueuedCommand>> commandQueue; 83 QVector<QSharedPointer<QueuedCommand>> commandQueue;
81 QMap<uint, QSharedPointer<QueuedCommand>> pendingCommands; 84 QMap<uint, QSharedPointer<QueuedCommand>> pendingCommands;
82 QMultiMap<uint, std::function<void(int error, const QString &errorMessage)> > resultHandler; 85 QMultiMap<uint, std::function<void(int error, const QString &errorMessage)> > resultHandler;
86 QSet<uint> completeCommands;
83 uint messageId; 87 uint messageId;
84}; 88};
85 89
@@ -90,6 +94,31 @@ ResourceAccess::Private::Private(const QByteArray &name, const QByteArray &insta
90{ 94{
91} 95}
92 96
97void ResourceAccess::Private::abortPendingOperations()
98{
99 callCallbacks();
100 if (!resultHandler.isEmpty()) {
101 Warning() << "Aborting pending operations " << resultHandler.keys();
102 }
103 auto handlers = resultHandler.values();
104 resultHandler.clear();
105 for(auto handler : handlers) {
106 handler(1, "The resource closed unexpectedly");
107 }
108}
109
110void ResourceAccess::Private::callCallbacks()
111{
112 for (auto id : completeCommands) {
113 //We remove the callbacks first because the handler can kill resourceaccess directly
114 const auto callbacks = resultHandler.values(id);
115 resultHandler.remove(id);
116 for(auto handler : callbacks) {
117 handler(0, QString());
118 }
119 }
120}
121
93//Connects to server and returns connected socket on success 122//Connects to server and returns connected socket on success
94KAsync::Job<QSharedPointer<QLocalSocket> > ResourceAccess::connectToServer(const QByteArray &identifier) 123KAsync::Job<QSharedPointer<QLocalSocket> > ResourceAccess::connectToServer(const QByteArray &identifier)
95{ 124{
@@ -333,6 +362,8 @@ void ResourceAccess::disconnected()
333{ 362{
334 d->socket->close(); 363 d->socket->close();
335 log(QString("Disconnected from %1").arg(d->socket->fullServerName())); 364 log(QString("Disconnected from %1").arg(d->socket->fullServerName()));
365 //TODO fail all existing jobs? or retry
366 d->abortPendingOperations();
336 emit ready(false); 367 emit ready(false);
337} 368}
338 369
@@ -345,10 +376,7 @@ void ResourceAccess::connectionError(QLocalSocket::LocalSocketError error)
345 } 376 }
346 377
347 //TODO We could first try to reconnect and resend the message if necessary. 378 //TODO We could first try to reconnect and resend the message if necessary.
348 for(auto handler : d->resultHandler.values()) { 379 d->abortPendingOperations();
349 handler(1, "The resource closed unexpectedly");
350 }
351 d->resultHandler.clear();
352} 380}
353 381
354void ResourceAccess::readResourceMessage() 382void ResourceAccess::readResourceMessage()
@@ -392,10 +420,10 @@ bool ResourceAccess::processMessageBuffer()
392 case Commands::CommandCompletion: { 420 case Commands::CommandCompletion: {
393 auto buffer = GetCommandCompletion(d->partialMessageBuffer.constData() + headerSize); 421 auto buffer = GetCommandCompletion(d->partialMessageBuffer.constData() + headerSize);
394 log(QString("Command with messageId %1 completed %2").arg(buffer->id()).arg(buffer->success() ? "sucessfully" : "unsuccessfully")); 422 log(QString("Command with messageId %1 completed %2").arg(buffer->id()).arg(buffer->success() ? "sucessfully" : "unsuccessfully"));
395 //TODO: if a queued command, get it out of the queue ... pass on completion ot the relevant objects .. etc
396 423
424 d->completeCommands << buffer->id();
397 //The callbacks can result in this object getting destroyed directly, so we need to ensure we finish our work first 425 //The callbacks can result in this object getting destroyed directly, so we need to ensure we finish our work first
398 QMetaObject::invokeMethod(this, "callCallbacks", Qt::QueuedConnection, QGenericReturnArgument(), Q_ARG(int, buffer->id())); 426 QMetaObject::invokeMethod(this, "callCallbacks", Qt::QueuedConnection);
399 break; 427 break;
400 } 428 }
401 case Commands::NotificationCommand: { 429 case Commands::NotificationCommand: {
@@ -419,14 +447,9 @@ bool ResourceAccess::processMessageBuffer()
419 return d->partialMessageBuffer.size() >= headerSize; 447 return d->partialMessageBuffer.size() >= headerSize;
420} 448}
421 449
422void ResourceAccess::callCallbacks(int id) 450void ResourceAccess::callCallbacks()
423{ 451{
424 //We remove the callbacks first because the handler can kill resourceaccess directly 452 d->callCallbacks();
425 const auto callbacks = d->resultHandler.values(id);
426 d->resultHandler.remove(id);
427 for(auto handler : callbacks) {
428 handler(0, QString());
429 }
430} 453}
431 454
432void ResourceAccess::log(const QString &message) 455void ResourceAccess::log(const QString &message)
diff --git a/common/resourceaccess.h b/common/resourceaccess.h
index de58525..e873d8e 100644
--- a/common/resourceaccess.h
+++ b/common/resourceaccess.h
@@ -67,7 +67,7 @@ private Q_SLOTS:
67 void connectionError(QLocalSocket::LocalSocketError error); 67 void connectionError(QLocalSocket::LocalSocketError error);
68 void readResourceMessage(); 68 void readResourceMessage();
69 bool processMessageBuffer(); 69 bool processMessageBuffer();
70 void callCallbacks(int id); 70 void callCallbacks();
71 71
72private: 72private:
73 void connected(); 73 void connected();