diff --git a/libretroshare/src/gxs/rsdataservice.cc b/libretroshare/src/gxs/rsdataservice.cc index 3dc99a85f..cc215dc14 100644 --- a/libretroshare/src/gxs/rsdataservice.cc +++ b/libretroshare/src/gxs/rsdataservice.cc @@ -26,6 +26,10 @@ * #define RS_DATA_SERVICE_DEBUG_CACHE 1 ****/ +#define RS_DATA_SERVICE_DEBUG 1 +#define RS_DATA_SERVICE_DEBUG_TIME 1 +#define RS_DATA_SERVICE_DEBUG_CACHE 1 + #include #include #include @@ -1312,7 +1316,7 @@ int RsDataService::retrieveGxsMsgMetaData(const GxsMsgReq& reqIds, GxsMsgMetaRes { locked_retrieveMsgMeta(c, metaSet); #ifdef RS_DATA_SERVICE_DEBUG_CACHE - std::cerr << "Retrieving (all) Msg metadata grpId=" << grpId << ", " << std::dec << metaSet.size() << " messages" << std::endl; + std::cerr << mDbName << ": Retrieving (all) Msg metadata grpId=" << grpId << ", " << std::dec << metaSet.size() << " messages" << std::endl; #endif } }else{ @@ -1329,7 +1333,7 @@ int RsDataService::retrieveGxsMsgMetaData(const GxsMsgReq& reqIds, GxsMsgMetaRes { locked_retrieveMsgMeta(c, metaSet); #ifdef RS_DATA_SERVICE_DEBUG_CACHE - std::cerr << "Retrieving Msg metadata grpId=" << grpId << ", " << std::dec << metaSet.size() << " messages" << std::endl; + std::cerr << mDbName << ": Retrieving Msg metadata grpId=" << grpId << ", " << std::dec << metaSet.size() << " messages" << std::endl; #endif } } @@ -1414,7 +1418,7 @@ int RsDataService::retrieveGxsGrpMetaData(RsGxsGrpMetaTemporaryMap& grp) { grp[g->mGroupId] = g; #ifdef RS_DATA_SERVICE_DEBUG_CACHE - std::cerr << (void *)this << ": Retrieving (all) Grp metadata grpId=" << g->mGroupId << std::endl; + std::cerr << (void *)this << " " << mDbName << ": Retrieving (all) Grp metadata grpId=" << g->mGroupId << std::endl; #endif } valid = c->moveToNext(); @@ -1441,14 +1445,14 @@ int RsDataService::retrieveGxsGrpMetaData(RsGxsGrpMetaTemporaryMap& grp) if(itt != mGrpMetaDataCache.end()) { #ifdef RS_DATA_SERVICE_DEBUG_CACHE - std::cerr << "Retrieving Grp metadata grpId=" << mit->first << " from cache!" << std::endl; + std::cerr << mDbName << ": Retrieving Grp metadata grpId=" << mit->first << " from cache!" << std::endl; #endif grp[mit->first] = itt->second ; } else { #ifdef RS_DATA_SERVICE_DEBUG_CACHE - std::cerr << "Retrieving Grp metadata grpId=" << mit->first ; + std::cerr << mDbName << ": Retrieving Grp metadata grpId=" << mit->first ; #endif const RsGxsGroupId& grpId = mit->first; diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index 49fd8b2e2..840dc97b3 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -726,7 +726,7 @@ public: virtual void setSyncPeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) ; virtual bool getGroupNetworkStats(const RsGxsGroupId& grpId,RsGroupNetworkStats& stats); - uint16_t serviceType() const { return mServType ; } + uint16_t serviceType() const override { return mServType ; } uint32_t serviceFullType() const { return RsServiceInfo::RsServiceInfoUIn16ToFullServiceId(mServType); } virtual RsReputationLevel minReputationForForwardingMessages( diff --git a/libretroshare/src/gxs/rsgxsdataaccess.cc b/libretroshare/src/gxs/rsgxsdataaccess.cc index 59c828e60..373d9a872 100644 --- a/libretroshare/src/gxs/rsgxsdataaccess.cc +++ b/libretroshare/src/gxs/rsgxsdataaccess.cc @@ -30,6 +30,8 @@ * #define DATA_DEBUG 1 **********/ +#define DATA_DEBUG 1 + RsGxsDataAccess::RsGxsDataAccess(RsGeneralDataService* ds) : mDataStore(ds), mDataMutex("RsGxsDataAccess"), mNextToken(0) {} diff --git a/libretroshare/src/retroshare/rsgxsiface.h b/libretroshare/src/retroshare/rsgxsiface.h index 54a27656d..7bb6bba28 100644 --- a/libretroshare/src/retroshare/rsgxsiface.h +++ b/libretroshare/src/retroshare/rsgxsiface.h @@ -110,6 +110,12 @@ struct RsGxsChanges : RsEvent */ struct RsGxsIface { + /*! + * \brief serviceType + * \return The 16-bits service type. See @serialiser/rsserviceids.h + */ + virtual uint16_t serviceType() const =0; + /*! * Gxs services should call this for automatic handling of * changes, send diff --git a/libretroshare/src/retroshare/rsgxsifacehelper.h b/libretroshare/src/retroshare/rsgxsifacehelper.h index 0d9965c6c..2a9b5bba3 100644 --- a/libretroshare/src/retroshare/rsgxsifacehelper.h +++ b/libretroshare/src/retroshare/rsgxsifacehelper.h @@ -26,6 +26,7 @@ #include #include "retroshare/rsgxsiface.h" +#include "retroshare/rsservicecontrol.h" #include "retroshare/rsreputations.h" #include "rsgxsflags.h" #include "util/rsdeprecate.h" @@ -454,9 +455,19 @@ private: void locked_dumpTokens() { - std::cerr << "Active tokens (this=" << (void*)this << "): " ; - for(auto it: mActiveTokens) - std::cerr << std::dec << it.first << " (" << static_cast(it.second) << ") " ; + uint16_t service_id = mGxs.serviceType(); + + uint32_t count[7] = {0}; + + std::cerr << "Service 0x0" << std::hex << service_id + << " (" << rsServiceControl->getServiceName(RsServiceInfo::RsServiceInfoUIn16ToFullServiceId(service_id)) + << ") this=0x" << (void*)this << ") Active tokens (per type): " ; + + for(auto& it: mActiveTokens) // let's count how many token of each type we've got. + ++count[static_cast(it.second)]; + + for(uint32_t i=0;i<7;++i) + std::cerr /* << i << ":" */ << count[i] << " "; std::cerr << std::endl; } }; diff --git a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp index 08833d9e0..244676b6c 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupFrameDialog.cpp @@ -175,7 +175,7 @@ void GxsGroupFrameDialog::initUi() void GxsGroupFrameDialog::showEvent(QShowEvent *event) { - if (!mInitialized || ui->groupTreeWidget->treeWidget()->topLevelItemCount() == 0) + if (!mInitialized ) { /* Problem: virtual methods cannot be used in constructor */ @@ -1028,6 +1028,8 @@ void GxsGroupFrameDialog::updateGroupSummary() std::cerr << __PRETTY_FUNCTION__ << " failed to collect group info " << std::endl; return; } + if(groupInfo.empty()) + return; RsQThreadUtils::postToObject( [this,groupInfo]() { @@ -1049,17 +1051,18 @@ void GxsGroupFrameDialog::updateGroupSummary() mNavigatePendingGroupId.clear(); mNavigatePendingMsgId.clear(); } - // update the local cache in order to avoid re-asking the data when the UI wants it (this happens on ::show() for instance) - mCachedGroupMetas.clear(); + // update the local cache in order to avoid re-asking the data when the UI wants it (this happens on ::show() for instance) + + mCachedGroupMetas.clear(); // now delete the data that is not used anymore - for(auto& g:groupInfo) - { - mCachedGroupMetas[g->mMeta.mGroupId] = g->mMeta; - delete g; - } + for(auto& g:groupInfo) + { + mCachedGroupMetas[g->mMeta.mGroupId] = g->mMeta; + delete g; + } }, this ); }); diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index b0908ce18..37b479e6a 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -1102,6 +1102,19 @@ void GxsForumThreadWidget::insertMessage() // markMsgAsRead(); } +void GxsForumThreadWidget::setMessageLoadingError(const QString& error) +{ + ui->time_label->setText(QString("")); + ui->by_label->setId(RsGxsId()); + ui->lineRight->show(); + ui->lineLeft->show(); + ui->by_text_label->show(); + ui->by_label->show(); + ui->threadTreeWidget->setFocus(); + + ui->postText->setText(error); +} + void GxsForumThreadWidget::insertMessageData(const RsGxsForumMsg &msg) { /* As some time has elapsed since request - check that this is still the current msg. @@ -1735,28 +1748,32 @@ void GxsForumThreadWidget::updateGroupData() else success = true; - // 2 - sort the messages into a proper hierarchy - - RsGxsForumGroup group(groups[0]); // we use a copy to share the object in order to avoid group deletion while we're in the thread. - - // 3 - update the model in the UI thread. - - RsQThreadUtils::postToObject( [group,success,this]() + if(success) { - /* Here it goes any code you want to be executed on the Qt Gui + // 2 - sort the messages into a proper hierarchy + + RsGxsForumGroup group(groups[0]); // we use a copy to share the object in order to avoid group deletion while we're in the thread. + + // 3 - update the model in the UI thread. + + RsQThreadUtils::postToObject( [group,this]() + { + /* Here it goes any code you want to be executed on the Qt Gui * thread, for example to update the data model with new information * after a blocking call to RetroShare API complete */ - mForumGroup = group; - mThreadId.clear(); + mForumGroup = group; + mThreadId.clear(); - ui->threadTreeWidget->setColumnHidden(RsGxsForumModel::COLUMN_THREAD_DISTRIBUTION, !IS_GROUP_PGP_KNOWN_AUTHED(mForumGroup.mMeta.mSignFlags) && !(IS_GROUP_PGP_AUTHED(mForumGroup.mMeta.mSignFlags))); - ui->subscribeToolButton->setHidden(IS_GROUP_SUBSCRIBED(mForumGroup.mMeta.mSubscribeFlags)) ; + ui->threadTreeWidget->setColumnHidden(RsGxsForumModel::COLUMN_THREAD_DISTRIBUTION, !IS_GROUP_PGP_KNOWN_AUTHED(mForumGroup.mMeta.mSignFlags) && !(IS_GROUP_PGP_AUTHED(mForumGroup.mMeta.mSignFlags))); + ui->subscribeToolButton->setHidden(IS_GROUP_SUBSCRIBED(mForumGroup.mMeta.mSubscribeFlags)) ; - updateForumDescription(success); - - }, this ); + updateForumDescription(true); + }, this ); + } + else + RsQThreadUtils::postToObject( [this]() { updateForumDescription(false); },this); }); } @@ -1774,17 +1791,18 @@ void GxsForumThreadWidget::updateMessageData(const RsGxsMessageId& msgId) std::vector msgs; msgs_to_request.insert(msgId); + QString error_string; if(!rsGxsForums->getForumContent(groupId(),msgs_to_request,msgs)) { std::cerr << __PRETTY_FUNCTION__ << " failed to retrieve message info for forum " << groupId() << " and MsgId " << msgId << std::endl; - return; + error_string = tr("Failed to retrieve this message. Is the database currently overloaded?"); } if(msgs.empty()) { std::cerr << __PRETTY_FUNCTION__ << " no posts for msgId " << msgId << ". Database corruption?" << std::endl; - return; + error_string = tr("No data for this message. Is the database corrupted?"); } if(msgs.size() > 1) { @@ -1792,25 +1810,32 @@ void GxsForumThreadWidget::updateMessageData(const RsGxsMessageId& msgId) std::cerr << "Messages are:" << std::endl; for(auto it(msgs.begin());it!=msgs.end();++it) std::cerr << (*it).mMeta << std::endl; + + error_string = tr("More than one entry for this message. Is the database corrupted?"); } - // 2 - sort the messages into a proper hierarchy - - RsGxsForumMsg msg(msgs[0]); - - // 3 - update the model in the UI thread. - - RsQThreadUtils::postToObject( [msg,this]() + if(error_string.isNull()) { - /* Here it goes any code you want to be executed on the Qt Gui + // 2 - sort the messages into a proper hierarchy + + RsGxsForumMsg msg(msgs[0]); + + // 3 - update the model in the UI thread. + + RsQThreadUtils::postToObject( [msg,this]() + { + /* Here it goes any code you want to be executed on the Qt Gui * thread, for example to update the data model with new information * after a blocking call to RetroShare API complete */ - insertMessageData(msg); + insertMessageData(msg); - ui->threadTreeWidget->setColumnHidden(RsGxsForumModel::COLUMN_THREAD_DISTRIBUTION, !IS_GROUP_PGP_KNOWN_AUTHED(mForumGroup.mMeta.mSignFlags) && !(IS_GROUP_PGP_AUTHED(mForumGroup.mMeta.mSignFlags))); - ui->subscribeToolButton->setHidden(IS_GROUP_SUBSCRIBED(mForumGroup.mMeta.mSubscribeFlags)) ; - }, this ); + ui->threadTreeWidget->setColumnHidden(RsGxsForumModel::COLUMN_THREAD_DISTRIBUTION, !IS_GROUP_PGP_KNOWN_AUTHED(mForumGroup.mMeta.mSignFlags) && !(IS_GROUP_PGP_AUTHED(mForumGroup.mMeta.mSignFlags))); + ui->subscribeToolButton->setHidden(IS_GROUP_SUBSCRIBED(mForumGroup.mMeta.mSubscribeFlags)) ; + }, this ); + } + else + RsQThreadUtils::postToObject( [error_string,this](){ setMessageLoadingError(error_string); } ); }); } diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h index 2dc7f4b78..a23b859ef 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h @@ -92,6 +92,7 @@ protected: /* GxsMessageFrameWidget */ virtual void setAllMessagesReadDo(bool read, uint32_t &token); + void setMessageLoadingError(const QString& error); private slots: /** Create the context popup menu and it's submenus */ void threadListCustomPopupMenu(QPoint point);