* Added Dummy Forums and Messages to GxsForums.

* Extra GxsForums::getRelatedMessages() fn + HACKs to cover up GXS bugs.
 * more debugging in rsgenexchange.
 * fixed up some of wikis text.
 


git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5828 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
drbob 2012-11-15 23:50:54 +00:00
parent 2230bd1a96
commit 9373d26be0
6 changed files with 293 additions and 209 deletions

View File

@ -47,6 +47,8 @@
#define PRIV_GRP_OFFSET 16 #define PRIV_GRP_OFFSET 16
#define GRP_OPTIONS_OFFSET 24 #define GRP_OPTIONS_OFFSET 24
#define GEN_EXCH_DEBUG 1
RsGenExchange::RsGenExchange(RsGeneralDataService *gds, RsNetworkExchangeService *ns, RsGenExchange::RsGenExchange(RsGeneralDataService *gds, RsNetworkExchangeService *ns,
RsSerialType *serviceSerialiser, uint16_t servType, RsGixs* gixs, uint32_t authenPolicy) RsSerialType *serviceSerialiser, uint16_t servType, RsGixs* gixs, uint32_t authenPolicy)
: mGenMtx("GenExchange"), mDataStore(gds), mNetService(ns), mSerialiser(serviceSerialiser), : mGenMtx("GenExchange"), mDataStore(gds), mNetService(ns), mSerialiser(serviceSerialiser),
@ -952,17 +954,27 @@ void RsGenExchange::publishGroup(uint32_t& token, RsGxsGrpItem *grpItem)
{ {
RsStackMutex stack(mGenMtx); RsStackMutex stack(mGenMtx);
token = mDataAccess->generatePublicToken(); token = mDataAccess->generatePublicToken();
mGrpsToPublish.insert(std::make_pair(token, grpItem)); mGrpsToPublish.insert(std::make_pair(token, grpItem));
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::publishGroup() token: " << token;
std::cerr << std::endl;
#endif
} }
void RsGenExchange::publishMsg(uint32_t& token, RsGxsMsgItem *msgItem) void RsGenExchange::publishMsg(uint32_t& token, RsGxsMsgItem *msgItem)
{ {
RsStackMutex stack(mGenMtx); RsStackMutex stack(mGenMtx);
token = mDataAccess->generatePublicToken(); token = mDataAccess->generatePublicToken();
mMsgsToPublish.insert(std::make_pair(token, msgItem)); mMsgsToPublish.insert(std::make_pair(token, msgItem));
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::publishMsg() token: " << token;
std::cerr << std::endl;
#endif
} }
void RsGenExchange::setGroupSubscribeFlags(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& flag, const uint32_t& mask) void RsGenExchange::setGroupSubscribeFlags(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& flag, const uint32_t& mask)
@ -1125,6 +1137,13 @@ void RsGenExchange::publishMsgs()
req.insert(std::make_pair(msg->grpId, msgV)); req.insert(std::make_pair(msg->grpId, msgV));
mDataStore->retrieveGxsMsgMetaData(req, res); mDataStore->retrieveGxsMsgMetaData(req, res);
msgDoesnExist = res[grpId].empty(); msgDoesnExist = res[grpId].empty();
#ifdef GEN_EXCH_DEBUG
if (!msgDoesnExist)
{
std::cerr << "RsGenExchange::publishMsgs() msg exists already :( " << std::endl;
}
#endif
} }
if(createOk && msgDoesnExist) if(createOk && msgDoesnExist)
@ -1167,6 +1186,12 @@ void RsGenExchange::publishMsgs()
#endif #endif
} }
} }
else
{
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::publishMsgs() failed to serialise msg " << std::endl;
#endif
}
delete[] mData; delete[] mData;
delete msgItem; delete msgItem;

View File

@ -75,6 +75,7 @@ virtual ~RsGxsForums() { return; }
/* Specific Service Data */ /* Specific Service Data */
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsForumGroup> &groups) = 0; virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsForumGroup> &groups) = 0;
virtual bool getMsgData(const uint32_t &token, std::vector<RsGxsForumMsg> &msgs) = 0; virtual bool getMsgData(const uint32_t &token, std::vector<RsGxsForumMsg> &msgs) = 0;
virtual bool getRelatedMessages(const uint32_t &token, std::vector<RsGxsForumMsg> &msgs) = 0;
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) = 0; virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read) = 0;
@ -88,6 +89,7 @@ virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgI
virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group) = 0; virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group) = 0;
virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg) = 0; virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg) = 0;
virtual bool generateDummyData() = 0;
}; };

