added logic to keep track of circles activity from friend nodes and the methods to estimate when circles are not used

This commit is contained in:
csoler 2020-11-24 18:33:16 +01:00
parent 2fd15134c9
commit 2c7ee7ebeb
4 changed files with 194 additions and 35 deletions

View File

@ -128,6 +128,7 @@ RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_TYPE_JSONAPI
RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_GXS_TYPE_FORUMS_CONFIG = 0x0315; RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_GXS_TYPE_FORUMS_CONFIG = 0x0315;
RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_GXS_TYPE_POSTED_CONFIG = 0x0316; RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_GXS_TYPE_POSTED_CONFIG = 0x0316;
RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_GXS_TYPE_CHANNELS_CONFIG = 0x0317; RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_GXS_TYPE_CHANNELS_CONFIG = 0x0317;
RS_DEPRECATED_FOR(RsServiceType) const uint16_t RS_SERVICE_GXS_TYPE_CIRCLES_CONFIG = 0x0318;
// Experimental Services. // Experimental Services.
/* DSDV Testing at the moment - Service Only */ /* DSDV Testing at the moment - Service Only */

View File

@ -1639,6 +1639,7 @@ int RsServer::StartupRetroShare()
mConfigMgr->addConfiguration("gxschannels.cfg" , gxschannels_ns); mConfigMgr->addConfiguration("gxschannels.cfg" , gxschannels_ns);
mConfigMgr->addConfiguration("gxschannels_srv.cfg", mGxsChannels); mConfigMgr->addConfiguration("gxschannels_srv.cfg", mGxsChannels);
mConfigMgr->addConfiguration("gxscircles.cfg" , gxscircles_ns); mConfigMgr->addConfiguration("gxscircles.cfg" , gxscircles_ns);
mConfigMgr->addConfiguration("gxscircles_srv.cfg" , mGxsCircles);
mConfigMgr->addConfiguration("posted.cfg" , posted_ns); mConfigMgr->addConfiguration("posted.cfg" , posted_ns);
mConfigMgr->addConfiguration("gxsposted_srv.cfg" , mPosted); mConfigMgr->addConfiguration("gxsposted_srv.cfg" , mPosted);
#ifdef RS_USE_WIKI #ifdef RS_USE_WIKI

View File

