diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2015-07-20 21:58:14 +0200 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2015-07-23 17:37:53 +0200 |
commit | be5a340912f0a568115aee4ffb41b1a4da805f60 (patch) | |
tree | e45a473267511a9687216928126539041798886b /common/resourceaccess.cpp | |
parent | 166aa563ad41c4566c02cff583df612e328d1520 (diff) | |
download | sink-be5a340912f0a568115aee4ffb41b1a4da805f60.tar.gz sink-be5a340912f0a568115aee4ffb41b1a4da805f60.zip |
Call callbacks for already completed commands before aborting
Diffstat (limited to 'common/resourceaccess.cpp')
-rw-r--r-- | common/resourceaccess.cpp | 49 |
1 files changed, 36 insertions, 13 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 | ||
97 | void 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 | |||
110 | void 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 |
94 | KAsync::Job<QSharedPointer<QLocalSocket> > ResourceAccess::connectToServer(const QByteArray &identifier) | 123 | KAsync::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 | ||
354 | void ResourceAccess::readResourceMessage() | 382 | void 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 | ||
422 | void ResourceAccess::callCallbacks(int id) | 450 | void 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 | ||
432 | void ResourceAccess::log(const QString &message) | 455 | void ResourceAccess::log(const QString &message) |