View File

@ -279,7 +279,7 @@ uint32_t RsGxsForumSerialiser::sizeGxsForumMsgItem(RsGxsForumMsgItem *item)
const RsGxsForumMsg& msg = item->mMsg; const RsGxsForumMsg& msg = item->mMsg;
uint32_t s = 8; // header uint32_t s = 8; // header
s += 4; // mMsg. s += GetTlvStringSize(msg.mMsg); // mMsg.
return s; return s;
} }

View File

@ -26,10 +26,14 @@
#include "services/p3gxsforums.h" #include "services/p3gxsforums.h"
#include "serialiser/rsgxsforumitems.h" #include "serialiser/rsgxsforumitems.h"
#include "util/rsrandom.h"
#include "gxs/rsgxsflags.h" #include "gxs/rsgxsflags.h"
#include <stdio.h> #include <stdio.h>
// For Dummy Msgs.
#include "util/rsrandom.h"
#include "util/rsstring.h"
/**** /****
* #define GXSFORUM_DEBUG 1 * #define GXSFORUM_DEBUG 1
****/ ****/
@ -45,6 +49,8 @@ RsGxsForums *rsGxsForums = NULL;
p3GxsForums::p3GxsForums(RsGeneralDataService *gds, RsNetworkExchangeService *nes) p3GxsForums::p3GxsForums(RsGeneralDataService *gds, RsNetworkExchangeService *nes)
: RsGenExchange(gds, nes, new RsGxsForumSerialiser(), RS_SERVICE_GXSV1_TYPE_FORUMS), RsGxsForums(this) : RsGenExchange(gds, nes, new RsGxsForumSerialiser(), RS_SERVICE_GXSV1_TYPE_FORUMS), RsGxsForums(this)
{ {
// For Dummy Msgs.
mGenActive = false;
} }
void p3GxsForums::notifyChanges(std::vector<RsGxsNotify *> &changes) void p3GxsForums::notifyChanges(std::vector<RsGxsNotify *> &changes)
@ -54,6 +60,7 @@ void p3GxsForums::notifyChanges(std::vector<RsGxsNotify *> &changes)
void p3GxsForums::service_tick() void p3GxsForums::service_tick()
{ {
dummy_tick();
return; return;
} }
@ -122,6 +129,65 @@ bool p3GxsForums::getMsgData(const uint32_t &token, std::vector<RsGxsForumMsg> &
return ok; return ok;
} }
bool p3GxsForums::getRelatedMessages(const uint32_t &token, std::vector<RsGxsForumMsg> &msgs)
{
GxsMsgRelatedDataMap msgData;
bool ok = RsGenExchange::getMsgRelatedData(token, msgData);
if(ok)
{
GxsMsgRelatedDataMap::iterator mit = msgData.begin();
for(; mit != msgData.end(); mit++)
{
std::vector<RsGxsMsgItem*>& msgItems = mit->second;
std::vector<RsGxsMsgItem*>::iterator vit = msgItems.begin();
for(; vit != msgItems.end(); vit++)
{
RsGxsForumMsgItem* item = dynamic_cast<RsGxsForumMsgItem*>(*vit);
if(item)
{
/* HACK UNTIL CHRIS FIXES RELATED MSGS in GXS */
if (item->meta.mMsgId == (mit->first).second)
{
std::cerr << "p3GxsForums::getRelatedMessages()";
std::cerr << " ERROR Found Original - discarding";
std::cerr << " Id: " << item->meta.mMsgId;
std::cerr << std::endl;
delete item;
continue;
}
if (item->meta.mParentId != (mit->first).second)
{
std::cerr << "p3GxsForums::getRelatedMessages()";
std::cerr << " ERROR Found !CHILD - discarding";
std::cerr << " Id: " << item->meta.mMsgId;
std::cerr << std::endl;
delete item;
continue;
}
RsGxsForumMsg msg = item->mMsg;
msg.mMeta = item->meta;
msgs.push_back(msg);
delete item;
}
else
{
std::cerr << "Not a GxsForumMsgItem, deleting!" << std::endl;
delete *vit;
}
}
}
}
return ok;
}
/********************************************************************************************/ /********************************************************************************************/
bool p3GxsForums::createGroup(uint32_t &token, RsGxsForumGroup &group) bool p3GxsForums::createGroup(uint32_t &token, RsGxsForumGroup &group)
@ -170,6 +236,11 @@ void p3GxsForums::setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair&
/********************************************************************************************/ /********************************************************************************************/
/********************************************************************************************/ /********************************************************************************************/
/* so we need the same tick idea as wiki for generating dummy forums
*/
#define MAX_GEN_GROUPS 5
#define MAX_GEN_MESSAGES 100
std::string p3GxsForums::genRandomId() std::string p3GxsForums::genRandomId()
{ {
@ -184,204 +255,165 @@ std::string p3GxsForums::genRandomId()
bool p3GxsForums::generateDummyData() bool p3GxsForums::generateDummyData()
{ {
return false; mGenCount = 0;
} mGenRefs.resize(MAX_GEN_MESSAGES);
std::string groupName;
rs_sprintf(groupName, "TestForum_%d", mGenCount);
#if 0 std::cerr << "p3GxsForums::generateDummyData() Starting off with Group: " << groupName;
std::cerr << std::endl;
bool p3GxsForums::generateDummyData() /* create a new group */
{ generateGroup(mGenToken, groupName);
/* so we want to generate 100's of forums */
#define MAX_FORUMS 10 //100
#define MAX_THREADS 10 //1000
#define MAX_MSGS 100 //10000
std::list<RsForumV2Group> mGroups; mGenActive = true;
std::list<RsForumV2Group>::iterator git;
return true;
std::list<RsForumV2Msg> mMsgs; }
std::list<RsForumV2Msg>::iterator mit;
#define DUMMY_NAME_MAX_LEN 10000 void p3GxsForums::dummy_tick()
char name[DUMMY_NAME_MAX_LEN]; {
int i, j; /* check for a new callback */
time_t now = time(NULL);
if (mGenActive)
for(i = 0; i < MAX_FORUMS; i++) {
{ std::cerr << "p3Wiki::dummyTick() AboutActive";
/* generate a new forum */ std::cerr << std::endl;
RsForumV2Group forum;
uint32_t status = RsGenExchange::getTokenService()->requestStatus(mGenToken);
/* generate a temp id */ if (status != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
forum.mMeta.mGroupId = genRandomId(); {
std::cerr << "p3GxsForums::dummy_tick() Status: " << status;
snprintf(name, DUMMY_NAME_MAX_LEN, "TestForum_%d", i+1); std::cerr << std::endl;
forum.mMeta.mGroupId = genRandomId(); if (status == RsTokenService::GXS_REQUEST_V2_STATUS_FAILED)
forum.mMeta.mGroupName = name; {
std::cerr << "p3GxsForums::dummy_tick() generateDummyMsgs() FAILED";
forum.mMeta.mPublishTs = now - (RSRandom::random_f32() * 100000); std::cerr << std::endl;
/* key fields to fill in: mGenActive = false;
* GroupId. }
* Name. return;
* Flags. }
* Pop.
*/ if (mGenCount < MAX_GEN_GROUPS)
{
/* get the group Id */
RsGxsGroupId groupId;
/* use probability to decide which are subscribed / own / popularity. RsGxsMessageId emptyId;
*/ if (!acknowledgeTokenGrp(mGenToken, groupId))
{
float rnd = RSRandom::random_f32(); std::cerr << " ERROR ";
if (rnd < 0.1) std::cerr << std::endl;
{ mGenActive = false;
forum.mMeta.mSubscribeFlags = RSGXS_GROUP_SUBSCRIBE_ADMIN; return;
}
}
else if (rnd < 0.3) std::cerr << "p3GxsForums::dummy_tick() Acknowledged GroupId: " << groupId;
{ std::cerr << std::endl;
forum.mMeta.mSubscribeFlags = RSGXS_GROUP_SUBSCRIBE_SUBSCRIBED;
} ForumDummyRef ref(groupId, emptyId, emptyId);
else mGenRefs[mGenCount] = ref;
{ }
forum.mMeta.mSubscribeFlags = 0; else if (mGenCount < MAX_GEN_MESSAGES)
} {
/* get the msg Id, and generate next snapshot */
forum.mMeta.mPop = (int) (RSRandom::random_f32() * 10.0); RsGxsGrpMsgIdPair msgId;
if (!acknowledgeTokenMsg(mGenToken, msgId))
mGroups.push_back(forum); {
std::cerr << " ERROR ";
std::cerr << std::endl;
//std::cerr << "p3GxsForums::generateDummyData() Generated Forum: " << forum.mMeta; mGenActive = false;
//std::cerr << std::endl; return;
} }
std::cerr << "p3GxsForums::dummy_tick() Acknowledged <GroupId: " << msgId.first << ", MsgId: " << msgId.second << ">";
for(i = 0; i < MAX_THREADS; i++) std::cerr << std::endl;
{
/* generate a base thread */ /* store results for later selection */
/* rotate the Forum Groups Around, then pick one. ForumDummyRef ref(msgId.first, mGenThreadId, msgId.second);
*/ mGenRefs[mGenCount] = ref;
}
int rnd = (int) (RSRandom::random_f32() * 10.0); else
{
for(j = 0; j < rnd; j++) std::cerr << "p3GxsForums::dummy_tick() Finished";
{ std::cerr << std::endl;
RsForumV2Group head = mGroups.front();
mGroups.pop_front(); /* done */
mGroups.push_back(head); mGenActive = false;
} return;
}
RsForumV2Group forum = mGroups.front();
mGenCount++;
/* now create a new thread */
if (mGenCount < MAX_GEN_GROUPS)
RsForumV2Msg msg; {
std::string groupName;
/* fill in key data rs_sprintf(groupName, "TestForum_%d", mGenCount);
* GroupId
* MsgId std::cerr << "p3GxsForums::dummy_tick() Generating Group: " << groupName;
* OrigMsgId std::cerr << std::endl;
* ThreadId
* ParentId /* create a new group */
* PublishTS (take Forum TS + a bit ). generateGroup(mGenToken, groupName);
* }
* ChildTS ???? else
*/ {
snprintf(name, DUMMY_NAME_MAX_LEN, "%s => ThreadMsg_%d", forum.mMeta.mGroupName.c_str(), i+1); /* create a new message */
msg.mMeta.mMsgName = name; uint32_t idx = (uint32_t) (mGenCount * RSRandom::random_f32());
ForumDummyRef &ref = mGenRefs[idx];
msg.mMeta.mGroupId = forum.mMeta.mGroupId;
msg.mMeta.mMsgId = genRandomId(); RsGxsGroupId grpId = ref.mGroupId;
msg.mMeta.mOrigMsgId = msg.mMeta.mMsgId; RsGxsMessageId parentId = ref.mMsgId;
msg.mMeta.mThreadId = msg.mMeta.mMsgId; mGenThreadId = ref.mThreadId;
msg.mMeta.mParentId = ""; if (mGenThreadId.empty())
{
msg.mMeta.mPublishTs = forum.mMeta.mPublishTs + (RSRandom::random_f32() * 10000); mGenThreadId = parentId;
if (msg.mMeta.mPublishTs > now) }
msg.mMeta.mPublishTs = now - 1;
std::cerr << "p3GxsForums::dummy_tick() Generating Msg ... ";
mMsgs.push_back(msg); std::cerr << " GroupId: " << grpId;
std::cerr << " ThreadId: " << mGenThreadId;
//std::cerr << "p3GxsForums::generateDummyData() Generated Thread: " << msg.mMeta; std::cerr << " ParentId: " << parentId;
//std::cerr << std::endl; std::cerr << std::endl;
} generateMessage(mGenToken, grpId, parentId, mGenThreadId);
}
for(i = 0; i < MAX_MSGS; i++) }
{ }
/* generate a base thread */
/* rotate the Forum Groups Around, then pick one. bool p3GxsForums::generateMessage(uint32_t &token, const RsGxsGroupId &grpId, const RsGxsMessageId &parentId, const RsGxsMessageId &threadId)
*/ {
RsGxsForumMsg msg;
int rnd = (int) (RSRandom::random_f32() * 10.0);
std::string rndId = genRandomId();
for(j = 0; j < rnd; j++)
{ rs_sprintf(msg.mMsg, "Forum Msg: GroupId: %s, ThreadId: %s, ParentId: %s + some randomness: %s",
RsForumV2Msg head = mMsgs.front(); grpId.c_str(), threadId.c_str(), parentId.c_str(), rndId.c_str());
mMsgs.pop_front();
mMsgs.push_back(head); msg.mMeta.mMsgName = msg.mMsg;
}
msg.mMeta.mGroupId = grpId;
RsForumV2Msg parent = mMsgs.front(); msg.mMeta.mThreadId = threadId;
msg.mMeta.mParentId = parentId;
/* now create a new child msg */
createMsg(token, msg);
RsForumV2Msg msg;
return true;
/* fill in key data }
* GroupId
* MsgId
* OrigMsgId bool p3GxsForums::generateGroup(uint32_t &token, std::string groupName)
* ThreadId {
* ParentId /* generate a new forum */
* PublishTS (take Forum TS + a bit ). RsGxsForumGroup forum;
* forum.mMeta.mGroupName = groupName;
* ChildTS ????
*/ createGroup(token, forum);
snprintf(name, DUMMY_NAME_MAX_LEN, "%s => Msg_%d", parent.mMeta.mMsgName.c_str(), i+1);
msg.mMeta.mMsgName = name;
msg.mMsg = name;
msg.mMeta.mGroupId = parent.mMeta.mGroupId;
msg.mMeta.mMsgId = genRandomId();
msg.mMeta.mOrigMsgId = msg.mMeta.mMsgId;
msg.mMeta.mThreadId = parent.mMeta.mThreadId;
msg.mMeta.mParentId = parent.mMeta.mOrigMsgId;
msg.mMeta.mPublishTs = parent.mMeta.mPublishTs + (RSRandom::random_f32() * 10000);
if (msg.mMeta.mPublishTs > now)
msg.mMeta.mPublishTs = now - 1;
mMsgs.push_back(msg);
//std::cerr << "p3GxsForums::generateDummyData() Generated Child Msg: " << msg.mMeta;
//std::cerr << std::endl;
}
mUpdated = true;
/* Then - at the end, we push them all into the Proxy */
for(git = mGroups.begin(); git != mGroups.end(); git++)
{
/* pushback */
mForumProxy->addForumGroup(*git);
}
for(mit = mMsgs.begin(); mit != mMsgs.end(); mit++)
{
/* pushback */
mForumProxy->addForumMsg(*mit);
}
return true; return true;
} }
#endif

View File

@ -52,6 +52,7 @@ virtual void service_tick();
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsForumGroup> &groups); virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsForumGroup> &groups);
virtual bool getMsgData(const uint32_t &token, std::vector<RsGxsForumMsg> &msgs); virtual bool getMsgData(const uint32_t &token, std::vector<RsGxsForumMsg> &msgs);
virtual bool getRelatedMessages(const uint32_t &token, std::vector<RsGxsForumMsg> &msgs);
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read); virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read);
@ -65,10 +66,34 @@ virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgI
virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group); virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group);
virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg); virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg);
virtual bool generateDummyData();
private: private:
std::string genRandomId(); std::string genRandomId();
bool generateDummyData();
void dummy_tick();
bool generateMessage(uint32_t &token, const RsGxsGroupId &grpId,
const RsGxsMessageId &parentId, const RsGxsMessageId &threadId);
bool generateGroup(uint32_t &token, std::string groupName);
class ForumDummyRef
{
public:
ForumDummyRef() { return; }
ForumDummyRef(const RsGxsGroupId &grpId, const RsGxsMessageId &threadId, const RsGxsMessageId &msgId)
:mGroupId(grpId), mThreadId(threadId), mMsgId(msgId) { return; }
RsGxsGroupId mGroupId;
RsGxsMessageId mThreadId;
RsGxsMessageId mMsgId;
};
uint32_t mGenToken;
bool mGenActive;
int mGenCount;
std::vector<ForumDummyRef> mGenRefs;
RsGxsMessageId mGenThreadId;
}; };

