Merge branch 'master' into thewire_fix_message_display

This commit is contained in:
drbob 2020-03-31 21:23:51 +11:00
commit 3402aa861f
119 changed files with 1809 additions and 1100 deletions

View file

@ -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 <fstream>
#include <util/rsdir.h>
#include <algorithm>
@ -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
}
}
@ -1343,6 +1347,7 @@ int RsDataService::retrieveGxsMsgMetaData(const GxsMsgReq& reqIds, GxsMsgMetaRes
}
#ifdef RS_DATA_SERVICE_DEBUG_TIME
if(mDbName==std::string("gxsforums_db"))
std::cerr << "RsDataService::retrieveGxsMsgMetaData() " << mDbName << ", Requests: " << reqIds.size() << ", Results: " << resultCount << ", Time: " << timer.duration() << std::endl;
#endif
@ -1413,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();
@ -1440,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;

View file

@ -3461,20 +3461,32 @@ bool RsGenExchange::exportGroupBase64(
if(groupId.isNull()) return failure("groupId cannot be null");
// We have no blocking API here, so we need to make a blocking request manually.
const std::list<RsGxsGroupId> groupIds({groupId});
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
uint32_t token;
mDataAccess->requestGroupInfo(
token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds);
RsTokenService::GxsRequestStatus wtStatus = mDataAccess->waitToken(token);
if(wtStatus != RsTokenService::COMPLETE)
return failure( "waitToken(...) failed with: " +
std::to_string(wtStatus) );
mDataAccess->requestGroupInfo( token, RS_TOKREQ_ANSTYPE_DATA, opts, groupIds);
// provide a sync response: actually wait for the token.
std::chrono::milliseconds maxWait = std::chrono::milliseconds(10000);
std::chrono::milliseconds checkEvery = std::chrono::milliseconds(100);
auto timeout = std::chrono::steady_clock::now() + maxWait; // wait for 10 secs at most
auto st = mDataAccess->requestStatus(token);
while( !(st == RsTokenService::FAILED || st >= RsTokenService::COMPLETE) && std::chrono::steady_clock::now() < timeout )
{
std::this_thread::sleep_for(checkEvery);
st = mDataAccess->requestStatus(token);
}
if(st != RsTokenService::COMPLETE)
return failure( "waitToken(...) failed with: " + std::to_string(st) );
uint8_t* buf = nullptr;
uint32_t size;
RsGxsGroupId grpId;
if(!getSerializedGroupData(token, grpId, buf, size))
return failure("failed retrieving GXS data");

View file

@ -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(

View file

@ -30,6 +30,8 @@
* #define DATA_DEBUG 1
**********/
#define DATA_DEBUG 1
RsGxsDataAccess::RsGxsDataAccess(RsGeneralDataService* ds) :
mDataStore(ds), mDataMutex("RsGxsDataAccess"), mNextToken(0) {}

View file

@ -113,8 +113,6 @@ int p3GxsTunnelService::tick()
flush() ;
rstime::rs_usleep(1000*500);
return 0 ;
}

View file

@ -45,11 +45,10 @@ class RsGxsChannels;
extern RsGxsChannels* rsGxsChannels;
struct RsGxsChannelGroup : RsSerializable
struct RsGxsChannelGroup : RsSerializable, RsGxsGenericGroupData
{
RsGxsChannelGroup() : mAutoDownload(false) {}
RsGroupMetaData mMeta;
std::string mDescription;
RsGxsImage mImage;
@ -399,6 +398,15 @@ public:
virtual bool subscribeToChannel( const RsGxsGroupId& channelId,
bool subscribe ) = 0;
/**
* \brief Retrieve statistics about the given channel
* @jsonapi{development}
* \param[in] channelId Id of the channel group
* \param[out] stat Statistics structure
* \return
*/
virtual bool getChannelStatistics(const RsGxsGroupId& channelId,GxsGroupStatistic& stat) =0;
/**
* @brief Request remote channels search
* @jsonapi{development}

View file

@ -164,7 +164,9 @@ struct RsGxsCommentService
virtual bool getRelatedComments( uint32_t token,
std::vector<RsGxsComment> &comments ) = 0;
virtual bool createNewComment(uint32_t &token, RsGxsComment &comment) = 0;
virtual bool createNewComment(uint32_t &token, const RsGxsComment &comment) = 0; // async API
virtual bool createComment(RsGxsComment& comment) = 0; // blocking API. Updates comment with new metadata.
virtual bool createNewVote(uint32_t &token, RsGxsVote &vote) = 0;
virtual bool acknowledgeComment(

View file

@ -54,11 +54,8 @@ static const uint32_t RS_GXS_FORUM_MSG_FLAGS_MODERATED = 0x00000001;
#define IS_FORUM_MSG_MODERATION(flags) (flags & RS_GXS_FORUM_MSG_FLAGS_MODERATED)
struct RsGxsForumGroup : RsSerializable
struct RsGxsForumGroup : RsSerializable, RsGxsGenericGroupData
{
/** Forum GXS metadata */
RsGroupMetaData mMeta;
/** @brief Forum desciption */
std::string mDescription;
@ -222,6 +219,15 @@ public:
*/
virtual bool getForumsSummaries(std::list<RsGroupMetaData>& forums) = 0;
/**
* @brief returns statistics about a particular forum
* @jsonapi{development}
* @param[in] forumId Id of the forum
* @param[out] stat statistics struct
* @return false when the object doesn't exist or when the timeout is reached requesting the data
*/
virtual bool getForumStatistics(const RsGxsGroupId& forumId,GxsGroupStatistic& stat)=0;
/**
* @brief Get forums information (description, thumbnail...).
* Blocking API.
@ -364,5 +370,5 @@ public:
RS_DEPRECATED_FOR(createMessage)
virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg) = 0;
RS_DEPRECATED_FOR(editForum)
virtual bool updateGroup(uint32_t &token, RsGxsForumGroup &group) = 0;
virtual bool updateGroup(uint32_t &token, const RsGxsForumGroup &group) = 0;
};

View file

@ -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

View file

@ -26,6 +26,7 @@
#include <thread>
#include "retroshare/rsgxsiface.h"
#include "retroshare/rsservicecontrol.h"
#include "retroshare/rsreputations.h"
#include "rsgxsflags.h"
#include "util/rsdeprecate.h"
@ -38,14 +39,26 @@
* To properly fix the API design many changes with the implied chain reactions
* are necessary, so at this point this workaround seems acceptable.
*/
struct RsGxsIfaceHelper
enum class TokenRequestType: uint8_t
{
GROUP_INFO = 0x01,
MSG_INFO = 0x02,
MSG_RELATED_INFO = 0x03,
GROUP_STATISTICS = 0x04,
SERVICE_STATISTICS = 0x05,
NO_KILL_TYPE = 0x06,
};
class RsGxsIfaceHelper
{
public:
/*!
* @param gxs handle to RsGenExchange instance of service (Usually the
* service class itself)
*/
RsGxsIfaceHelper(RsGxsIface& gxs) :
mGxs(gxs), mTokenService(*gxs.getTokenService()) {}
mGxs(gxs), mTokenService(*gxs.getTokenService()),mMtx("GxsIfaceHelper") {}
~RsGxsIfaceHelper(){}
@ -233,30 +246,81 @@ struct RsGxsIfaceHelper
}
/// @see RsTokenService::requestGroupInfo
bool requestGroupInfo( uint32_t& token, const RsTokReqOptions& opts,
const std::list<RsGxsGroupId> &groupIds )
{ return mTokenService.requestGroupInfo(token, 0, opts, groupIds); }
bool requestGroupInfo( uint32_t& token, const RsTokReqOptions& opts, const std::list<RsGxsGroupId> &groupIds, bool high_priority_request = false )
{
cancelActiveRequestTokens(TokenRequestType::GROUP_INFO);
if( mTokenService.requestGroupInfo(token, 0, opts, groupIds))
{
RS_STACK_MUTEX(mMtx);
mActiveTokens[token]=high_priority_request? (TokenRequestType::NO_KILL_TYPE) : (TokenRequestType::GROUP_INFO);
locked_dumpTokens();
return true;
}
else
return false;
}
/// @see RsTokenService::requestGroupInfo
bool requestGroupInfo(uint32_t& token, const RsTokReqOptions& opts)
{ return mTokenService.requestGroupInfo(token, 0, opts); }
bool requestGroupInfo(uint32_t& token, const RsTokReqOptions& opts, bool high_priority_request = false)
{
cancelActiveRequestTokens(TokenRequestType::GROUP_INFO);
if( mTokenService.requestGroupInfo(token, 0, opts))
{
RS_STACK_MUTEX(mMtx);
mActiveTokens[token]=high_priority_request? (TokenRequestType::NO_KILL_TYPE) : (TokenRequestType::GROUP_INFO);
locked_dumpTokens();
return true;
}
else
return false;
}
/// @see RsTokenService::requestMsgInfo
bool requestMsgInfo( uint32_t& token,
const RsTokReqOptions& opts, const GxsMsgReq& msgIds )
{ return mTokenService.requestMsgInfo(token, 0, opts, msgIds); }
{
if(mTokenService.requestMsgInfo(token, 0, opts, msgIds))
{
RS_STACK_MUTEX(mMtx);
mActiveTokens[token]=TokenRequestType::MSG_INFO;
locked_dumpTokens();
return true;
}
else
return false;
}
/// @see RsTokenService::requestMsgInfo
bool requestMsgInfo(
uint32_t& token, const RsTokReqOptions& opts,
const std::list<RsGxsGroupId>& grpIds )
{ return mTokenService.requestMsgInfo(token, 0, opts, grpIds); }
bool requestMsgInfo( uint32_t& token, const RsTokReqOptions& opts, const std::list<RsGxsGroupId>& grpIds )
{
if(mTokenService.requestMsgInfo(token, 0, opts, grpIds))
{
RS_STACK_MUTEX(mMtx);
mActiveTokens[token]=TokenRequestType::MSG_INFO;
locked_dumpTokens();
return true;
}
else
return false;
}
/// @see RsTokenService::requestMsgRelatedInfo
bool requestMsgRelatedInfo(
uint32_t& token, const RsTokReqOptions& opts,
const std::vector<RsGxsGrpMsgIdPair>& msgIds )
{ return mTokenService.requestMsgRelatedInfo(token, 0, opts, msgIds); }
{
if( mTokenService.requestMsgRelatedInfo(token, 0, opts, msgIds))
{
RS_STACK_MUTEX(mMtx);
mActiveTokens[token]=TokenRequestType::MSG_RELATED_INFO;
locked_dumpTokens();
return true;
}
else
return false;
}
/**
* @jsonapi{development}
@ -267,15 +331,50 @@ struct RsGxsIfaceHelper
/// @see RsTokenService::requestServiceStatistic
void requestServiceStatistic(uint32_t& token)
{ mTokenService.requestServiceStatistic(token); }
{
mTokenService.requestServiceStatistic(token);
RS_STACK_MUTEX(mMtx);
mActiveTokens[token]=TokenRequestType::SERVICE_STATISTICS;
locked_dumpTokens();
}
/// @see RsTokenService::requestGroupStatistic
void requestGroupStatistic(uint32_t& token, const RsGxsGroupId& grpId)
{ mTokenService.requestGroupStatistic(token, grpId); }
bool requestGroupStatistic(uint32_t& token, const RsGxsGroupId& grpId)
{
mTokenService.requestGroupStatistic(token, grpId);
RS_STACK_MUTEX(mMtx);
mActiveTokens[token]=TokenRequestType::GROUP_STATISTICS;
locked_dumpTokens();
return true;
}
bool cancelActiveRequestTokens(TokenRequestType type)
{
RS_STACK_MUTEX(mMtx);
for(auto it = mActiveTokens.begin();it!=mActiveTokens.end();)
if(it->second == type)
{
mTokenService.cancelRequest(it->first);
it = mActiveTokens.erase(it);
}
else
++it;
return true;
}
/// @see RsTokenService::cancelRequest
bool cancelRequest(uint32_t token)
{ return mTokenService.cancelRequest(token); }
{
{
RS_STACK_MUTEX(mMtx);
mActiveTokens.erase(token);
}
return mTokenService.cancelRequest(token);
}
/**
* @deprecated
@ -291,14 +390,84 @@ protected:
* @param[in] token token associated to the request caller is waiting for
* @param[in] maxWait maximum waiting time in milliseconds
* @param[in] checkEvery time in millisecond between status checks
* @param[in] auto_delete_if_unsuccessful delete the request when it fails. This avoid leaving useless pending requests in the queue that would slow down additional calls.
*/
RsTokenService::GxsRequestStatus waitToken(
uint32_t token,
std::chrono::milliseconds maxWait = std::chrono::milliseconds(2000),
std::chrono::milliseconds checkEvery = std::chrono::milliseconds(20))
{ return mTokenService.waitToken(token, maxWait, checkEvery); }
std::chrono::milliseconds maxWait = std::chrono::milliseconds(20000),
std::chrono::milliseconds checkEvery = std::chrono::milliseconds(100),
bool auto_delete_if_unsuccessful=true)
{
#if defined(__ANDROID__) && (__ANDROID_API__ < 24)
auto wkStartime = std::chrono::steady_clock::now();
int maxWorkAroundCnt = 10;
LLwaitTokenBeginLabel:
#endif
auto timeout = std::chrono::steady_clock::now() + maxWait;
auto st = requestStatus(token);
while( !(st == RsTokenService::FAILED || st >= RsTokenService::COMPLETE) && std::chrono::steady_clock::now() < timeout )
{
std::this_thread::sleep_for(checkEvery);
st = requestStatus(token);
}
if(st != RsTokenService::COMPLETE && auto_delete_if_unsuccessful)
cancelRequest(token);
#if defined(__ANDROID__) && (__ANDROID_API__ < 24)
/* Work around for very slow/old android devices, we don't expect this
* to be necessary on newer devices. If it take unreasonably long
* something worser is already happening elsewere and we return anyway.
*/
if( st > RsTokenService::FAILED && st < RsTokenService::COMPLETE
&& maxWorkAroundCnt-- > 0 )
{
maxWait *= 10;
checkEvery *= 3;
Dbg3() << __PRETTY_FUNCTION__ << " Slow Android device "
<< " workaround st: " << st
<< " maxWorkAroundCnt: " << maxWorkAroundCnt
<< " maxWait: " << maxWait.count()
<< " checkEvery: " << checkEvery.count() << std::endl;
goto LLwaitTokenBeginLabel;
}
Dbg3() << __PRETTY_FUNCTION__ << " lasted: "
<< std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - wkStartime ).count()
<< "ms" << std::endl;
#endif
{
RS_STACK_MUTEX(mMtx);
mActiveTokens.erase(token);
}
return st;
}
private:
RsGxsIface& mGxs;
RsTokenService& mTokenService;
RsMutex mMtx;
std::map<uint32_t,TokenRequestType> mActiveTokens;
void locked_dumpTokens()
{
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<int>(it.second)];
for(uint32_t i=0;i<7;++i)
std::cerr /* << i << ":" */ << count[i] << " ";
std::cerr << std::endl;
}
};