@ -49,6 +49,8 @@
/*static*/ const std::string RsGxsCircles::CIRCLE_URL_ID_FIELD = "circleId"; /*static*/ const std::string RsGxsCircles::CIRCLE_URL_ID_FIELD = "circleId";
/*static*/ const std::string RsGxsCircles::CIRCLE_URL_DATA_FIELD = "circleData"; /*static*/ const std::string RsGxsCircles::CIRCLE_URL_DATA_FIELD = "circleData";
static const uint32_t CIRCLES_UNUSED_BY_FRIENDS_DELAY = 7*86400 ; // 7 days ...O...
RsGxsCircles::~RsGxsCircles() = default; RsGxsCircles::~RsGxsCircles() = default;
RsGxsCircleMsg::~RsGxsCircleMsg() = default; RsGxsCircleMsg::~RsGxsCircleMsg() = default;
RsGxsCircleDetails::~RsGxsCircleDetails() = default; RsGxsCircleDetails::~RsGxsCircleDetails() = default;
@ -141,6 +143,7 @@ p3GxsCircles::p3GxsCircles( RsGeneralDataService *gds, RsNetworkExchangeService
RsGxsCircles(static_cast<RsGxsIface&>(*this)), GxsTokenQueue(this), RsGxsCircles(static_cast<RsGxsIface&>(*this)), GxsTokenQueue(this),
RsTickEvent(), mIdentities(identities), mPgpUtils(pgpUtils), RsTickEvent(), mIdentities(identities), mPgpUtils(pgpUtils),
mCircleMtx("p3GxsCircles"), mCircleMtx("p3GxsCircles"),
mKnownCirclesMtx("p3GxsCircles"),
// mCircleCache(DEFAULT_MEM_CACHE_SIZE, "GxsCircleCache" ), // mCircleCache(DEFAULT_MEM_CACHE_SIZE, "GxsCircleCache" ),
mShouldSendCacheUpdateNotification(false) mShouldSendCacheUpdateNotification(false)
{ {
@ -655,6 +658,12 @@ void p3GxsCircles::notifyChanges(std::vector<RsGxsNotify *> &changes)
addCircleIdToList(RsGxsCircleId(*git), 0); addCircleIdToList(RsGxsCircleId(*git), 0);
circles_to_reload.insert(RsGxsCircleId(*git)); circles_to_reload.insert(RsGxsCircleId(*git));
} // fallthrough
case RsGxsNotify::TYPE_STATISTICS_CHANGED:
{
RS_STACK_MUTEX(mKnownCirclesMtx);
mKnownCircles[*git] = time(nullptr);
IndicateConfigChanged();
} }
break; break;
default: default:
@ -1713,6 +1722,52 @@ void p3GxsCircles::addCircleIdToList(const RsGxsCircleId &circleId, uint32_t cir
} }
} }
bool p3GxsCircles::service_checkIfGroupIsStillUsed(const RsGxsGrpMetaData& meta)
{
std::cerr << "p3gxsChannels: Checking unused board: called by GxsCleaning." << std::endl;
// request all group infos at once
rstime_t now = time(nullptr);
RS_STACK_MUTEX(mKnownCirclesMtx);
auto it = mKnownCircles.find(meta.mGroupId);
bool unknown_posted = (it == mKnownCircles.end());
std::cerr << " Circle " << meta.mGroupId ;
if(unknown_posted)
{
// This case should normally not happen. It does because this board was never registered since it may
// arrived before this code was here
std::cerr << ". Not known yet. Adding current time as new TS." << std::endl;
mKnownCircles[meta.mGroupId] = now;
IndicateConfigChanged();
return true;
}
else
{
bool used_by_friends = (now < it->second + CIRCLES_UNUSED_BY_FRIENDS_DELAY);
bool subscribed = static_cast<bool>(meta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED);
std::cerr << ". subscribed: " << subscribed << ", used_by_friends: " << used_by_friends << " last TS: " << now - it->second << " secs ago (" << (now-it->second)/86400 << " days)";
if(!subscribed && !used_by_friends)
{
std::cerr << ". Scheduling for deletion" << std::endl;
return false;
}
else
{
std::cerr << ". Keeping!" << std::endl;
return true;
}
}
}
//====================================================================================// //====================================================================================//
// Event handling // // Event handling //
//====================================================================================// //====================================================================================//
@ -2073,6 +2128,100 @@ bool p3GxsCircles::processMembershipRequests(uint32_t token)
return true ; return true ;
} }
//====================================================================================//
// p3Config methods //
//====================================================================================//
static const uint32_t GXS_FORUMS_CONFIG_MAX_TIME_NOTIFY_STORAGE = 86400*30*2 ; // ignore notifications for 2 months
static const uint8_t GXS_CIRCLES_CONFIG_SUBTYPE_NOTIFY_RECORD = 0x01 ;
struct RsGxsCirclesNotifyRecordsItem: public RsItem
{
RsGxsCirclesNotifyRecordsItem()
: RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_GXS_TYPE_CIRCLES_CONFIG,GXS_CIRCLES_CONFIG_SUBTYPE_NOTIFY_RECORD)
{}
virtual ~RsGxsCirclesNotifyRecordsItem() {}
void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx )
{ RS_SERIAL_PROCESS(records); }
void clear() {}
std::map<RsGxsGroupId,rstime_t> records;
};
class GxsCirclesConfigSerializer : public RsServiceSerializer
{
public:
GxsCirclesConfigSerializer() : RsServiceSerializer(RS_SERVICE_GXS_TYPE_CIRCLES_CONFIG) {}
virtual ~GxsCirclesConfigSerializer() {}
RsItem* create_item(uint16_t service_id, uint8_t item_sub_id) const
{
if(service_id != RS_SERVICE_GXS_TYPE_CIRCLES_CONFIG)
return NULL;
switch(item_sub_id)
{
case GXS_CIRCLES_CONFIG_SUBTYPE_NOTIFY_RECORD: return new RsGxsCirclesNotifyRecordsItem();
default:
return NULL;
}
}
};
bool p3GxsCircles::saveList(bool& cleanup, std::list<RsItem *>&saveList)
{
cleanup = true ;
RsGxsCirclesNotifyRecordsItem *item = new RsGxsCirclesNotifyRecordsItem ;
{
RS_STACK_MUTEX(mKnownCirclesMtx);
item->records = mKnownCircles ;
}
saveList.push_back(item) ;
return true;
}
bool p3GxsCircles::loadList(std::list<RsItem *>& loadList)
{
while(!loadList.empty())
{
RsItem *item = loadList.front();
loadList.pop_front();
rstime_t now = time(NULL);
RsGxsCirclesNotifyRecordsItem *fnr = dynamic_cast<RsGxsCirclesNotifyRecordsItem*>(item) ;
if(fnr != NULL)
{
RS_STACK_MUTEX(mKnownCirclesMtx);
mKnownCircles.clear();
for(auto it(fnr->records.begin());it!=fnr->records.end();++it)
if( now < it->second + GXS_FORUMS_CONFIG_MAX_TIME_NOTIFY_STORAGE)
mKnownCircles.insert(*it) ;
}
delete item ;
}
return true;
}
RsSerialiser* p3GxsCircles::setupSerialiser()
{
RsSerialiser* rss = new RsSerialiser;
rss->addSerialType(new GxsCirclesConfigSerializer());
return rss;
}
//====================================================================================// //====================================================================================//
// DEBUG STUFF // // DEBUG STUFF //

