Merge pull request #2120 from csoler/v0.6-BugFixing_2

Trying to optimize circles and prevent the spread of unwanted/useless circles
This commit is contained in:
csoler 2020-11-24 18:40:49 +01:00 committed by GitHub
commit be1728d535
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 211 additions and 162 deletions

View File

@ -61,7 +61,9 @@ static const uint32_t INDEX_AUTHEN_ADMIN = 0x00000040; // admin key
#define GXS_MASK "GXS_MASK_HACK"
#define GEN_EXCH_DEBUG 1
/*
* #define GEN_EXCH_DEBUG 1
*/
// Data flow in RsGenExchange
//

View File

@ -60,7 +60,6 @@ public:
: _threshold(0.0)
, _counter(0.0)
, _inc(0.0)
, _item_count(0)
{}
void *pop()
{
@ -69,7 +68,6 @@ public:
void *item = _items.front().data ;
_items.pop_front() ;
--_item_count ;
return item ;
}
@ -137,12 +135,11 @@ public:
_items.push_back(rec) ;
}
uint32_t size() const { return _item_count ; }
uint32_t size() const { return _items.size() ; }
float _threshold ;
float _counter ;
float _inc ;
uint32_t _item_count ;
std::list<ItemRecord> _items ;
};

View File

@ -40,6 +40,7 @@
/****
* #define DEBUG_CIRCLES 1
****/
#define DEBUG_CIRCLES 1
/*extern*/ RsGxsCircles* rsGxsCircles = nullptr;
@ -67,7 +68,7 @@ RsGxsCircleEvent::~RsGxsCircleEvent() = default;
* and GXS asks this service before forwarding any data.
*
* The CircleGroup contains:
* list of GxsId's
* list of invited GxsId's
* list of GxsCircleId's (subcircles also allowed).
*
* This service runs a background task to transform the CircleGroups
@ -75,14 +76,30 @@ RsGxsCircleEvent::~RsGxsCircleEvent() = default;
* These results are cached to provide GXS with quick access to the information.
* This involves:
* - fetching the GroupData via GXS.
* - querying the list of GxsId to see if they are known.
* (NB: this will cause caching of GxsId in p3IdService.
* - querying the list of GxsId to see if they are known (NB: this will cause caching of GxsId in p3IdService.
* - recursively loading subcircles to complete Circle definition.
* - saving the result into Cache.
*
* For Phase 1, we will only use the list of GxsIds. No subcircles will be allowed.
* Recursively determining membership via sub-circles is complex and needs more thought.
* The data-types for the full system, however, will be in-place.
*
* Circle Membership
* - Actual members of the circle are computed by intersecting the set of invited IDs with the set of IDs actually requesting membership.
* - To be a member, one therefore has to publish a membership message. To leave the circle, a new message is published accordingly.
*
* Circle Subscription system
* - Circles are subscribed only when we need to dispatch information about our own membership, or when we are admin of the circle.
* - Circle (group) membership is decided automatically. Not to be mixed up with whether or not to be a member of the circle, which is GUI based.
*
* Handling of old/dead circles
* - auto-subscription based on own membership requests should limit the spread of unwanted circles (such as when one adds all visible IDs into
* the invited list of a new circle. Such a circle would not be visible beyond friend nodes of the node creating that circle.
*
* - since this feature is new (in 0.6.6), there is already a bunch of unwanted circles. How we can get rid of them is not entirely clear.
* Indeed, once a node requests membership (and even later on denies it), it will have to remain subscribed to the circle group in order
* to ensure that this unsubscribe request keeps spreading from its actual source. A some point however, the circle msgs disappear, and
* therefore the circle will switch to unsubscribe automatically.
*/
#define CIRCLEREQ_CACHELOAD 0x0001
@ -1074,6 +1091,7 @@ RsGxsCircleCache::RsGxsCircleCache()
mLastUpdatedMembershipTS = 0 ;
mStatus = CircleEntryCacheStatus::NO_DATA_YET;
mAllIdsHere = false;
mDoIAuthorAMembershipMsg = false;
return;
}
@ -1286,7 +1304,7 @@ bool p3GxsCircles::cache_request_load(const RsGxsCircleId &id)
int32_t age = 0;
if (RsTickEvent::prev_event_ago(CIRCLE_EVENT_CACHELOAD, age) && age<MIN_CIRCLE_LOAD_GAP)
RsTickEvent::schedule_in(CIRCLE_EVENT_CACHELOAD, MIN_CIRCLE_LOAD_GAP - age);
RsTickEvent::schedule_in(CIRCLE_EVENT_CACHELOAD, MIN_CIRCLE_LOAD_GAP - age);
else
RsTickEvent::schedule_now(CIRCLE_EVENT_CACHELOAD);
@ -1406,8 +1424,6 @@ bool p3GxsCircles::cache_load_for_token(uint32_t token)
RsTickEvent::schedule_in(CIRCLE_EVENT_RELOADIDS, GXSID_LOAD_CYCLE, id.toStdString());
}
mShouldSendCacheUpdateNotification = true;
locked_checkCircleCacheForAutoSubscribe(cache);
}
return true;
@ -1505,8 +1521,6 @@ bool p3GxsCircles::cache_reloadids(const RsGxsCircleId &circleId)
// We can check for self inclusion in the circle right away, since own ids are always loaded.
// that allows to subscribe/unsubscribe uncomplete circles
locked_checkCircleCacheForAutoSubscribe(cache);
cache.mStatus = CircleEntryCacheStatus::CHECKING_MEMBERSHIP;
locked_checkCircleCacheForMembershipUpdate(cache);
@ -1537,8 +1551,7 @@ bool p3GxsCircles::checkCircleCache()
#endif
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
mCircleCache.applyToAllCachedEntries(*this,&p3GxsCircles::locked_checkCircleCacheForMembershipUpdate) ;
mCircleCache.applyToAllCachedEntries(*this,&p3GxsCircles::locked_checkCircleCacheForAutoSubscribe) ;
mCircleCache.applyToAllCachedEntries(*this,&p3GxsCircles::locked_checkCircleCacheForMembershipUpdate) ;
return true ;
}
@ -1555,11 +1568,13 @@ bool p3GxsCircles::locked_checkCircleCacheForMembershipUpdate(RsGxsCircleCache&
#ifdef DEBUG_CIRCLES
std::cerr << "Cache entry for circle " << cache.mCircleId << " needs a swab over membership requests. Re-scheduling it." << std::endl;
#endif
cache.mGroupStatus |= GXS_SERV::GXS_GRP_STATUS_UNPROCESSED; // forces processing of cache entry
uint32_t token;
RsGenExchange::setGroupStatusFlags(token, RsGxsGroupId(cache.mCircleId.toStdString()), 0, GXS_SERV::GXS_GRP_STATUS_UNPROCESSED);
// this should be called regularly
uint32_t token ;
RsTokReqOptions opts;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
std::list<RsGxsGroupId> grpIds ;
@ -1573,7 +1588,7 @@ bool p3GxsCircles::locked_checkCircleCacheForMembershipUpdate(RsGxsCircleCache&
/* We need to AutoSubscribe if the Circle is relevent to us */
bool p3GxsCircles::locked_checkCircleCacheForAutoSubscribe(RsGxsCircleCache &cache)
bool p3GxsCircles::locked_checkCircleCacheForAutoSubscribe(RsGxsCircleCache& cache)
{
#ifdef DEBUG_CIRCLES
std::cerr << "p3GxsCircles::locked_checkCircleCacheForAutoSubscribe() : "<< cache.mCircleId << std::endl;
@ -1615,73 +1630,70 @@ bool p3GxsCircles::locked_checkCircleCacheForAutoSubscribe(RsGxsCircleCache &cac
return false ;
}
bool in_admin_list = false ;
bool member_request = false ;
bool am_I_invited = false ;
for(std::list<RsGxsId>::const_iterator it(myOwnIds.begin());it!=myOwnIds.end() && (!in_admin_list) && (!member_request);++it)
for(std::list<RsGxsId>::const_iterator it(myOwnIds.begin());it!=myOwnIds.end() && (!am_I_invited);++it)
{
std::map<RsGxsId,RsGxsCircleMembershipStatus>::const_iterator it2 = cache.mMembershipStatus.find(*it) ;
if(it2 != cache.mMembershipStatus.end())
{
in_admin_list = in_admin_list || bool(it2->second.subscription_flags & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST) ;
member_request= member_request|| bool(it2->second.subscription_flags & GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED) ;
}
am_I_invited = am_I_invited || bool(it2->second.subscription_flags & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST) ;
}
bool am_I_admin( cache.mGroupSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) ;
bool am_I_admin( cache.mGroupSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) ;
bool do_I_have_a_msg( cache.mDoIAuthorAMembershipMsg );
#ifdef DEBUG_CIRCLES
std::cerr << " own ID in circle: " << in_admin_list << ", own subscribe request: " << member_request << ", am I admin?: " << am_I_admin << std::endl;
std::cerr << " own ID invited in circle: " << am_I_invited << ", membership msg author: " << do_I_have_a_msg << ", admin: " << am_I_admin << std::endl;
#endif
if(in_admin_list || member_request || am_I_admin)
{
uint32_t token, token2;
if(! (cache.mGroupSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED))
{
if(do_I_have_a_msg || am_I_admin)
{
if(! (cache.mGroupSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED))
{
#ifdef DEBUG_CIRCLES
/* we are part of this group - subscribe, clear unprocessed flag */
std::cerr << " I'm allowed in this circle => AutoSubscribing!" << std::endl;
/* we are part of this group - subscribe, clear unprocessed flag */
std::cerr << " either admin or have posted a subscribe/unsubscribe message => AutoSubscribing!" << std::endl;
#endif
RsGenExchange::subscribeToGroup(token, RsGxsGroupId(cache.mCircleId), true);
}
uint32_t token;
RsGenExchange::subscribeToGroup(token, RsGxsGroupId(cache.mCircleId), true);
mShouldSendCacheUpdateNotification = true;
}
#ifdef DEBUG_CIRCLES
else
std::cerr << " I'm allowed in this circle, and already subscribed." << std::endl;
else
std::cerr << " either admin or have posted a subscribe/unsubscribe message, already subscribed." << std::endl;
#endif
RsGenExchange::setGroupStatusFlags(token2, RsGxsGroupId(cache.mCircleId), 0, GXS_SERV::GXS_GRP_STATUS_UNPROCESSED);
cache.mGroupStatus &= ~GXS_SERV::GXS_GRP_STATUS_UNPROCESSED;
cache.mGroupStatus &= ~GXS_SERV::GXS_GRP_STATUS_UNPROCESSED;
mShouldSendCacheUpdateNotification = true;
return true;
}
return true;
}
else
{
/* we know all the peers - we are not part - we can flag as PROCESSED. */
uint32_t token,token2;
RsGenExchange::setGroupStatusFlags(token, RsGxsGroupId(cache.mCircleId.toStdString()), 0, GXS_SERV::GXS_GRP_STATUS_UNPROCESSED);
/* we know all the peers - we are not part - we can flag as PROCESSED. */
if(cache.mGroupSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED)
{
RsGenExchange::subscribeToGroup(token2, RsGxsGroupId(cache.mCircleId), false);
uint32_t token;
RsGenExchange::subscribeToGroup(token, RsGxsGroupId(cache.mCircleId), false);
mShouldSendCacheUpdateNotification = true;
#ifdef DEBUG_CIRCLES
std::cerr << " Not part of the group! Let's unsubscribe this circle of unfriendly Napoleons!" << std::endl;
std::cerr << " Neither admin nor subscription msg author! Let's unsubscribe this circle of unfriendly Napoleons!" << std::endl;
#endif
}
#ifdef DEBUG_CIRCLES
else
std::cerr << " Not part of the group, and not subscribed either." << std::endl;
std::cerr << " Neither admin nor subscription msg author! Not subscribed either." << std::endl;
#endif
cache.mGroupStatus &= ~GXS_SERV::GXS_GRP_STATUS_UNPROCESSED;
mShouldSendCacheUpdateNotification = true;
return true ;
}
#ifdef DEBUG_CIRCLES
std::cerr << " Marking the cache entry as processed." << std::endl;
#endif
uint32_t token2;
cache.mGroupStatus &= ~GXS_SERV::GXS_GRP_STATUS_UNPROCESSED;
RsGenExchange::setGroupStatusFlags(token2, RsGxsGroupId(cache.mCircleId), 0, GXS_SERV::GXS_GRP_STATUS_UNPROCESSED);
return true;
}
void p3GxsCircles::addCircleIdToList(const RsGxsCircleId &circleId, uint32_t circleType)
@ -1861,14 +1873,22 @@ bool p3GxsCircles::pushCircleMembershipRequest(
return false;
}
if(!getCirclesInfo(
std::list<RsGxsGroupId>{static_cast<RsGxsGroupId>(circle_id)},
RS_DEFAULT_STORAGE_PARAM(std::vector<RsGxsCircleGroup>) ))
if(!getCirclesInfo( std::list<RsGxsGroupId>{static_cast<RsGxsGroupId>(circle_id)}, RS_DEFAULT_STORAGE_PARAM(std::vector<RsGxsCircleGroup>) ))
{
RsErr() << __PRETTY_FUNCTION__ << " Cannot generate membership request "
<< "from unknown circle: " << circle_id << std::endl;
RsErr() << __PRETTY_FUNCTION__ << " Cannot generate membership request from unknown circle: " << circle_id << std::endl;
return false;
}
// If the circle is not subscribed, then subscribe, whatever the subscription type. Indeed, if we publish a msg, even a msg for
// unsubscribing, we need to have a subscribed group first.
uint32_t token ;
RsGenExchange::subscribeToGroup(token, RsGxsGroupId(circle_id), true);
if(waitToken(token) != RsTokenService::COMPLETE)
{
std::cerr << __PRETTY_FUNCTION__ << " Could not subscribe to Circle group." << std::endl;
return false;
}
// Create a subscribe item
@ -1898,10 +1918,6 @@ bool p3GxsCircles::pushCircleMembershipRequest(
std::cerr << " AuthorId : " << s->meta.mAuthorId << std::endl;
std::cerr << " ThreadId : " << s->meta.mThreadId << std::endl;
#endif
uint32_t token ;
if(request_type == RsGxsCircleSubscriptionType::SUBSCRIBE)
RsGenExchange::subscribeToGroup(token, RsGxsGroupId(circle_id), true);
RsGenExchange::publishMsg(token, s);
@ -1920,6 +1936,90 @@ bool p3GxsCircles::cancelCircleMembership(const RsGxsId& own_gxsid,const RsGxsCi
return pushCircleMembershipRequest(own_gxsid,circle_id,RsGxsCircleSubscriptionType::UNSUBSCRIBE) ;
}
bool p3GxsCircles::locked_processMembershipMessages(RsGxsCircleCache& cache, const std::vector<RsGxsMsgItem*>& items, GxsMsgReq& messages_to_delete, const std::set<RsGxsId> &own_ids)
{
#ifdef DEBUG_CIRCLES
std::cerr << " Circle found in cache!" << std::endl;
std::cerr << " Retrieving messages..." << std::endl;
#endif
cache.mDoIAuthorAMembershipMsg = false; // default
for(uint32_t i=0;i<items.size();++i)
{
#ifdef DEBUG_CIRCLES
std::cerr << " Group ID: " << items[i]->meta.mGroupId << ", Message ID: " << items[i]->meta.mMsgId << ", thread ID: " << items[i]->meta.mThreadId << ", author: " << items[i]->meta.mAuthorId << ": " ;
#endif
RsGxsCircleSubscriptionRequestItem *item = dynamic_cast<RsGxsCircleSubscriptionRequestItem*>(items[i]) ;
if(item == NULL)
{
std::cerr << " (EE) item is not a RsGxsCircleSubscriptionRequestItem. Weird. Scheduling for deletion." << std::endl;
messages_to_delete[RsGxsGroupId(cache.mCircleId)].insert(item->meta.mMsgId);
continue ;
}
RsGxsCircleMembershipStatus& info(cache.mMembershipStatus[item->meta.mAuthorId]) ;
#ifdef DEBUG_CIRCLES
std::cerr << " " << time(NULL) - item->time_stamp << " seconds ago, " ;
#endif
if(info.last_subscription_TS <= item->time_stamp) // the <= here allows to make sure we update the flags is something happenned
{
info.last_subscription_TS = item->time_stamp ;
if(item->subscription_type == RsGxsCircleSubscriptionType::SUBSCRIBE)
info.subscription_flags |= GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED;
else if(item->subscription_type == RsGxsCircleSubscriptionType::UNSUBSCRIBE)
info.subscription_flags &= ~GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED;
else
std::cerr << " (EE) unknown subscription order type: " << static_cast<uint32_t>(item->subscription_type) ;
mShouldSendCacheUpdateNotification = true;
#ifdef DEBUG_CIRCLES
std::cerr << " UPDATING status to " << std::hex << info.subscription_flags << std::dec << std::endl;
#endif
if(own_ids.end() != own_ids.find(item->meta.mAuthorId)) // we have at least one subscribe/unsubscribe message. So we update the flag accordingly.
cache.mDoIAuthorAMembershipMsg = true;
}
else if(info.last_subscription_TS > item->time_stamp)
std::cerr << " Too old: item->TS=" << item->time_stamp << ", last_subscription_TS=" << info.last_subscription_TS << ". IGNORING." << std::endl;
}
// now do another sweep and remove all msgs that are older than the latest
#ifdef DEBUG_CIRCLES
std::cerr << " Cleaning older messages..." << std::endl;
#endif
for(uint32_t i=0;i<items.size();++i)
{
RsGxsCircleMembershipStatus& info(cache.mMembershipStatus[items[i]->meta.mAuthorId]) ;
RsGxsCircleSubscriptionRequestItem *item = dynamic_cast<RsGxsCircleSubscriptionRequestItem*>(items[i]) ;
if(item && info.last_subscription_TS > item->time_stamp)
{
#ifdef DEBUG_CIRCLES
std::cerr << " " << item->meta.mMsgId << ": Older than last known (" << (long int)info.last_subscription_TS - (long int)item->time_stamp << " seconds before): deleting." << std::endl;
#endif
messages_to_delete[RsGxsGroupId(cache.mCircleId)].insert(item->meta.mMsgId) ;
}
}
#ifdef DEBUG_CIRCLES
std::cerr << " Cleaning older messages..." << std::endl;
#endif
cache.mLastUpdatedMembershipTS = time(NULL) ;
cache.mStatus = CircleEntryCacheStatus::UP_TO_DATE;
cache.mLastUpdateTime = time(NULL);
mShouldSendCacheUpdateNotification = true;
return true;
}
bool p3GxsCircles::processMembershipRequests(uint32_t token)
{
// Go through membership request messages and process them according to the following rule:
@ -1934,111 +2034,59 @@ bool p3GxsCircles::processMembershipRequests(uint32_t token)
if(!RsGenExchange::getMsgData(token, msgItems))
{
std::cerr << "(EE) Cannot get msg data for circle. Something's weird." << std::endl;
return false;
std::cerr << "(EE) Cannot get msg data for circle. Something's weird." << std::endl;
return false;
}
std::list<RsGxsId> own_ids ;
rsIdentity->getOwnIds(own_ids);
std::set<RsGxsId> own_ids_set;
for(auto& id:own_ids)
own_ids_set.insert(id);
GxsMsgReq messages_to_delete ;
for(GxsMsgDataMap::const_iterator it(msgItems.begin());it!=msgItems.end();++it)
{
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
{
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
#ifdef DEBUG_CIRCLES
std::cerr << " Circle ID: " << it->first << std::endl;
std::cerr << " Circle ID: " << it->first << std::endl;
#endif
// Find the circle ID in cache and process the list of messages to keep the latest order in time.
// Find the circle ID in cache and process the list of messages to keep the latest order in time.
RsGxsCircleId circle_id(it->first);
RsGxsCircleCache& cache( mCircleCache[circle_id] );
RsGxsCircleCache& cache( mCircleCache[circle_id] );
// First process membership messages
#ifdef DEBUG_CIRCLES
std::cerr << " Circle found in cache!" << std::endl;
std::cerr << " Retrieving messages..." << std::endl;
std::cerr << " Processing membership messages..." << std::endl;
#endif
for(uint32_t i=0;i<it->second.size();++i)
{
locked_processMembershipMessages(cache,it->second,messages_to_delete,own_ids_set);
#ifdef DEBUG_CIRCLES
std::cerr << " Group ID: " << it->second[i]->meta.mGroupId << ", Message ID: " << it->second[i]->meta.mMsgId << ", thread ID: " << it->second[i]->meta.mThreadId << ", author: " << it->second[i]->meta.mAuthorId << ": " ;
std::cerr << " Now checking for auto-subscribe..." << std::endl;
#endif
RsGxsCircleSubscriptionRequestItem *item = dynamic_cast<RsGxsCircleSubscriptionRequestItem*>(it->second[i]) ;
if(item == NULL)
{
std::cerr << " (EE) item is not a RsGxsCircleSubscriptionRequestItem. Weird. Scheduling for deletion." << std::endl;
messages_to_delete[RsGxsGroupId(circle_id)].insert(it->second[i]->meta.mMsgId);
continue ;
}
RsGxsCircleMembershipStatus& info(cache.mMembershipStatus[item->meta.mAuthorId]) ;
#ifdef DEBUG_CIRCLES
std::cerr << " " << time(NULL) - item->time_stamp << " seconds ago, " ;
#endif
if(info.last_subscription_TS <= item->time_stamp) // the <= here allows to make sure we update the flags is something happenned
{
info.last_subscription_TS = item->time_stamp ;
if(item->subscription_type == RsGxsCircleSubscriptionType::SUBSCRIBE)
info.subscription_flags |= GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED;
else if(item->subscription_type == RsGxsCircleSubscriptionType::UNSUBSCRIBE)
info.subscription_flags &= ~GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED;
else
std::cerr << " (EE) unknown subscription order type: " << static_cast<uint32_t>(item->subscription_type) ;
mShouldSendCacheUpdateNotification = true;
#ifdef DEBUG_CIRCLES
std::cerr << " UPDATING status to " << std::hex << info.subscription_flags << std::dec << std::endl;
#endif
}
else if(info.last_subscription_TS > item->time_stamp)
std::cerr << " Too old: item->TS=" << item->time_stamp << ", last_subscription_TS=" << info.last_subscription_TS << ". IGNORING." << std::endl;
}
// now do another sweep and remove all msgs that are older than the latest
#ifdef DEBUG_CIRCLES
std::cerr << " Cleaning old messages..." << std::endl;
#endif
for(uint32_t i=0;i<it->second.size();++i)
{
RsGxsCircleMembershipStatus& info(cache.mMembershipStatus[it->second[i]->meta.mAuthorId]) ;
RsGxsCircleSubscriptionRequestItem *item = dynamic_cast<RsGxsCircleSubscriptionRequestItem*>(it->second[i]) ;
if(item && info.last_subscription_TS > item->time_stamp)
{
#ifdef DEBUG_CIRCLES
std::cerr << " " << item->meta.mMsgId << ": Older than last known (" << (long int)info.last_subscription_TS - (long int)item->time_stamp << " seconds before): deleting." << std::endl;
#endif
messages_to_delete[RsGxsGroupId(circle_id)].insert(item->meta.mMsgId) ;
}
}
cache.mLastUpdatedMembershipTS = time(NULL) ;
cache.mStatus = CircleEntryCacheStatus::UP_TO_DATE;
cache.mLastUpdateTime = time(NULL);
mShouldSendCacheUpdateNotification = true;
}
locked_checkCircleCacheForAutoSubscribe(cache);
}
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
uint32_t token2;
RsGenExchange::deleteMsgs(token2,messages_to_delete);
return true ;
}
//====================================================================================//
// DEBUG STUFF //
//====================================================================================//
bool p3GxsCircles::debug_dumpCacheEntry(RsGxsCircleCache& cache)
{
std::cerr << " Circle: " << cache.mCircleId << " status: " << cache.mStatus << " MembershipTS: " << cache.mLastUpdatedMembershipTS
<< " UpdateTS: " << cache.mLastUpdateTime << " All Ids here: " << cache.mAllIdsHere << std::endl;
std::cerr << " Circle: " << cache.mCircleId
<< " status: " << static_cast<int>(cache.mStatus)
<< " MembershipTS: " << cache.mLastUpdatedMembershipTS
<< " UpdateTS: " << cache.mLastUpdateTime
<< " All Ids here: " << cache.mAllIdsHere
<< " Has own msg: " << cache.mDoIAuthorAMembershipMsg << std::endl;
return true;
}

View File

@ -128,7 +128,7 @@ public:
uint32_t subscription_flags ; // combination of GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST and GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED
};
enum CircleEntryCacheStatus: uint8_t {
enum class CircleEntryCacheStatus: uint8_t {
UNKNOWN = 0x00, // Used to detect uninitialized memory
NO_DATA_YET = 0x01, // Used in the constuctor
LOADING = 0x02, // When the token request to load cache has been sent and no data is present
@ -167,17 +167,18 @@ public:
bool mIsExternal;
RsGxsCircleId mRestrictedCircleId ; // circle ID that circle is restricted to.
uint32_t mGroupStatus;
uint32_t mGroupSubscribeFlags;
bool mDoIAuthorAMembershipMsg; // Do I have a subscribe/unsubscribe message in the circle group? Will be used to determine if we subscribe to the group or not
uint32_t mGroupStatus; // Copy of the group status from the GXS group.
uint32_t mGroupSubscribeFlags; // Subscribe flags of the group.
#ifdef SUBSCIRCLES
std::set<RsGxsCircleId> mUnprocessedCircles;
std::set<RsGxsCircleId> mProcessedCircles;
#endif
std::map<RsGxsId,RsGxsCircleMembershipStatus> mMembershipStatus;
std::map<RsGxsId,RsGxsCircleMembershipStatus> mMembershipStatus; // Membership status of each ID cited in the group (including the ones posting a message)
std::set<RsGxsId> mAllowedGxsIds; // IDs that are allowed in the circle and have requested membership. This is the official members list.
std::set<RsPgpId> mAllowedNodes;
std::set<RsGxsId> mAllowedGxsIds; // IDs that are allowed in the circle and have requested membership. This is the official members list.
std::set<RsPgpId> mAllowedNodes; // List of friend nodes allowed in the circle (local circles only)
RsPeerId mOriginator ; // peer who sent the data, in case we need to ask for ids
};
@ -338,7 +339,8 @@ public:
bool checkCircleCache();
bool locked_checkCircleCacheForAutoSubscribe(RsGxsCircleCache &cache);
bool locked_processLoadingCacheEntry(RsGxsCircleCache &cache);
bool locked_processMembershipMessages(RsGxsCircleCache& cache,const std::vector<RsGxsMsgItem*>& items, GxsMsgReq& messages_to_delete,const std::set<RsGxsId>& own_ids);
bool locked_processLoadingCacheEntry(RsGxsCircleCache &cache);
bool locked_checkCircleCacheForMembershipUpdate(RsGxsCircleCache &cache);
p3IdService *mIdentities; // Needed for constructing Circle Info,