View file

@ -118,8 +118,15 @@ struct RsGroupMetaData : RsSerializable
}
};
// This is the parent class of all interface-level GXS group data. Derived classes
// will include service-specific information, such as icon, description, etc
struct RsGxsGenericGroupData
{
virtual ~RsGxsGenericGroupData() = default; // making the type polymorphic
RsGroupMetaData mMeta;
};
struct RsMsgMetaData : RsSerializable
{

View file

@ -383,8 +383,9 @@ struct RsIdentityDetails : RsSerializable
/** The Main Interface Class for GXS people identities */
struct RsIdentity : RsGxsIfaceHelper
class RsIdentity: public RsGxsIfaceHelper
{
public:
explicit RsIdentity(RsGxsIface& gxs) : RsGxsIfaceHelper(gxs) {}
/**

View file

@ -40,9 +40,8 @@ class RsPosted;
*/
extern RsPosted* rsPosted;
struct RsPostedGroup
struct RsPostedGroup: RsGxsGenericGroupData
{
RsGroupMetaData mMeta;
std::string mDescription;
RsGxsImage mGroupImage;
};
@ -150,12 +149,20 @@ public:
const std::list<RsGxsGroupId>& boardsIds,
std::vector<RsPostedGroup>& boardsInfo ) = 0;
virtual bool getBoardsSummaries(std::list<RsGroupMetaData>& groupInfo) =0;
virtual bool getBoardContent(
const RsGxsGroupId& boardId,
const std::set<RsGxsMessageId>& contentsIds,
std::vector<RsPostedPost>& posts,
std::vector<RsGxsComment>& comments ) = 0;
virtual bool editBoard(RsPostedGroup& board) =0;
virtual bool createBoard(RsPostedGroup& board) =0;
virtual bool getBoardStatistics(const RsGxsGroupId& boardId,GxsGroupStatistic& stat) =0;
enum RS_DEPRECATED RankType {TopRankType, HotRankType, NewRankType };
RS_DEPRECATED_FOR(getBoardsInfo)

View file

@ -222,6 +222,7 @@ public:
*/
virtual bool cancelRequest(const uint32_t &token) = 0;
#ifdef TO_REMOVE
/**
* Block caller while request is being processed.
* Useful for blocking API implementation.
@ -231,8 +232,9 @@ public:
*/
RsTokenService::GxsRequestStatus waitToken(
uint32_t token,
std::chrono::milliseconds maxWait = std::chrono::milliseconds(500),
std::chrono::milliseconds checkEvery = std::chrono::milliseconds(2))
std::chrono::milliseconds maxWait = std::chrono::milliseconds(10000),
std::chrono::milliseconds checkEvery = std::chrono::milliseconds(20),
bool auto_delete_if_unsuccessful=true)
{
#if defined(__ANDROID__) && (__ANDROID_API__ < 24)
auto wkStartime = std::chrono::steady_clock::now();
@ -241,12 +243,13 @@ LLwaitTokenBeginLabel:
#endif
auto timeout = std::chrono::steady_clock::now() + maxWait;
auto st = requestStatus(token);
while( !(st == RsTokenService::FAILED || st >= RsTokenService::COMPLETE)
&& std::chrono::steady_clock::now() < timeout )
while( !(st == RsTokenService::FAILED || st >= RsTokenService::COMPLETE) && std::chrono::steady_clock::now() < timeout )
{
std::this_thread::sleep_for(checkEvery);
st = requestStatus(token);
}
if(st != RsTokenService::COMPLETE && auto_delete_if_unsuccessful)
cancelRequest(token);
#if defined(__ANDROID__) && (__ANDROID_API__ < 24)
/* Work around for very slow/old android devices, we don't expect this
@ -274,6 +277,7 @@ LLwaitTokenBeginLabel:
return st;
}
#endif
RS_SET_CONTEXT_DEBUG_LEVEL(2)
};

View file

@ -1033,18 +1033,35 @@ bool p3GxsChannels::getChannelsSummaries(
return getGroupSummary(token, channels);
}
bool p3GxsChannels::getChannelsInfo(
const std::list<RsGxsGroupId>& chanIds,
std::vector<RsGxsChannelGroup>& channelsInfo )
bool p3GxsChannels::getChannelsInfo( const std::list<RsGxsGroupId>& chanIds, std::vector<RsGxsChannelGroup>& channelsInfo )
{
uint32_t token;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
if( !requestGroupInfo(token, opts, chanIds)
|| waitToken(token) != RsTokenService::COMPLETE ) return false;
if(chanIds.empty())
{
if( !requestGroupInfo(token, opts) || waitToken(token) != RsTokenService::COMPLETE )
return false;
}
else
{
if( !requestGroupInfo(token, opts, chanIds) || waitToken(token) != RsTokenService::COMPLETE )
return false;
}
return getGroupData(token, channelsInfo) && !channelsInfo.empty();
}
bool p3GxsChannels::getChannelStatistics(const RsGxsGroupId& channelId,GxsGroupStatistic& stat)
{
uint32_t token;
if(!RsGxsIfaceHelper::requestGroupStatistic(token, channelId) || waitToken(token) != RsTokenService::COMPLETE)
return false;
return RsGenExchange::getGroupStatistic(token,stat);
}
bool p3GxsChannels::getContentSummaries(
const RsGxsGroupId& channelId, std::vector<RsMsgMetaData>& summaries )
{

View file

@ -140,7 +140,7 @@ virtual bool getChannelDownloadDirectory(const RsGxsGroupId &groupId, std::strin
std::vector<RsGxsComment> &msgs ) override
{ return mCommentService->getGxsRelatedComments(token, msgs); }
virtual bool createNewComment(uint32_t &token, RsGxsComment &msg) override
virtual bool createNewComment(uint32_t &token, const RsGxsComment &msg) override
{
return mCommentService->createGxsComment(token, msg);
}
@ -196,6 +196,9 @@ virtual bool ExtraFileRemove(const RsFileHash &hash);
const RsGxsGroupId& channelId,
std::vector<RsMsgMetaData>& summaries ) override;
/// Implementation of @see RsGxsChannels::getChannelStatistics
bool getChannelStatistics(const RsGxsGroupId& channelId,GxsGroupStatistic& stat) override;
/// Implementation of @see RsGxsChannels::createChannelV2
bool createChannelV2(
const std::string& name, const std::string& description,
@ -277,7 +280,7 @@ virtual bool ExtraFileRemove(const RsFileHash &hash);
/// @deprecated Implementation of @see RsGxsChannels::createComment
RS_DEPRECATED_FOR(createCommentV2)
bool createComment(RsGxsComment& comment) override;
bool createComment(RsGxsComment &comment) override;
/// @deprecated Implementation of @see RsGxsChannels::createVote
RS_DEPRECATED_FOR(createVoteV2)

View file

@ -278,9 +278,13 @@ bool p3GxsCircles::getCirclesSummaries(std::list<RsGroupMetaData>& circles)
uint32_t token;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_META;
if( !requestGroupInfo(token, opts)
|| waitToken(token) != RsTokenService::COMPLETE ) return false;
return getGroupSummary(token, circles);
if( !requestGroupInfo(token, opts) || waitToken(token) != RsTokenService::COMPLETE )
{
std::cerr << "Cannot get circles summary. Token queue is overloaded?" << std::endl;
return false;
}
else
return getGroupSummary(token, circles);
}
bool p3GxsCircles::getCirclesInfo( const std::list<RsGxsGroupId>& circlesIds,
@ -289,9 +293,13 @@ bool p3GxsCircles::getCirclesInfo( const std::list<RsGxsGroupId>& circlesIds,
uint32_t token;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
if( !requestGroupInfo(token, opts, circlesIds)
|| waitToken(token) != RsTokenService::COMPLETE ) return false;
return getGroupData(token, circlesInfo);
if( !requestGroupInfo(token, opts, circlesIds) || waitToken(token) != RsTokenService::COMPLETE )
{
std::cerr << "Cannot get circle info. Token queue is overloaded?" << std::endl;
return false;
}
else
return getGroupData(token, circlesInfo);
}
bool p3GxsCircles::getCircleRequests( const RsGxsGroupId& circleId,

View file

@ -425,7 +425,7 @@ double p3GxsCommentService::calculateBestScore(int upVotes, int downVotes)
/********************************************************************************************/
bool p3GxsCommentService::createGxsComment(uint32_t &token, RsGxsComment &msg)
bool p3GxsCommentService::createGxsComment(uint32_t &token, const RsGxsComment &msg)
{
#ifdef DEBUG_GXSCOMMON
std::cerr << "p3GxsCommentService::createGxsComment() GroupId: " << msg.mMeta.mGroupId;

View file

@ -66,7 +66,7 @@ class p3GxsCommentService: public GxsTokenQueue
bool getGxsCommentData(const uint32_t &token, std::vector<RsGxsComment> &msgs);
bool getGxsRelatedComments(const uint32_t &token, std::vector<RsGxsComment> &msgs);
bool createGxsComment(uint32_t &token, RsGxsComment &msg);
bool createGxsComment(uint32_t &token, const RsGxsComment &msg);
bool createGxsVote(uint32_t &token, RsGxsVote &msg);
// Special Acknowledge.

View file

@ -666,15 +666,22 @@ bool p3GxsForums::getForumsSummaries( std::list<RsGroupMetaData>& forums )
return getGroupSummary(token, forums);
}
bool p3GxsForums::getForumsInfo(
const std::list<RsGxsGroupId>& forumIds,
std::vector<RsGxsForumGroup>& forumsInfo )
bool p3GxsForums::getForumsInfo( const std::list<RsGxsGroupId>& forumIds, std::vector<RsGxsForumGroup>& forumsInfo )
{
uint32_t token;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
if( !requestGroupInfo(token, opts, forumIds)
|| waitToken(token,std::chrono::milliseconds(5000)) != RsTokenService::COMPLETE ) return false;
if(forumIds.empty())
{
if( !requestGroupInfo(token, opts) || waitToken(token,std::chrono::milliseconds(5000)) != RsTokenService::COMPLETE )
return false;
}
else
{
if( !requestGroupInfo(token, opts, forumIds, forumIds.size()==1) || waitToken(token,std::chrono::milliseconds(5000)) != RsTokenService::COMPLETE )
return false;
}
return getGroupData(token, forumsInfo);
}
@ -812,7 +819,16 @@ bool p3GxsForums::createGroup(uint32_t &token, RsGxsForumGroup &group)
return true;
}
bool p3GxsForums::updateGroup(uint32_t &token, RsGxsForumGroup &group)
bool p3GxsForums::getForumStatistics(const RsGxsGroupId& ForumId,GxsGroupStatistic& stat)
{
uint32_t token;
if(!RsGxsIfaceHelper::requestGroupStatistic(token, ForumId) || waitToken(token) != RsTokenService::COMPLETE)
return false;
return RsGenExchange::getGroupStatistic(token,stat);
}
bool p3GxsForums::updateGroup(uint32_t &token, const RsGxsForumGroup &group)
{
std::cerr << "p3GxsForums::updateGroup()" << std::endl;

View file

@ -94,6 +94,9 @@ public:
const std::list<RsGxsGroupId>& forumIds,
std::vector<RsGxsForumGroup>& forumsInfo );
/// Implementation of @see RsGxsForums::getForumStatistics
bool getForumStatistics(const RsGxsGroupId& ForumId,GxsGroupStatistic& stat) override;
/// @see RsGxsForums::getForumMsgMetaData
virtual bool getForumMsgMetaData(const RsGxsGroupId& forumId, std::vector<RsMsgMetaData>& msg_metas) ;
@ -125,13 +128,16 @@ public:
std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string)
) override;
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsForumGroup> &groups);
virtual bool getMsgData(const uint32_t &token, std::vector<RsGxsForumMsg> &msgs);
virtual bool getMsgMetaData(const uint32_t &token, GxsMsgMetaMap& msg_metas);
virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read);
virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group);
virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg);
virtual bool updateGroup(uint32_t &token, RsGxsForumGroup &group);
/// implementation of rsGxsGorums
///
bool getGroupData(const uint32_t &token, std::vector<RsGxsForumGroup> &groups) override;
bool getMsgData(const uint32_t &token, std::vector<RsGxsForumMsg> &msgs) override;
void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) override;
bool createGroup(uint32_t &token, RsGxsForumGroup &group) override;
bool createMsg(uint32_t &token, RsGxsForumMsg &msg) override;
bool updateGroup(uint32_t &token, const RsGxsForumGroup &group) override;
bool getMsgMetaData(const uint32_t &token, GxsMsgMetaMap& msg_metas) ;
private:

View file

@ -639,25 +639,28 @@ void p3IdService::notifyChanges(std::vector<RsGxsNotify *> &changes)
std::cerr << "p3IdService::notifyChanges() Auto Subscribe to Incoming Groups: " << *git;
std::cerr << std::endl;
#endif
if(!rsReputations->isIdentityBanned(RsGxsId(*git)))
{
uint32_t token;
RsGenExchange::subscribeToGroup(token, *git, true);
// also time_stamp the key that this group represents
timeStampKey(RsGxsId(*git),RsIdentityUsage(serviceType(),RsIdentityUsage::IDENTITY_DATA_UPDATE)) ;
// notify that a new identity is received, if needed
bool should_subscribe = false;
switch(groupChange->getType())
{
case RsGxsNotify::TYPE_PROCESSED: break ; // Happens when the group is subscribed. This is triggered by RsGenExchange::subscribeToGroup, so better not
// call it again from here!!
case RsGxsNotify::TYPE_PUBLISHED:
{
auto ev = std::make_shared<RsGxsIdentityEvent>();
ev->mIdentityId = *git;
ev->mIdentityEventCode = RsGxsIdentityEventCode::UPDATED_IDENTITY;
rsEvents->postEvent(ev);
// also time_stamp the key that this group represents
timeStampKey(RsGxsId(*git),RsIdentityUsage(serviceType(),RsIdentityUsage::IDENTITY_DATA_UPDATE)) ;
should_subscribe = true;
}
break;
@ -667,12 +670,23 @@ void p3IdService::notifyChanges(std::vector<RsGxsNotify *> &changes)
ev->mIdentityId = *git;
ev->mIdentityEventCode = RsGxsIdentityEventCode::NEW_IDENTITY;
rsEvents->postEvent(ev);
// also time_stamp the key that this group represents
timeStampKey(RsGxsId(*git),RsIdentityUsage(serviceType(),RsIdentityUsage::IDENTITY_DATA_UPDATE)) ;
should_subscribe = true;
}
break;
default:
break;
}
if(should_subscribe)
{
uint32_t token;
RsGenExchange::subscribeToGroup(token, *git, true);
}
}
}
}