View File

@ -330,13 +330,13 @@ const std::string improvements_txt[] =
" - Diffs, lots of edits will lead to complex merges - a robust merge tool is essential\n", " - Diffs, lots of edits will lead to complex merges - a robust merge tool is essential\n",
" - Read Mode... hide all the Edits, and only show the most recently published versions\n", " - Read Mode... hide all the Edits, and only show the most recently published versions\n",
" - Easy Duplication - to take over an Abandoned or badly moderated Wiki. Copies All base versions to a new group\n", " - Easy Duplication - to take over an Abandoned or badly moderated Wiki. Copies All base versions to a new group\n",
" - WikiLinks. A generic Wiki Cross Linking system. This should be combined with Easy Duplication option,\n", " - WikiLinks. A generic Wiki Cross Linking system. This should be combined with Easy Duplication option,",
" to allow easy replacement of groups if necessary... A good design here is critical to a successful Wiki ecosystem", " to allow easy replacement of groups if necessary... A good design here is critical to a successful Wiki ecosystem\n",
" the republished page becomes a new version of the Root Page, allowing more edits to be done\n",
" - work out how to include media (photos, audio, video, etc) without embedding in pages", " - work out how to include media (photos, audio, video, etc) without embedding in pages",
" this would leverage the turtle transfer system somehow - maybe like channels.\n", " this would leverage the turtle transfer system somehow - maybe like channels.\n",
" - Comments, reviews etc can be incorporated - ideas here are welcome.\n", " - Comments, reviews etc can be incorporated - ideas here are welcome.\n",
" - Any other suggestion???" " - Any other suggestion???",
" - Come on more ideas!"
}; };