Skip to content

Commit

Permalink
Implement a back-off so that sync requests are sent no sooner than 5 …
Browse files Browse the repository at this point in the history
…minutes after the last.

This should help issue #61
  • Loading branch information
blizzard4591 committed Apr 17, 2020
1 parent 70829e9 commit 856f431
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/database/Database.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ namespace openmittsu {
virtual void setContactAccountStatusBatch(ContactToAccountStatusMap const& status) = 0;
virtual void setContactFeatureLevelBatch(ContactToFeatureLevelMap const& featureLevels) = 0;
virtual GroupToTitleMap getKnownGroupsContainingMember(openmittsu::protocol::ContactId const& identity) const = 0;
virtual openmittsu::protocol::MessageTime getGroupLastSyncRequestTime(openmittsu::protocol::GroupId const& group) = 0;

// Deleting Messages
virtual void deleteContactMessageByUuid(openmittsu::protocol::ContactId const& contact, QString const& uuid) = 0;
Expand Down
4 changes: 4 additions & 0 deletions src/database/DatabaseWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,10 @@ namespace openmittsu {
OPENMITTSU_DATABASEWRAPPER_WRAP_RETURN(getKnownGroupsContainingMember, GroupToTitleMap, Q_ARG(openmittsu::protocol::ContactId const&, identity));
}

openmittsu::protocol::MessageTime DatabaseWrapper::getGroupLastSyncRequestTime(openmittsu::protocol::GroupId const& group) {
OPENMITTSU_DATABASEWRAPPER_WRAP_RETURN(getGroupLastSyncRequestTime, openmittsu::protocol::MessageTime, Q_ARG(openmittsu::protocol::GroupId const&, group));
}

void DatabaseWrapper::deleteContactMessageByUuid(openmittsu::protocol::ContactId const& contact, QString const& uuid) {
OPENMITTSU_DATABASEWRAPPER_WRAP_VOID(deleteContactMessageByUuid, Q_ARG(openmittsu::protocol::ContactId const&, contact), Q_ARG(QString const&, uuid));
}
Expand Down
1 change: 1 addition & 0 deletions src/database/DatabaseWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ namespace openmittsu {
virtual void setContactAccountStatusBatch(ContactToAccountStatusMap const& status) override;
virtual void setContactFeatureLevelBatch(ContactToFeatureLevelMap const& featureLevels) override;
virtual GroupToTitleMap getKnownGroupsContainingMember(openmittsu::protocol::ContactId const& identity) const override;
virtual openmittsu::protocol::MessageTime getGroupLastSyncRequestTime(openmittsu::protocol::GroupId const& group) override;
// Deleting Messages
virtual void deleteContactMessageByUuid(openmittsu::protocol::ContactId const& contact, QString const& uuid) override;
virtual void deleteContactMessagesByAge(openmittsu::protocol::ContactId const& contact, bool olderThanOrNewerThan, openmittsu::protocol::MessageTime const& timePoint) override;
Expand Down
4 changes: 4 additions & 0 deletions src/database/SimpleDatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1408,6 +1408,10 @@ namespace openmittsu {
return m_contactAndGroupDataProvider.getKnownGroupsContainingMember(identity);
}

openmittsu::protocol::MessageTime SimpleDatabase::getGroupLastSyncRequestTime(openmittsu::protocol::GroupId const& group) {
return internal::DatabaseGroupMessageCursor::getLastSyncRequestTimeByUs(this, group);
}

internal::DatabaseContactMessageCursor SimpleDatabase::getMessageCursor(openmittsu::protocol::ContactId const& contact) {
if (!hasContact(contact)) {
throw openmittsu::exceptions::InternalErrorException() << "Could not create message cursor because the given contact " << contact.toString() << " is unknown!";
Expand Down
1 change: 1 addition & 0 deletions src/database/SimpleDatabase.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ namespace openmittsu {
virtual QSet<openmittsu::protocol::ContactId> getContactsRequiringFeatureLevelCheck(int maximalAgeInSeconds) const override;
virtual QSet<openmittsu::protocol::ContactId> getContactsRequiringAccountStatusCheck(int maximalAgeInSeconds) const override;
virtual GroupToTitleMap getKnownGroupsContainingMember(openmittsu::protocol::ContactId const& identity) const override;
virtual openmittsu::protocol::MessageTime getGroupLastSyncRequestTime(openmittsu::protocol::GroupId const& group) override;

virtual std::shared_ptr<openmittsu::backup::IdentityBackup> getBackup() const override;

Expand Down
24 changes: 24 additions & 0 deletions src/database/internal/DatabaseGroupMessageCursor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,30 @@ namespace openmittsu {
}
}

openmittsu::protocol::MessageTime DatabaseGroupMessageCursor::getLastSyncRequestTimeByUs(InternalDatabaseInterface* database, openmittsu::protocol::GroupId const& group) {
QString const selectQuery = QStringLiteral("SELECT `uid`, `sort_by` FROM `group_messages` WHERE `group_id` = :groupId AND `is_outbox` = 1 AND `group_message_type` = :groupMessageType ORDER BY `sort_by` DESC LIMIT 1");
{
QSqlQuery query(database->getQueryObject());
if (!query.prepare(selectQuery)) {
throw openmittsu::exceptions::InternalErrorException() << "Could not prepare group message enumeration query. SQL error: " << query.lastError().text().toStdString();
}
query.bindValue(QStringLiteral(":groupId"), QVariant(group.groupIdWithoutOwnerToQString()));
query.bindValue(QStringLiteral(":groupMessageType"), QVariant(GroupMessageTypeHelper::toQString(GroupMessageType::SYNC_REQUEST)));
if (query.exec() && query.isSelect()) {
if (query.next()) {
QString const uuid(query.value(QStringLiteral("uid")).toString());
qint64 const messageTime = query.value(QStringLiteral("sort_by")).toLongLong();
return openmittsu::protocol::MessageTime::fromDatabase(messageTime);
} else {
LOGGER_DEBUG("Failed to find an outgoing group sync request for group {}.", group.toString());
return openmittsu::protocol::MessageTime::fromDatabase(-1); // This creates a "null" MessageTime
}
} else {
throw openmittsu::exceptions::InternalErrorException() << "Could not execute group message enumeration query for table group_messages. Query error: " << query.lastError().text().toStdString();
}
}
}

}
}
}
1 change: 1 addition & 0 deletions src/database/internal/DatabaseGroupMessageCursor.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ namespace openmittsu {

static void deleteMessagesByAge(InternalDatabaseInterface* database, openmittsu::protocol::GroupId const& group, bool olderThanOrNewerThan, openmittsu::protocol::MessageTime const& timePoint);
static void deleteMessagesByCount(InternalDatabaseInterface* database, openmittsu::protocol::GroupId const& group, bool oldestOrNewest, int count);
static openmittsu::protocol::MessageTime getLastSyncRequestTimeByUs(InternalDatabaseInterface* database, openmittsu::protocol::GroupId const& group);
protected:
virtual QString getWhereString() const override;
virtual void bindWhereStringValues(QSqlQuery& query) const override;
Expand Down
17 changes: 16 additions & 1 deletion src/dataproviders/SimpleMessageCenter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1238,7 +1238,22 @@ namespace openmittsu {

void SimpleMessageCenter::requestSyncForGroupIfApplicable(openmittsu::protocol::GroupId const& group) {
if (!m_messageQueue.hasMessageForGroup(group)) {
this->sendSyncRequest(group);
openmittsu::protocol::MessageTime const lastSyncRequestTime = this->m_storage.getGroupLastSyncRequestTime(group);
bool isLastSyncRequestLongEnoughInThePast = false;
if (lastSyncRequestTime.isNull()) {
LOGGER_DEBUG("Last sync request time for group {} is null!", group.toString());
isLastSyncRequestLongEnoughInThePast = true;
} else if (lastSyncRequestTime.getTime().addSecs(5 * 60) < QDateTime::currentDateTime()) { // At least 5 minutes since the last sync request
LOGGER_DEBUG("Last sync request time for group {} is {}!", group.toString(), lastSyncRequestTime.getTime().toString().toStdString());
isLastSyncRequestLongEnoughInThePast = true;
}

if (isLastSyncRequestLongEnoughInThePast) {
LOGGER_DEBUG("requestSyncForGroupIfApplicable for group {} will send sync request.", group.toString());
this->sendSyncRequest(group);
}
} else {
LOGGER_DEBUG("requestSyncForGroupIfApplicable for group {} will NOT send sync request, messageQueue has waiting messages for group.", group.toString());
}
}

Expand Down

0 comments on commit 856f431

Please sign in to comment.