[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [sink/develop] /: Prepare for making the resource status available
From: Christian Mollekopf <chrigi_1 () fastmail ! fm>
Date: 2016-07-11 9:55:51
Message-ID: E1bMXwN-00021f-N8 () code ! kde ! org
[Download RAW message or body]
Git commit b4df9eb5f1f4a0ac2b1272fc34d4b8aad473008b by Christian Mollekopf.
Committed on 05/07/2016 at 13:22.
Pushed by cmollekopf into branch 'develop'.
Prepare for making the resource status available
M +1 -0 common/changereplay.cpp
M +1 -0 common/changereplay.h
M +2 -5 common/commands/notification.fbs
M +55 -7 common/domain/applicationdomaintype.h
M +36 -4 common/genericresource.cpp
M +2 -2 common/listener.cpp
M +13 -0 common/notification.h
M +31 -18 common/resourceaccess.cpp
M +9 -1 common/resourceaccess.h
M +1 -1 tests/dummyresourcebenchmark.cpp
http://commits.kde.org/akonadi-next/b4df9eb5f1f4a0ac2b1272fc34d4b8aad473008b
diff --git a/common/changereplay.cpp b/common/changereplay.cpp
index 0096bd0..78c0ff5 100644
--- a/common/changereplay.cpp
+++ b/common/changereplay.cpp
@@ -86,6 +86,7 @@ KAsync::Job<void> ChangeReplay::replayNextRevision()
if (lastReplayedRevision < topRevision) {
Trace() << "Changereplay from " << lastReplayedRevision << " to " << \
topRevision; + emit replayingChanges();
qint64 revision = lastReplayedRevision + 1;
const auto uid = Storage::getUidFromRevision(mainStoreTransaction, \
revision);
const auto type = Storage::getTypeFromRevision(mainStoreTransaction, \
revision);
diff --git a/common/changereplay.h b/common/changereplay.h
index aba3dd0..6c1c1db 100644
--- a/common/changereplay.h
+++ b/common/changereplay.h
@@ -45,6 +45,7 @@ public:
signals:
void changesReplayed();
+ void replayingChanges();
public slots:
void revisionChanged();
diff --git a/common/commands/notification.fbs b/common/commands/notification.fbs
index 8750ff5..c82fad3 100644
--- a/common/commands/notification.fbs
+++ b/common/commands/notification.fbs
@@ -1,13 +1,10 @@
namespace Sink.Commands;
-enum NotificationType : byte { Shutdown = 1, Status, Warning, Progress, Inspection, \
RevisionUpdate }
-enum NotificationCode : byte { Success = 0, Failure = 1, UserCode }
-
table Notification {
- type: NotificationType = Status;
+ type: int = 0; //See notification.h
identifier: string; //An identifier that links back to the something related to \
the notification (e.g. an entity id or a command id) message: string;
- code: int = 0; //Of type NotificationCode
+ code: int = 0; //See notification.h
}
root_type Notification;
diff --git a/common/domain/applicationdomaintype.h \
b/common/domain/applicationdomaintype.h index 849c3e2..5efb936 100644
--- a/common/domain/applicationdomaintype.h
+++ b/common/domain/applicationdomaintype.h
@@ -52,6 +52,13 @@
void setExtracted##NAME(const TYPE &value) { setProperty(NAME::name, \
QVariant::fromValue(value)); } \
TYPE get##NAME() const { return getProperty(NAME::name).value<TYPE>(); } \
+#define SINK_STATUS_PROPERTY(TYPE, NAME, LOWERCASENAME) \
+ struct NAME { \
+ static constexpr const char *name = #LOWERCASENAME; \
+ typedef TYPE Type; \
+ }; \
+ void setStatus##NAME(const TYPE &value) { setProperty(NAME::name, \
QVariant::fromValue(value)); } \ + TYPE get##NAME() const { return \
getProperty(NAME::name).value<TYPE>(); } \
#define SINK_BLOB_PROPERTY(NAME, LOWERCASENAME) \
struct NAME { \
@@ -76,6 +83,14 @@
namespace Sink {
namespace ApplicationDomain {
+struct SINK_EXPORT Error {
+
+};
+
+struct SINK_EXPORT Progress {
+
+};
+
/**
* The domain type interface has two purposes:
* * provide a unified interface to read buffers (for zero-copy reading)
@@ -215,6 +230,38 @@ struct SINK_EXPORT Mail : public Entity {
};
/**
+ * The status of an account or resource.
+ *
+ * It is set as follows:
+ * * By default the status is offline.
+ * * If a connection to the server could be established the status is Connected.
+ * * If an error occurred that keeps the resource from operating (so non transient), \
the resource enters the error state. + * * If a long running operation is started the \
resource goes to the busy state (and return to the previous state after that). + */
+enum SINK_EXPORT Status {
+ OfflineStatus,
+ ConnectedStatus,
+ BusyStatus,
+ ErrorStatus
+};
+
+struct SINK_EXPORT SinkAccount : public ApplicationDomainType {
+ typedef QSharedPointer<SinkAccount> Ptr;
+ explicit SinkAccount(const QByteArray &resourceInstanceIdentifier, const \
QByteArray &identifier, qint64 revision, const QSharedPointer<BufferAdaptor> \
&adaptor); + explicit SinkAccount(const QByteArray &identifier);
+ SinkAccount();
+ virtual ~SinkAccount();
+
+ SINK_PROPERTY(QString, Name, name);
+ SINK_PROPERTY(QString, Icon, icon);
+ SINK_PROPERTY(QString, AccountType, accountType);
+ SINK_STATUS_PROPERTY(int, Status, status);
+ SINK_STATUS_PROPERTY(ApplicationDomain::Error, Error, error);
+ SINK_STATUS_PROPERTY(ApplicationDomain::Progress, Progress, progress);
+};
+
+
+/**
* Represents an sink resource.
*
* This type is used for configuration of resources,
@@ -226,14 +273,13 @@ struct SINK_EXPORT SinkResource : public ApplicationDomainType \
{ explicit SinkResource(const QByteArray &identifier);
SinkResource();
virtual ~SinkResource();
-};
-struct SINK_EXPORT SinkAccount : public ApplicationDomainType {
- typedef QSharedPointer<SinkAccount> Ptr;
- explicit SinkAccount(const QByteArray &resourceInstanceIdentifier, const \
QByteArray &identifier, qint64 revision, const QSharedPointer<BufferAdaptor> \
&adaptor);
- explicit SinkAccount(const QByteArray &identifier);
- SinkAccount();
- virtual ~SinkAccount();
+ SINK_REFERENCE_PROPERTY(SinkAccount, Account, account);
+ SINK_PROPERTY(QString, ResourceType, resourceType);
+ SINK_PROPERTY(QByteArrayList, Capabilities, capabilities);
+ SINK_STATUS_PROPERTY(int, Status, status);
+ SINK_STATUS_PROPERTY(ApplicationDomain::Error, Error, error);
+ SINK_STATUS_PROPERTY(ApplicationDomain::Progress, Progress, progress);
};
struct SINK_EXPORT Identity : public ApplicationDomainType {
@@ -330,3 +376,5 @@ Q_DECLARE_METATYPE(Sink::ApplicationDomain::SinkAccount)
Q_DECLARE_METATYPE(Sink::ApplicationDomain::SinkAccount::Ptr)
Q_DECLARE_METATYPE(Sink::ApplicationDomain::Identity)
Q_DECLARE_METATYPE(Sink::ApplicationDomain::Identity::Ptr)
+Q_DECLARE_METATYPE(Sink::ApplicationDomain::Error)
+Q_DECLARE_METATYPE(Sink::ApplicationDomain::Progress)
diff --git a/common/genericresource.cpp b/common/genericresource.cpp
index c06c22a..5522174 100644
--- a/common/genericresource.cpp
+++ b/common/genericresource.cpp
@@ -260,18 +260,18 @@ GenericResource::GenericResource(const QByteArray \
&resourceType, const QByteArra [=]() {
Log_area("resource.inspection") << "Inspection was \
successful: " << inspectionType << inspectionId << entityId; Sink::Notification n;
- n.type = Sink::Commands::NotificationType_Inspection;
+ n.type = Sink::Notification::Inspection;
n.id = inspectionId;
- n.code = Sink::Commands::NotificationCode_Success;
+ n.code = Sink::Notification::Success;
emit notify(n);
},
[=](int code, const QString &message) {
Warning_area("resource.inspection") << "Inspection failed: " \
<< inspectionType << inspectionId << entityId << message; Sink::Notification n;
- n.type = Sink::Commands::NotificationType_Inspection;
+ n.type = Sink::Notification::Inspection;
n.message = message;
n.id = inspectionId;
- n.code = Sink::Commands::NotificationCode_Failure;
+ n.code = Sink::Notification::Failure;
emit notify(n);
})
.exec();
@@ -283,6 +283,23 @@ GenericResource::GenericResource(const QByteArray &resourceType, \
const QByteArra
QObject::connect(mPipeline.data(), &Pipeline::revisionUpdated, this, \
&Resource::revisionUpdated); mClientLowerBoundRevision = \
mPipeline->cleanedUpRevision();
+ QObject::connect(mChangeReplay.data(), &ChangeReplay::replayingChanges, [this]() \
{ + Sink::Notification n;
+ n.id = "changereplay";
+ n.type = Sink::Notification::Status;
+ n.message = "Replaying changes.";
+ n.code = Sink::ApplicationDomain::BusyStatus;
+ emit notify(n);
+ });
+ QObject::connect(mChangeReplay.data(), &ChangeReplay::changesReplayed, [this]() \
{ + Sink::Notification n;
+ n.id = "changereplay";
+ n.type = Sink::Notification::Status;
+ n.message = "All changes have been replayed.";
+ n.code = Sink::ApplicationDomain::ConnectedStatus;
+ emit notify(n);
+ });
+
mCommitQueueTimer.setInterval(sCommitInterval);
mCommitQueueTimer.setSingleShot(true);
QObject::connect(&mCommitQueueTimer, &QTimer::timeout, &mUserQueue, \
&MessageQueue::commit); @@ -399,12 +416,27 @@ void \
GenericResource::processCommand(int commandId, const QByteArray &data) \
KAsync::Job<void> GenericResource::synchronizeWithSource() {
return KAsync::start<void>([this](KAsync::Future<void> &future) {
+
+ Sink::Notification n;
+ n.id = "sync";
+ n.type = Sink::Notification::Status;
+ n.message = "Synchronization has started.";
+ n.code = Sink::ApplicationDomain::BusyStatus;
+ emit notify(n);
+
Log() << " Synchronizing";
// Changereplay would deadlock otherwise when trying to open the \
synchronization store enableChangeReplay(false);
mSynchronizer->synchronize()
.then<void>([this, &future]() {
Log() << "Done Synchronizing";
+ Sink::Notification n;
+ n.id = "sync";
+ n.type = Sink::Notification::Status;
+ n.message = "Synchronization has ended.";
+ n.code = Sink::ApplicationDomain::ConnectedStatus;
+ emit notify(n);
+
enableChangeReplay(true);
future.setFinished();
}, [this, &future](int errorCode, const QString &error) {
diff --git a/common/listener.cpp b/common/listener.cpp
index 84afe16..d2fc510 100644
--- a/common/listener.cpp
+++ b/common/listener.cpp
@@ -330,7 +330,7 @@ qint64 Listener::lowerBoundRevision()
void Listener::quit()
{
// Broadcast shutdown notifications to open clients, so they don't try to \
restart the resource
- auto command = Sink::Commands::CreateNotification(m_fbb, \
Sink::Commands::NotificationType::NotificationType_Shutdown); + auto command = \
Sink::Commands::CreateNotification(m_fbb, Sink::Notification::Shutdown); \
Sink::Commands::FinishNotificationBuffer(m_fbb, command); for (Client &client : \
m_connections) { if (client.socket && client.socket->isOpen()) {
@@ -418,7 +418,7 @@ void Listener::notify(const Sink::Notification ¬ification)
auto messageString = \
m_fbb.CreateString(notification.message.toUtf8().constData(), \
notification.message.toUtf8().size());
auto idString = m_fbb.CreateString(notification.id.constData(), \
notification.id.size()); Sink::Commands::NotificationBuilder builder(m_fbb);
- builder.add_type(static_cast<Sink::Commands::NotificationType>(notification.type));
+ builder.add_type(notification.type);
builder.add_code(notification.code);
builder.add_identifier(idString);
builder.add_message(messageString);
diff --git a/common/notification.h b/common/notification.h
index 0eb796d..0a267e6 100644
--- a/common/notification.h
+++ b/common/notification.h
@@ -30,6 +30,19 @@ namespace Sink {
class SINK_EXPORT Notification
{
public:
+ enum NoticationType {
+ Shutdown,
+ Status,
+ Warning,
+ Progress,
+ Inspection,
+ RevisionUpdate
+ };
+ enum InspectionCode {
+ Success,
+ Failure
+ };
+
QByteArray id;
int type;
QString message;
diff --git a/common/resourceaccess.cpp b/common/resourceaccess.cpp
index d3bd85f..95b4a7e 100644
--- a/common/resourceaccess.cpp
+++ b/common/resourceaccess.cpp
@@ -230,6 +230,7 @@ KAsync::Job<void> ResourceAccess::Private::initializeSocket()
ResourceAccess::ResourceAccess(const QByteArray &resourceInstanceIdentifier, const \
QByteArray &resourceType)
: ResourceAccessInterface(), d(new Private(resourceType, \
resourceInstanceIdentifier, this)) {
+ mResourceStatus = Sink::ApplicationDomain::OfflineStatus;
Trace() << "Starting access";
}
@@ -513,6 +514,22 @@ void ResourceAccess::readResourceMessage()
}
}
+static Sink::Notification getNotification(const Sink::Commands::Notification \
*buffer) +{
+ Sink::Notification n;
+ if (buffer->identifier()) {
+ // Don't use fromRawData, the buffer is gone once we invoke emit \
notification + n.id = BufferUtils::extractBufferCopy(buffer->identifier());
+ }
+ if (buffer->message()) {
+ // Don't use fromRawData, the buffer is gone once we invoke emit \
notification + n.message = BufferUtils::extractBufferCopy(buffer->message());
+ }
+ n.type = buffer->type();
+ n.code = buffer->code();
+ return n;
+}
+
bool ResourceAccess::processMessageBuffer()
{
static const int headerSize = Commands::headerSize();
@@ -535,7 +552,7 @@ bool ResourceAccess::processMessageBuffer()
auto buffer = \
Commands::GetRevisionUpdate(d->partialMessageBuffer.constData() + \
headerSize);
Trace() << QString("Revision updated to: %1").arg(buffer->revision());
Notification n;
- n.type = \
Sink::Commands::NotificationType::NotificationType_RevisionUpdate; + \
n.type = Sink::Notification::RevisionUpdate; emit notification(n);
emit revisionChanged(buffer->revision());
@@ -553,30 +570,26 @@ bool ResourceAccess::processMessageBuffer()
case Commands::NotificationCommand: {
auto buffer = \
Commands::GetNotification(d->partialMessageBuffer.constData() + headerSize); switch \
(buffer->type()) {
- case Sink::Commands::NotificationType::NotificationType_Shutdown:
+ case Sink::Notification::Shutdown:
Log() << "Received shutdown notification.";
close();
break;
- case Sink::Commands::NotificationType::NotificationType_Inspection: \
{ + case Sink::Notification::Inspection: {
Trace() << "Received inspection notification.";
- Notification n;
- if (buffer->identifier()) {
- // Don't use fromRawData, the buffer is gone once we invoke \
emit notification
- n.id = BufferUtils::extractBufferCopy(buffer->identifier());
- }
- if (buffer->message()) {
- // Don't use fromRawData, the buffer is gone once we invoke \
emit notification
- n.message = \
BufferUtils::extractBufferCopy(buffer->message());
- }
- n.type = buffer->type();
- n.code = buffer->code();
+ auto n = getNotification(buffer);
// The callbacks can result in this object getting destroyed \
directly, so we need to ensure we finish our work first queuedInvoke([=]() { emit \
notification(n); }, this); } break;
- case Sink::Commands::NotificationType::NotificationType_Status:
- case Sink::Commands::NotificationType::NotificationType_Warning:
- case Sink::Commands::NotificationType::NotificationType_Progress:
- case \
Sink::Commands::NotificationType::NotificationType_RevisionUpdate: + \
case Sink::Notification::Status: + mResourceStatus = \
buffer->code(); + [[clang::fallthrough]];
+ case Sink::Notification::Warning:
+ [[clang::fallthrough]];
+ case Sink::Notification::Progress: {
+ auto n = getNotification(buffer);
+ emit notification(n);
+ } break;
+ case Sink::Notification::RevisionUpdate:
default:
Warning() << "Received unknown notification: " << \
buffer->type(); break;
diff --git a/common/resourceaccess.h b/common/resourceaccess.h
index 69d52b4..5c65998 100644
--- a/common/resourceaccess.h
+++ b/common/resourceaccess.h
@@ -72,14 +72,22 @@ public:
return KAsync::null<void>();
};
+ int getResourceStatus() const
+ {
+ return mResourceStatus;
+ }
+
signals:
void ready(bool isReady);
void revisionChanged(qint64 revision);
- void notification(Notification revision);
+ void notification(Notification notification);
public slots:
virtual void open() = 0;
virtual void close() = 0;
+
+protected:
+ int mResourceStatus;
};
class SINK_EXPORT ResourceAccess : public ResourceAccessInterface
diff --git a/tests/dummyresourcebenchmark.cpp b/tests/dummyresourcebenchmark.cpp
index d5f98c3..7e334a6 100644
--- a/tests/dummyresourcebenchmark.cpp
+++ b/tests/dummyresourcebenchmark.cpp
@@ -90,7 +90,7 @@ private slots:
bool gotNotification = false;
int duration = 0;
notifier->registerHandler([&gotNotification, &duration, &time](const \
Sink::Notification ¬ification) {
- if (notification.type == \
Sink::Commands::NotificationType::NotificationType_RevisionUpdate) { + if \
(notification.type == Sink::Notification::RevisionUpdate) { gotNotification = true;
duration = time.elapsed();
}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic