made group notifications separate so that they can be treated more easily and added group item to new_group notifications, to allow more GUI notifications

This commit is contained in:
csoler 2020-05-01 00:00:13 +02:00
parent 767440afc5
commit d32daaa111
No known key found for this signature in database
GPG Key ID: 7BCA522266C0804C
8 changed files with 293 additions and 375 deletions

View File

@ -236,14 +236,19 @@ void RsGenExchange::tick()
if (!grpIds.empty())
{
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PROCESSED, false);
gc->mGrpIdList = grpIds;
for(auto& groupId:grpIds)
{
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_MESSAGES_DELETED, false);
gc->mGroupId = groupId;
#ifdef GEN_EXCH_DEBUG
std::cerr << " adding the following grp ids to notification: " << std::endl;
for(std::list<RsGxsGroupId>::const_iterator it(grpIds.begin());it!=grpIds.end();++it)
std::cerr << " " << *it << std::endl;
std::cerr << " adding the following grp ids to notification: " << std::endl;
for(std::list<RsGxsGroupId>::const_iterator it(grpIds.begin());it!=grpIds.end();++it)
std::cerr << " " << *it << std::endl;
#endif
mNotifications.push_back(gc);
mNotifications.push_back(gc);
}
// also notify the network exchange service that these groups no longer exist.
@ -1686,7 +1691,8 @@ void RsGenExchange::notifyReceivePublishKey(const RsGxsGroupId &grpId)
RS_STACK_MUTEX(mGenMtx);
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY, true);
gc->mGrpIdList.push_back(grpId);
gc->mGroupId = grpId;
mNotifications.push_back(gc);
}
@ -1695,7 +1701,8 @@ void RsGenExchange::notifyChangedGroupStats(const RsGxsGroupId &grpId)
RS_STACK_MUTEX(mGenMtx);
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_STATISTICS_CHANGED, false);
gc->mGrpIdList.push_back(grpId);
gc->mGroupId = grpId;
mNotifications.push_back(gc);
}
@ -2101,11 +2108,13 @@ void RsGenExchange::processGrpMetaChanges()
}
}
if(!grpChanged.empty())
for(auto& groupId:grpChanged)
{
RS_STACK_MUTEX(mGenMtx);
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PROCESSED, true);
gc->mGrpIdList = grpChanged;
gc->mGroupId = groupId;
mNotifications.push_back(gc);
#ifdef GEN_EXCH_DEBUG
std::cerr << " adding the following grp ids to notification: " << std::endl;
@ -2496,15 +2505,17 @@ void RsGenExchange::processGroupDelete()
grpDeleted.push_back(note.second);
}
if(!grpDeleted.empty())
for(auto& groupId:grpDeleted)
{
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PUBLISHED, false);
gc->mGrpIdList = grpDeleted;
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_GROUP_DELETED, false);
gc->mGroupId = groupId;
mNotifications.push_back(gc);
}
mGroupDeletePublish.clear();
}
void RsGenExchange::processMessageDelete()
{
RS_STACK_MUTEX(mGenMtx) ;
@ -2523,31 +2534,29 @@ void RsGenExchange::processMessageDelete()
mDataStore->removeMsgs( (*vit).mMsgs );
}
// std::list<RsGxsGroupId> grpDeleted;
// std::map<uint32_t, GrpNote>::iterator mit = toNotify.begin();
// for(; mit != toNotify.end(); ++mit)
// {
// GrpNote& note = mit->second;
// uint8_t status = note.first ? RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE
// : RsTokenService::GXS_REQUEST_V2_STATUS_FAILED;
//
// mGrpNotify.insert(std::make_pair(mit->first, note.second));
// mDataAccess->updatePublicRequestStatus(mit->first, status);
//
// if(note.first)
// grpDeleted.push_back(note.second);
// }
#warning csoler: TODO: notify for deleted messages
#ifdef SUSPENDED
std::list<RsGxsGroupId> grpDeleted;
std::map<uint32_t, GrpNote>::iterator mit = toNotify.begin();
for(; mit != toNotify.end(); ++mit)
{
GrpNote& note = mit->second;
uint8_t status = note.first ? RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE
: RsTokenService::GXS_REQUEST_V2_STATUS_FAILED;
for(uint32_t i=0;i<mMsgDeletePublish.size();++i)
for(auto it(mMsgDeletePublish[i].mMsgs.begin());it!=mMsgDeletePublish[i].mMsgs.end();++it)
{
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_MESSAGES_DELETED, false);
gc->mGroupId = it->first;
mGrpNotify.insert(std::make_pair(mit->first, note.second));
mDataAccess->updatePublicRequestStatus(mit->first, status);
if(note.first)
grpDeleted.push_back(note.second);
}
if(!grpDeleted.empty())
{
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PUBLISH, false);
gc->mGrpIdList = grpDeleted;
mNotifications.push_back(gc);
}
#endif
mNotifications.push_back(gc);
}
mMsgDeletePublish.clear();
}
@ -2807,10 +2816,12 @@ void RsGenExchange::publishGrps()
grpChanged.push_back(note.second);
}
if(!grpChanged.empty())
for(auto& groupId:grpChanged)
{
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_NEW, true);
gc->mGrpIdList = grpChanged;
gc->mGroupId = groupId;
mNotifications.push_back(gc);
#ifdef GEN_EXCH_DEBUG
std::cerr << " adding the following grp ids to notification: " << std::endl;
@ -3207,11 +3218,18 @@ void RsGenExchange::processRecvdGroups()
vit = tmp ;
}
if(!grpIds.empty())
if(!grps_to_store.empty())
{
RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_NEW, false);
c->mGrpIdList = grpIds;
mNotifications.push_back(c);
for(auto Grp:grps_to_store)
{
RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_NEW, false);
c->mGroupId = Grp->grpId;
c->mNewGroupItem = dynamic_cast<RsGxsGrpItem*>(mSerialiser->deserialise(Grp->grp.bin_data,&Grp->grp.bin_len));
mNotifications.push_back(c);
}
mDataStore->storeGroup(grps_to_store);
#ifdef GEN_EXCH_DEBUG
std::cerr << " adding the following grp ids to notification: " << std::endl;
@ -3286,7 +3304,7 @@ void RsGenExchange::performUpdateValidation()
// Now prepare notification of the client
RsGxsGroupUpdate *c = new RsGxsGroupUpdate();
RsGxsGroupChange *c = new RsGxsGroupChange(RsGxsNotify::TYPE_UPDATED,false);
c->mNewGroupItem = dynamic_cast<RsGxsGrpItem*>(mSerialiser->deserialise(gu.newGrp->grp.bin_data,&gu.newGrp->grp.bin_len));
c->mNewGroupItem->meta = *gu.newGrp->metaData; // gu.newGrp will be deleted because mDataStore will destroy it on update