View file

@ -85,7 +85,7 @@ public:
return mCommentService->getGxsRelatedComments(token, msgs);
}
virtual bool createNewComment(uint32_t &token, RsGxsComment &msg) override
virtual bool createNewComment(uint32_t &token, const RsGxsComment &msg) override
{
return mCommentService->createGxsComment(token, msg);
}

View file

@ -307,8 +307,18 @@ bool p3Posted::getBoardsInfo(
uint32_t token;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
if( !requestGroupInfo(token, opts, boardsIds)
|| waitToken(token) != RsTokenService::COMPLETE ) return false;
if(boardsIds.empty())
{
if( !requestGroupInfo(token, opts) || waitToken(token) != RsTokenService::COMPLETE )
return false;
}
else
{
if( !requestGroupInfo(token, opts, boardsIds) || waitToken(token) != RsTokenService::COMPLETE )
return false;
}
return getGroupData(token, groupsInfo) && !groupsInfo.empty();
}
@ -330,5 +340,72 @@ bool p3Posted::getBoardContent( const RsGxsGroupId& groupId,
return getPostData(token, posts, comments);
}
bool p3Posted::getBoardsSummaries(std::list<RsGroupMetaData>& boards )
{
uint32_t token;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_META;
if( !requestGroupInfo(token, opts) || waitToken(token) != RsTokenService::COMPLETE ) return false;
return getGroupSummary(token, boards);
}
bool p3Posted::getBoardStatistics(const RsGxsGroupId& boardId,GxsGroupStatistic& stat)
{
uint32_t token;
if(!RsGxsIfaceHelper::requestGroupStatistic(token, boardId) || waitToken(token) != RsTokenService::COMPLETE)
return false;
return RsGenExchange::getGroupStatistic(token,stat);
}
bool p3Posted::createBoard(RsPostedGroup& board)
{
uint32_t token;
if(!createGroup(token, board))
{
std::cerr << __PRETTY_FUNCTION__ << "Error! Failed creating group." << std::endl;
return false;
}
if(waitToken(token,std::chrono::milliseconds(5000)) != RsTokenService::COMPLETE)
{
std::cerr << __PRETTY_FUNCTION__ << "Error! GXS operation failed." << std::endl;
return false;
}
if(!RsGenExchange::getPublishedGroupMeta(token, board.mMeta))
{
std::cerr << __PRETTY_FUNCTION__ << "Error! Failure getting updated " << " group data." << std::endl;
return false;
}
return true;
}
bool p3Posted::editBoard(RsPostedGroup& board)
{
uint32_t token;
if(!updateGroup(token, board))
{
std::cerr << __PRETTY_FUNCTION__ << " Error! Failed updating group." << std::endl;
return false;
}
if(waitToken(token) != RsTokenService::COMPLETE)
{
std::cerr << __PRETTY_FUNCTION__ << " Error! GXS operation failed." << std::endl;
return false;
}
if(!RsGenExchange::getPublishedGroupMeta(token, board.mMeta))
{
std::cerr << __PRETTY_FUNCTION__ << " Error! Failure getting updated " << " group data." << std::endl;
return false;
}
return true;
}
RsPosted::~RsPosted() = default;
RsGxsPostedEvent::~RsGxsPostedEvent() = default;