View File

@ -208,8 +208,7 @@ public:
} }
}; };
class p3GxsCircles: public RsGxsCircleExchange, public RsGxsCircles, class p3GxsCircles: public RsGxsCircleExchange, public RsGxsCircles, public GxsTokenQueue, public RsTickEvent, public p3Config
public GxsTokenQueue, public RsTickEvent
{ {
public: public:
p3GxsCircles( p3GxsCircles(
@ -271,52 +270,58 @@ public:
std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string) std::string& errMsg = RS_DEFAULT_STORAGE_PARAM(std::string)
) override; ) override;
virtual bool getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails &details); virtual bool getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails &details) override;
virtual bool getCircleExternalIdList(std::list<RsGxsCircleId> &circleIds); virtual bool getCircleExternalIdList(std::list<RsGxsCircleId> &circleIds) override;
virtual bool isLoaded(const RsGxsCircleId &circleId); virtual bool isLoaded(const RsGxsCircleId &circleId) override;
virtual bool loadCircle(const RsGxsCircleId &circleId); virtual bool loadCircle(const RsGxsCircleId &circleId) override;
virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id, bool &should_encrypt); virtual int canSend(const RsGxsCircleId &circleId, const RsPgpId &id, bool &should_encrypt) override;
virtual int canReceive(const RsGxsCircleId &circleId, const RsPgpId &id); virtual int canReceive(const RsGxsCircleId &circleId, const RsPgpId &id) override;
virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsPgpId> &friendlist) ; virtual bool recipients(const RsGxsCircleId &circleId, std::list<RsPgpId> &friendlist) override;
virtual bool recipients(const RsGxsCircleId &circleId, const RsGxsGroupId& dest_group, std::list<RsGxsId> &gxs_ids) ; virtual bool recipients(const RsGxsCircleId &circleId, const RsGxsGroupId& dest_group, std::list<RsGxsId> &gxs_ids) override;
virtual bool isRecipient(const RsGxsCircleId &circleId, const RsGxsGroupId& destination_group, const RsGxsId& id) ; virtual bool isRecipient(const RsGxsCircleId &circleId, const RsGxsGroupId& destination_group, const RsGxsId& id) override;
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsCircleGroup> &groups); virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsCircleGroup> &groups) override;
virtual bool getMsgData(const uint32_t &token, std::vector<RsGxsCircleMsg> &msgs); virtual bool getMsgData(const uint32_t &token, std::vector<RsGxsCircleMsg> &msgs) override;
virtual void createGroup(uint32_t& token, RsGxsCircleGroup &group); virtual void createGroup(uint32_t& token, RsGxsCircleGroup &group) override;
virtual void updateGroup(uint32_t &token, RsGxsCircleGroup &group); virtual void updateGroup(uint32_t &token, RsGxsCircleGroup &group) override;
virtual bool service_checkIfGroupIsStillUsed(const RsGxsGrpMetaData& meta) override;
/* membership management for external circles */ /* membership management for external circles */
virtual bool requestCircleMembership(const RsGxsId &own_gxsid, const RsGxsCircleId& circle_id) ; virtual bool requestCircleMembership(const RsGxsId &own_gxsid, const RsGxsCircleId& circle_id) override;
virtual bool cancelCircleMembership(const RsGxsId &own_gxsid, const RsGxsCircleId& circle_id) ; virtual bool cancelCircleMembership(const RsGxsId &own_gxsid, const RsGxsCircleId& circle_id) override;
/**********************************************/ /**********************************************/
// needed for background processing. // needed for background processing.
virtual void service_tick(); virtual void service_tick() override;
protected: protected:
// overloads p3Config
virtual bool saveList(bool &cleanup, std::list<RsItem *>&saveList) override;
virtual bool loadList(std::list<RsItem *>& loadList) override;
virtual RsSerialiser *setupSerialiser() override;
bool pushCircleMembershipRequest(const RsGxsId& own_gxsid, const RsGxsCircleId& circle_id, RsGxsCircleSubscriptionType request_type) ; bool pushCircleMembershipRequest(const RsGxsId& own_gxsid, const RsGxsCircleId& circle_id, RsGxsCircleSubscriptionType request_type) ;
static uint32_t circleAuthenPolicy(); static uint32_t circleAuthenPolicy();
/** Notifications **/ /** Notifications **/
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes); virtual void notifyChanges(std::vector<RsGxsNotify*>& changes) override;
/** Overloaded to add PgpIdHash to Group Definition **/ /** Overloaded to add PgpIdHash to Group Definition **/
virtual ServiceCreate_Return service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet); virtual ServiceCreate_Return service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet) override;
// Overloaded from GxsTokenQueue for Request callbacks. // Overloaded from GxsTokenQueue for Request callbacks.
virtual void handleResponse(uint32_t token, uint32_t req_type); virtual void handleResponse(uint32_t token, uint32_t req_type) override;
// Overloaded from RsTickEvent. // Overloaded from RsTickEvent.
virtual void handle_event(uint32_t event_type, const std::string &elabel); virtual void handle_event(uint32_t event_type, const std::string &elabel) override;
private: private:
@ -354,6 +359,9 @@ public:
void addCircleIdToList(const RsGxsCircleId& circleId, uint32_t circleType); void addCircleIdToList(const RsGxsCircleId& circleId, uint32_t circleType);
RsMutex mCircleMtx; /* Locked Below Here */ RsMutex mCircleMtx; /* Locked Below Here */
RsMutex mKnownCirclesMtx; /* Locked Below Here */
std::map<RsGxsGroupId,rstime_t> mKnownCircles;
std::list<RsGxsCircleId> mCircleExternalIdList; std::list<RsGxsCircleId> mCircleExternalIdList;
std::list<RsGxsCircleId> mCirclePersonalIdList; std::list<RsGxsCircleId> mCirclePersonalIdList;