View File

@ -38,6 +38,8 @@ struct RsGxsNotify
TYPE_RECEIVED_DISTANT_SEARCH_RESULTS = 0x05,
TYPE_STATISTICS_CHANGED = 0x06,
TYPE_UPDATED = 0x07,
TYPE_MESSAGES_DELETED = 0x08,
TYPE_GROUP_DELETED = 0x09,
};
virtual ~RsGxsNotify() {}
@ -50,29 +52,22 @@ struct RsGxsNotify
class RsGxsGroupChange : public RsGxsNotify
{
public:
RsGxsGroupChange(NotifyType type, bool metaChange) : mNotifyType(type), mMetaChange(metaChange) {}
std::list<RsGxsGroupId> mGrpIdList;
RsGxsGroupChange(NotifyType type, bool metaChange) : mNewGroupItem(nullptr),mOldGroupItem(nullptr), mNotifyType(type), mMetaChange(metaChange) {}
virtual ~RsGxsGroupChange() { delete mOldGroupItem; delete mNewGroupItem ; }
NotifyType getType() override { return mNotifyType;}
bool metaChange() { return mMetaChange; }
RsGxsGroupId mGroupId; // Group id of the group we're talking about. When the group is deleted, it's useful to know which group
// that was although there is no pointers to the actual group data anymore.
RsGxsGrpItem *mNewGroupItem; // Valid when a group has changed, or a new group is received.
RsGxsGrpItem *mOldGroupItem; // only valid when mNotifyType is TYPE_UPDATED
protected:
NotifyType mNotifyType;
bool mMetaChange;
};
class RsGxsGroupUpdate : public RsGxsNotify
{
public:
RsGxsGroupUpdate() : mOldGroupItem(nullptr),mNewGroupItem(nullptr) {}
virtual ~RsGxsGroupUpdate() { delete mOldGroupItem; delete mNewGroupItem ; }
RsGxsGrpItem *mOldGroupItem;
RsGxsGrpItem *mNewGroupItem;
NotifyType getType() override { return RsGxsNotify::TYPE_UPDATED;}
};
class RsGxsDistantSearchResultChange: public RsGxsNotify
{
public:

View File

@ -656,6 +656,8 @@ void p3GxsTrans::notifyChanges(std::vector<RsGxsNotify*>& changes)
#ifdef DEBUG_GXSTRANS
std::cout << "p3GxsTrans::notifyChanges(...)" << std::endl;
#endif
std::list<RsGxsGroupId> grps_to_request;
for( auto it = changes.begin(); it != changes.end(); ++it )
{
RsGxsGroupChange* grpChange = dynamic_cast<RsGxsGroupChange *>(*it);
@ -666,7 +668,7 @@ void p3GxsTrans::notifyChanges(std::vector<RsGxsNotify*>& changes)
#ifdef DEBUG_GXSTRANS
std::cout << "p3GxsTrans::notifyChanges(...) grpChange" << std::endl;
#endif
requestGroupsData(&(grpChange->mGrpIdList));
grps_to_request.push_back(grpChange->mGroupId);
}
else if(msgChange)
{
@ -698,6 +700,9 @@ void p3GxsTrans::notifyChanges(std::vector<RsGxsNotify*>& changes)
}
delete *it;
}
if(!grps_to_request.empty())
requestGroupsData(&grps_to_request);
}
uint32_t p3GxsTrans::AuthenPolicy()