View file

@ -66,6 +66,14 @@ virtual void receiveHelperChanges(std::vector<RsGxsNotify*>& changes)
std::vector<RsPostedPost>& posts,
std::vector<RsGxsComment>& comments ) override;
bool getBoardsSummaries(std::list<RsGroupMetaData>& groupInfo) override;
bool getBoardStatistics(const RsGxsGroupId& boardId,GxsGroupStatistic& stat) override;
bool editBoard(RsPostedGroup& board) override;
bool createBoard(RsPostedGroup& board) override;
virtual bool getGroupData(const uint32_t &token, std::vector<RsPostedGroup> &groups);
virtual bool getPostData(const uint32_t &token, std::vector<RsPostedPost> &posts, std::vector<RsGxsComment> &cmts);
virtual bool getPostData(const uint32_t &token, std::vector<RsPostedPost> &posts) { std::vector<RsGxsComment> cmts; return getPostData( token, posts, cmts);}
@ -96,10 +104,16 @@ virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgI
std::vector<RsGxsComment> &msgs )
{ return mCommentService->getGxsRelatedComments(token, msgs); }
virtual bool createNewComment(uint32_t &token, RsGxsComment &msg)
virtual bool createNewComment(uint32_t &token, const RsGxsComment &msg) override
{
return mCommentService->createGxsComment(token, msg);
}
virtual bool createComment(RsGxsComment& msg) override
{
uint32_t token;
return mCommentService->createGxsComment(token, msg) && waitToken(token) == RsTokenService::COMPLETE ;
}
virtual bool createNewVote(uint32_t &token, RsGxsVote &msg)
{