View File

@ -304,71 +304,52 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
{
case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed
{
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for (git = grpList.begin(); git != grpList.end(); ++git)
{
auto ev = std::make_shared<RsGxsChannelEvent>();
ev->mChannelGroupId = *git;
ev->mChannelEventCode = RsChannelEventCode::SUBSCRIBE_STATUS_CHANGED;
rsEvents->postEvent(ev);
}
auto ev = std::make_shared<RsGxsChannelEvent>();
ev->mChannelGroupId = grpChange->mGroupId;
ev->mChannelEventCode = RsChannelEventCode::SUBSCRIBE_STATUS_CHANGED;
rsEvents->postEvent(ev);
}
break;
case RsGxsNotify::TYPE_STATISTICS_CHANGED:
{
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for (git = grpList.begin(); git != grpList.end(); ++git)
{
auto ev = std::make_shared<RsGxsChannelEvent>();
ev->mChannelGroupId = *git;
ev->mChannelEventCode = RsChannelEventCode::STATISTICS_CHANGED;
rsEvents->postEvent(ev);
}
}
{
auto ev = std::make_shared<RsGxsChannelEvent>();
ev->mChannelGroupId = grpChange->mGroupId;
ev->mChannelEventCode = RsChannelEventCode::STATISTICS_CHANGED;
rsEvents->postEvent(ev);
}
break;
case RsGxsNotify::TYPE_PUBLISHED:
case RsGxsNotify::TYPE_RECEIVED_NEW:
{
/* group received */
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
RS_STACK_MUTEX(mKnownChannelsMutex);
for (git = grpList.begin(); git != grpList.end(); ++git)
{
if(mKnownChannels.find(*git) == mKnownChannels.end())
{
mKnownChannels.insert(std::make_pair(*git,time(NULL))) ;
IndicateConfigChanged();
auto ev = std::make_shared<RsGxsChannelEvent>();
ev->mChannelGroupId = *git;
ev->mChannelEventCode = RsChannelEventCode::NEW_CHANNEL;
rsEvents->postEvent(ev);
}
else
std::cerr << "(II) Not notifying already known channel " << *git << std::endl;
RS_STACK_MUTEX(mKnownChannelsMutex);
if(mKnownChannels.find(grpChange->mGroupId) == mKnownChannels.end())
{
mKnownChannels.insert(std::make_pair(grpChange->mGroupId,time(NULL))) ;
IndicateConfigChanged();
auto ev = std::make_shared<RsGxsChannelEvent>();
ev->mChannelGroupId = grpChange->mGroupId;
ev->mChannelEventCode = RsChannelEventCode::NEW_CHANNEL;
rsEvents->postEvent(ev);
}
break;
else
std::cerr << "(II) Not notifying already known channel " << grpChange->mGroupId << std::endl;
}
break;
case RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY:
{
/* group received */
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for (git = grpList.begin(); git != grpList.end(); ++git)
{
auto ev = std::make_shared<RsGxsChannelEvent>();
ev->mChannelGroupId = *git;
ev->mChannelEventCode = RsChannelEventCode::RECEIVED_PUBLISH_KEY;
auto ev = std::make_shared<RsGxsChannelEvent>();
ev->mChannelGroupId = grpChange->mGroupId;
ev->mChannelEventCode = RsChannelEventCode::RECEIVED_PUBLISH_KEY;
rsEvents->postEvent(ev);
}
rsEvents->postEvent(ev);
}
break;

View File

@ -535,7 +535,6 @@ void p3GxsCircles::notifyChanges(std::vector<RsGxsNotify *> &changes)
for(auto it = changes.begin(); it != changes.end(); ++it)
{
RsGxsGroupChange *groupChange = dynamic_cast<RsGxsGroupChange *>(*it);
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(*it);
RsGxsNotify *c = *it;
@ -581,93 +580,127 @@ void p3GxsCircles::notifyChanges(std::vector<RsGxsNotify *> &changes)
}
}
RsGxsGroupChange *groupChange = dynamic_cast<RsGxsGroupChange *>(*it);
/* add groups to ExternalIdList (Might get Personal Circles here until NetChecks in place) */
if (groupChange && !groupChange->metaChange())
{
#ifdef DEBUG_CIRCLES
std::cerr << " Found Group Change Notification" << std::endl;
#endif
for(std::list<RsGxsGroupId>::iterator git = groupChange->mGrpIdList.begin(); git != groupChange->mGrpIdList.end(); ++git)
{
#ifdef DEBUG_CIRCLES
std::cerr << " Incoming Group: " << *git << ". Forcing cache load." << std::endl;
#endif
// for new circles we need to add them to the list.
// we don't know the type of this circle here
// original behavior was to add all ids to the external ids list
addCircleIdToList(RsGxsCircleId(*git), 0);
// reset the cached circle data for this id
{
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
mCircleCache.erase(RsGxsCircleId(*git));
mCacheUpdated = true;
}
}
}
if(groupChange)
if (groupChange)
{
std::list<RsGxsId> own_ids;
rsIdentity->getOwnIds(own_ids);
const RsGxsGroupId *git(&groupChange->mGroupId);
for(std::list<RsGxsGroupId>::const_iterator git(groupChange->mGrpIdList.begin());git!=groupChange->mGrpIdList.end();++git)
if(!groupChange->metaChange())
{
#ifdef DEBUG_CIRCLES
std::cerr << " forcing cache loading for circle " << *git << " in order to trigger subscribe update." << std::endl;
std::cerr << " Found Group Change Notification" << std::endl;
#endif
//for(std::list<RsGxsGroupId>::iterator git = groupChange->mGrpIdList.begin(); git != groupChange->mGrpIdList.end(); ++git)
{
#ifdef DEBUG_CIRCLES
std::cerr << " Incoming Group: " << *git << ". Forcing cache load." << std::endl;
#endif
#ifdef TODO
// This code will not work: we would like to detect changes in the circle data that reflects the fact that one of the
// owned GXS ids is invited. But there's no way to compare the old circle data to the new if cache has to be updated.
// For this we need to add the old metadata and group data in the RsGxsGroupChange structure and account for it.
// for new circles we need to add them to the list.
// we don't know the type of this circle here
// original behavior was to add all ids to the external ids list
if(rsEvents && (c->getType() == RsGxsNotify::TYPE_RECEIVED_NEW) )
{
RsGxsCircleId circle_id(*git);
force_cache_reload(circle_id);
addCircleIdToList(RsGxsCircleId(*git), 0);
RsGxsCircleDetails details;
getCircleDetails(circle_id,details);
// We check that the change corresponds to one of our own ids. Since we do not know what the change is, we notify
// for whatever is different from what is currently known. Other ids, that get invited only trigger a notification when the
// ID also accepts the invitation, so it becomes a member of the circle.
for(auto own_id: own_ids)
// reset the cached circle data for this id
{
auto it = details.mSubscriptionFlags.find(own_id);
if(it == details.mSubscriptionFlags.end())
continue;
bool invited ( it->second & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST );
bool subscrb ( it->second & GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED );
if(std::find(details.mAllowedGxsIds.begin(),details.mAllowedGxsIds.end(),id) != details.mAllowedGxsIds.end() && !me_in_circle)
{
auto ev = std::make_shared<RsGxsCircleEvent>();
ev->mType = RsGxsCircleEvent::CIRCLE_MEMBERSHIP_INVITE;
ev->mCircleId = circle_id;
ev->mGxsId = ;
rsEvents->sendEvent(ev);
}
RsStackMutex stack(mCircleMtx); /********** STACK LOCKED MTX ******/
mCircleCache.erase(RsGxsCircleId(*git));
mCacheUpdated = true;
}
}
#endif
}
if(rsEvents && (c->getType() == RsGxsNotify::TYPE_RECEIVED_NEW|| c->getType() == RsGxsNotify::TYPE_PUBLISHED) )
if(rsEvents)
{
std::list<RsGxsId> own_ids_lst;
rsIdentity->getOwnIds(own_ids_lst,false); // retrieve own identities
std::set<RsGxsId> own_ids;
for(auto& id:own_ids_lst)
own_ids.insert(id); // put them in a std::set for O(log(n)) search
if(c->getType() == RsGxsNotify::TYPE_RECEIVED_NEW|| c->getType() == RsGxsNotify::TYPE_PUBLISHED)
{
auto ev = std::make_shared<RsGxsCircleEvent>();
ev->mCircleId = RsGxsCircleId(*git);
ev->mCircleEventType = RsGxsCircleEventCode::NEW_CIRCLE;
rsEvents->postEvent(ev);
// we also need to look into invitee list here!
RsGxsCircleGroupItem *new_circle_grp_item = dynamic_cast<RsGxsCircleGroupItem*>(groupChange->mNewGroupItem);
std::list<RsGxsId> added_identities;
for(auto& gxs_id: new_circle_grp_item->gxsIdSet.ids)
if(own_ids.find(gxs_id)!=own_ids.end())
added_identities.push_back(gxs_id);
for(auto& gxs_id:added_identities)
{
auto ev = std::make_shared<RsGxsCircleEvent>();
ev->mCircleEventType = RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_INVITE;
ev->mCircleId = RsGxsCircleId(*git);
ev->mGxsId = gxs_id;
rsEvents->sendEvent(ev);
}
}
else if(c->getType()==RsGxsNotify::TYPE_UPDATED)
{
// Happens when the group data has changed. In this case we need to analyse the old and new group in order to detect possible notifications for clients
RsGxsCircleGroupItem *old_circle_grp_item = dynamic_cast<RsGxsCircleGroupItem*>(groupChange->mOldGroupItem);
RsGxsCircleGroupItem *new_circle_grp_item = dynamic_cast<RsGxsCircleGroupItem*>(groupChange->mNewGroupItem);
const RsGxsCircleId circle_id ( old_circle_grp_item->meta.mGroupId );
if(old_circle_grp_item == nullptr || new_circle_grp_item == nullptr)
{
RsErr() << __PRETTY_FUNCTION__ << " received GxsGroupUpdate item with mOldGroup and mNewGroup not of type RsGxsCircleGroupItem. This is inconsistent!" << std::endl;
delete groupChange;
continue;
}
// First of all, we check if there is a difference between the old and new list of invited members
std::list<RsGxsId> added_identities, removed_identities;
for(auto& gxs_id: new_circle_grp_item->gxsIdSet.ids)
if(old_circle_grp_item->gxsIdSet.ids.find(gxs_id) == old_circle_grp_item->gxsIdSet.ids.end() && own_ids.find(gxs_id)!=own_ids.end())
added_identities.push_back(gxs_id);
for(auto& gxs_id: old_circle_grp_item->gxsIdSet.ids)
if(new_circle_grp_item->gxsIdSet.ids.find(gxs_id) == old_circle_grp_item->gxsIdSet.ids.end() && own_ids.find(gxs_id)!=own_ids.end())
removed_identities.push_back(gxs_id);
for(auto& gxs_id:added_identities)
{
auto ev = std::make_shared<RsGxsCircleEvent>();
ev->mCircleEventType = RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_INVITE;
ev->mCircleId = circle_id;
ev->mGxsId = gxs_id;
rsEvents->sendEvent(ev);
}
for(auto& gxs_id:removed_identities)
{
auto ev = std::make_shared<RsGxsCircleEvent>();
ev->mCircleEventType = RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_REVOKED;
ev->mCircleId = circle_id;
ev->mGxsId = gxs_id;
rsEvents->sendEvent(ev);
}
}
// reset circle from cache since the number of invitee may have changed.
{
@ -679,64 +712,6 @@ void p3GxsCircles::notifyChanges(std::vector<RsGxsNotify *> &changes)
}
}
RsGxsGroupUpdate *grpUpdate = dynamic_cast<RsGxsGroupUpdate*>(*it);
if (grpUpdate && rsEvents)
{
// Happens when the group data has changed. In this case we need to analyse the old and new group in order to detect possible notifications for clients
RsGxsCircleGroupItem *old_circle_grp_item = dynamic_cast<RsGxsCircleGroupItem*>(grpUpdate->mOldGroupItem);
RsGxsCircleGroupItem *new_circle_grp_item = dynamic_cast<RsGxsCircleGroupItem*>(grpUpdate->mNewGroupItem);
const RsGxsCircleId circle_id ( old_circle_grp_item->meta.mGroupId );
if(old_circle_grp_item == nullptr || new_circle_grp_item == nullptr)
{
RsErr() << __PRETTY_FUNCTION__ << " received GxsGroupUpdate item with mOldGroup and mNewGroup not of type RsGxsCircleGroupItem. This is inconsistent!" << std::endl;
delete grpUpdate;
continue;
}
// First of all, we check if there is a difference between the old and new list of invited members
std::list<RsGxsId> added_identities, removed_identities;
std::list<RsGxsId> own_ids_lst;
rsIdentity->getOwnIds(own_ids_lst,false); // retrieve own identities
std::set<RsGxsId> own_ids;
for(auto& id:own_ids_lst)
own_ids.insert(id); // put them in a std::set for O(log(n)) search
for(auto& gxs_id: new_circle_grp_item->gxsIdSet.ids)
if(old_circle_grp_item->gxsIdSet.ids.find(gxs_id) == old_circle_grp_item->gxsIdSet.ids.end() && own_ids.find(gxs_id)!=own_ids.end())
added_identities.push_back(gxs_id);
for(auto& gxs_id: old_circle_grp_item->gxsIdSet.ids)
if(new_circle_grp_item->gxsIdSet.ids.find(gxs_id) == old_circle_grp_item->gxsIdSet.ids.end() && own_ids.find(gxs_id)!=own_ids.end())
removed_identities.push_back(gxs_id);
for(auto& gxs_id:added_identities)
{
auto ev = std::make_shared<RsGxsCircleEvent>();
ev->mCircleEventType = RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_INVITE;
ev->mCircleId = circle_id;
ev->mGxsId = gxs_id;
rsEvents->sendEvent(ev);
}
for(auto& gxs_id:removed_identities)
{
auto ev = std::make_shared<RsGxsCircleEvent>();
ev->mCircleEventType = RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_REVOKED;
ev->mCircleId = circle_id;
ev->mGxsId = gxs_id;
rsEvents->sendEvent(ev);
}
}
delete *it;
}
}

View File

@ -249,16 +249,10 @@ void p3GxsForums::notifyChanges(std::vector<RsGxsNotify *> &changes)
{
case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed
{
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for (git = grpList.begin(); git != grpList.end(); ++git)
{
auto ev = std::make_shared<RsGxsForumEvent>();
ev->mForumGroupId = *git;
ev->mForumGroupId = grpChange->mGroupId;
ev->mForumEventCode = RsForumEventCode::SUBSCRIBE_STATUS_CHANGED;
rsEvents->postEvent(ev);
}
}
break;
@ -266,112 +260,81 @@ void p3GxsForums::notifyChanges(std::vector<RsGxsNotify *> &changes)
case RsGxsNotify::TYPE_RECEIVED_NEW:
{
/* group received */
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
RS_STACK_MUTEX(mKnownForumsMutex);
for (git = grpList.begin(); git != grpList.end(); ++git)
{
if(mKnownForums.find(*git) == mKnownForums.end())
{
mKnownForums.insert(
std::make_pair(*git, time(nullptr)));
IndicateConfigChanged();
auto ev = std::make_shared<RsGxsForumEvent>();
ev->mForumGroupId = *git;
ev->mForumEventCode = RsForumEventCode::NEW_FORUM;
rsEvents->postEvent(ev);
}
else
RsInfo() << __PRETTY_FUNCTION__
<< " Not notifying already known forum "
<< *git << std::endl;
if(mKnownForums.find(grpChange->mGroupId) == mKnownForums.end())
{
mKnownForums.insert( std::make_pair(grpChange->mGroupId, time(nullptr)));
IndicateConfigChanged();
auto ev = std::make_shared<RsGxsForumEvent>();
ev->mForumGroupId = grpChange->mGroupId;
ev->mForumEventCode = RsForumEventCode::NEW_FORUM;
rsEvents->postEvent(ev);
}
else
RsInfo() << __PRETTY_FUNCTION__
<< " Not notifying already known forum "
<< grpChange->mGroupId << std::endl;
}
break;
case RsGxsNotify::TYPE_STATISTICS_CHANGED:
{
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for (git = grpList.begin(); git != grpList.end(); ++git)
auto ev = std::make_shared<RsGxsForumEvent>();
ev->mForumGroupId = grpChange->mGroupId;
ev->mForumEventCode = RsForumEventCode::STATISTICS_CHANGED;
rsEvents->postEvent(ev);
}
break;
case RsGxsNotify::TYPE_UPDATED:
{
// Happens when the group data has changed. In this case we need to analyse the old and new group in order to detect possible notifications for clients
RsGxsForumGroupItem *old_forum_grp_item = dynamic_cast<RsGxsForumGroupItem*>(grpChange->mOldGroupItem);
RsGxsForumGroupItem *new_forum_grp_item = dynamic_cast<RsGxsForumGroupItem*>(grpChange->mNewGroupItem);
if(old_forum_grp_item == nullptr || new_forum_grp_item == nullptr)
{
RsErr() << __PRETTY_FUNCTION__ << " received GxsGroupUpdate item with mOldGroup and mNewGroup not of type RsGxsForumGroupItem. This is inconsistent!" << std::endl;
delete grpChange;
continue;
}
// First of all, we check if there is a difference between the old and new list of moderators
std::list<RsGxsId> added_mods, removed_mods;
for(auto& gxs_id: new_forum_grp_item->mGroup.mAdminList.ids)
if(old_forum_grp_item->mGroup.mAdminList.ids.find(gxs_id) == old_forum_grp_item->mGroup.mAdminList.ids.end())
added_mods.push_back(gxs_id);
for(auto& gxs_id: old_forum_grp_item->mGroup.mAdminList.ids)
if(new_forum_grp_item->mGroup.mAdminList.ids.find(gxs_id) == new_forum_grp_item->mGroup.mAdminList.ids.end())
removed_mods.push_back(gxs_id);
if(!added_mods.empty() || !removed_mods.empty())
{
auto ev = std::make_shared<RsGxsForumEvent>();
ev->mForumGroupId = *git;
ev->mForumEventCode = RsForumEventCode::STATISTICS_CHANGED;
ev->mForumGroupId = new_forum_grp_item->meta.mGroupId;
ev->mModeratorsAdded = added_mods;
ev->mModeratorsRemoved = removed_mods;
ev->mForumEventCode = RsForumEventCode::MODERATOR_LIST_CHANGED;
rsEvents->postEvent(ev);
}
}
break;
break;
default:
RsErr() << " Got a GXS event of type " << grpChange->getType() << " Currently not handled." << std::endl;
break;
#ifdef NOT_USED_YET
case RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY:
{
/* group received */
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for (git = grpList.begin(); git != grpList.end(); ++git)
{
auto ev = std::make_shared<RsGxsChannelEvent>();
ev->mChannelGroupId = *git;
ev->mChannelEventCode = RsGxsChannelEvent::RECEIVED_PUBLISH_KEY;
rsEvents->sendEvent(ev);
}
}
break;
#endif
}
}
RsGxsGroupUpdate *grpUpdate = dynamic_cast<RsGxsGroupUpdate*>(*it);
if (grpUpdate && rsEvents)
{
// Happens when the group data has changed. In this case we need to analyse the old and new group in order to detect possible notifications for clients
RsGxsForumGroupItem *old_forum_grp_item = dynamic_cast<RsGxsForumGroupItem*>(grpUpdate->mOldGroupItem);
RsGxsForumGroupItem *new_forum_grp_item = dynamic_cast<RsGxsForumGroupItem*>(grpUpdate->mNewGroupItem);
if(old_forum_grp_item == nullptr || new_forum_grp_item == nullptr)
{
RsErr() << __PRETTY_FUNCTION__ << " received GxsGroupUpdate item with mOldGroup and mNewGroup not of type RsGxsForumGroupItem. This is inconsistent!" << std::endl;
delete grpUpdate;
continue;
}
// First of all, we check if there is a difference between the old and new list of moderators
std::list<RsGxsId> added_mods, removed_mods;
for(auto& gxs_id: new_forum_grp_item->mGroup.mAdminList.ids)
if(old_forum_grp_item->mGroup.mAdminList.ids.find(gxs_id) == old_forum_grp_item->mGroup.mAdminList.ids.end())
added_mods.push_back(gxs_id);
for(auto& gxs_id: old_forum_grp_item->mGroup.mAdminList.ids)
if(new_forum_grp_item->mGroup.mAdminList.ids.find(gxs_id) == new_forum_grp_item->mGroup.mAdminList.ids.end())
removed_mods.push_back(gxs_id);
if(!added_mods.empty() || !removed_mods.empty())
{
auto ev = std::make_shared<RsGxsForumEvent>();
ev->mForumGroupId = new_forum_grp_item->meta.mGroupId;
ev->mModeratorsAdded = added_mods;
ev->mModeratorsRemoved = removed_mods;
ev->mForumEventCode = RsForumEventCode::MODERATOR_LIST_CHANGED;
rsEvents->postEvent(ev);
}
}
}
}

View File

@ -631,16 +631,13 @@ void p3IdService::notifyChanges(std::vector<RsGxsNotify *> &changes)
std::cerr << "p3IdService::notifyChanges() Found Group Change Notification";
std::cerr << std::endl;
#endif
std::list<RsGxsGroupId> &groupList = groupChange->mGrpIdList;
for(auto git = groupList.begin(); git != groupList.end();++git)
{
#ifdef DEBUG_IDS
std::cerr << "p3IdService::notifyChanges() Auto Subscribe to Incoming Groups: " << *git;
std::cerr << std::endl;
#endif
const RsGxsGroupId& gid(groupChange->mGroupId);
if(!rsReputations->isIdentityBanned(RsGxsId(*git)))
if(!rsReputations->isIdentityBanned(RsGxsId(gid)))
{
// notify that a new identity is received, if needed
@ -654,12 +651,12 @@ void p3IdService::notifyChanges(std::vector<RsGxsNotify *> &changes)
case RsGxsNotify::TYPE_PUBLISHED:
{
auto ev = std::make_shared<RsGxsIdentityEvent>();
ev->mIdentityId = *git;
ev->mIdentityId = gid;
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)) ;
timeStampKey(RsGxsId(gid),RsIdentityUsage(serviceType(),RsIdentityUsage::IDENTITY_DATA_UPDATE)) ;
should_subscribe = true;
}
break;
@ -667,12 +664,12 @@ void p3IdService::notifyChanges(std::vector<RsGxsNotify *> &changes)
case RsGxsNotify::TYPE_RECEIVED_NEW:
{
auto ev = std::make_shared<RsGxsIdentityEvent>();
ev->mIdentityId = *git;
ev->mIdentityId = gid;
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)) ;
timeStampKey(RsGxsId(gid),RsIdentityUsage(serviceType(),RsIdentityUsage::IDENTITY_DATA_UPDATE)) ;
should_subscribe = true;
}
break;
@ -684,11 +681,10 @@ void p3IdService::notifyChanges(std::vector<RsGxsNotify *> &changes)
if(should_subscribe)
{
uint32_t token;
RsGenExchange::subscribeToGroup(token, *git, true);
RsGenExchange::subscribeToGroup(token, gid, true);
}
}
}
}
delete changes[i];

View File

@ -131,36 +131,25 @@ void p3PostBase::notifyChanges(std::vector<RsGxsNotify *> &changes)
std::cerr << "p3PostBase::notifyChanges() Found Group Change Notification";
std::cerr << std::endl;
#endif
const RsGxsGroupId& group_id(grpChange->mGroupId);
switch(grpChange->getType())
{
case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed
{
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for (git = grpList.begin(); git != grpList.end(); ++git)
{
auto ev = std::make_shared<RsGxsPostedEvent>();
ev->mPostedGroupId = *git;
ev->mPostedEventCode = RsPostedEventCode::SUBSCRIBE_STATUS_CHANGED;
rsEvents->postEvent(ev);
}
auto ev = std::make_shared<RsGxsPostedEvent>();
ev->mPostedGroupId = group_id;
ev->mPostedEventCode = RsPostedEventCode::SUBSCRIBE_STATUS_CHANGED;
rsEvents->postEvent(ev);
}
break;
case RsGxsNotify::TYPE_STATISTICS_CHANGED:
{
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for (git = grpList.begin(); git != grpList.end(); ++git)
{
auto ev = std::make_shared<RsGxsPostedEvent>();
ev->mPostedGroupId = *git;
ev->mPostedEventCode = RsPostedEventCode::STATISTICS_CHANGED;
rsEvents->postEvent(ev);
}
auto ev = std::make_shared<RsGxsPostedEvent>();
ev->mPostedGroupId = group_id;
ev->mPostedEventCode = RsPostedEventCode::STATISTICS_CHANGED;
rsEvents->postEvent(ev);
}
break;
@ -168,30 +157,26 @@ void p3PostBase::notifyChanges(std::vector<RsGxsNotify *> &changes)
case RsGxsNotify::TYPE_RECEIVED_NEW:
{
/* group received */
const std::list<RsGxsGroupId>& grpList = grpChange->mGrpIdList;
for (auto git = grpList.begin(); git != grpList.end(); ++git)
if(mKnownPosted.find(group_id) == mKnownPosted.end())
{
if(mKnownPosted.find(*git) == mKnownPosted.end())
{
mKnownPosted.insert(std::make_pair(*git, time(nullptr)));
IndicateConfigChanged();
mKnownPosted.insert(std::make_pair(group_id, time(nullptr)));
IndicateConfigChanged();
auto ev = std::make_shared<RsGxsPostedEvent>();
ev->mPostedGroupId = *git;
ev->mPostedEventCode = RsPostedEventCode::NEW_POSTED_GROUP;
rsEvents->postEvent(ev);
auto ev = std::make_shared<RsGxsPostedEvent>();
ev->mPostedGroupId = group_id;
ev->mPostedEventCode = RsPostedEventCode::NEW_POSTED_GROUP;
rsEvents->postEvent(ev);
#ifdef POSTBASE_DEBUG
std::cerr << "p3PostBase::notifyChanges() Incoming Group: " << *git;
std::cerr << std::endl;
std::cerr << "p3PostBase::notifyChanges() Incoming Group: " << group_id;
std::cerr << std::endl;
#endif
}
else
RsInfo() << __PRETTY_FUNCTION__
<< " Not notifying already known forum "
<< *git << std::endl;
}
else
RsInfo() << __PRETTY_FUNCTION__
<< " Not notifying already known forum "
<< group_id << std::endl;
}
break;