mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-01-14 00:49:41 -05:00
286 lines
12 KiB
C++
286 lines
12 KiB
C++
/*******************************************************************************
|
|
* libretroshare/src/retroshare: rstokenservice.h *
|
|
* *
|
|
* libretroshare: retroshare core library *
|
|
* *
|
|
* Copyright (C) 2012 Chris Evi-Parker *
|
|
* Copyright (C) 2012 Robert Fernie <retroshare@lunamutt.com> *
|
|
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
|
|
* *
|
|
* This program is free software: you can redistribute it and/or modify *
|
|
* it under the terms of the GNU Lesser General Public License as *
|
|
* published by the Free Software Foundation, either version 3 of the *
|
|
* License, or (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU Lesser General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU Lesser General Public License *
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
|
* *
|
|
*******************************************************************************/
|
|
#pragma once
|
|
|
|
#include <inttypes.h>
|
|
#include <string>
|
|
#include <list>
|
|
|
|
#include "retroshare/rsgxsifacetypes.h"
|
|
#include "util/rsdeprecate.h"
|
|
#include "util/rsdebug.h"
|
|
|
|
// TODO CLEANUP: GXS_REQUEST_TYPE_* should be an inner enum of RsTokReqOptions
|
|
#define GXS_REQUEST_TYPE_GROUP_DATA 0x00010000
|
|
#define GXS_REQUEST_TYPE_GROUP_META 0x00020000
|
|
#define GXS_REQUEST_TYPE_GROUP_IDS 0x00040000
|
|
#define GXS_REQUEST_TYPE_MSG_DATA 0x00080000
|
|
#define GXS_REQUEST_TYPE_MSG_META 0x00100000
|
|
#define GXS_REQUEST_TYPE_MSG_IDS 0x00200000
|
|
|
|
#define GXS_REQUEST_TYPE_MSG_RELATED_DATA 0x00400000
|
|
#define GXS_REQUEST_TYPE_MSG_RELATED_META 0x00800000
|
|
#define GXS_REQUEST_TYPE_MSG_RELATED_IDS 0x01000000
|
|
|
|
#define GXS_REQUEST_TYPE_GROUP_STATS 0x01600000
|
|
#define GXS_REQUEST_TYPE_SERVICE_STATS 0x03200000
|
|
#define GXS_REQUEST_TYPE_GROUP_SERIALIZED_DATA 0x04000000
|
|
|
|
|
|
// TODO CLEANUP: RS_TOKREQOPT_MSG_* should be an inner enum of RsTokReqOptions
|
|
#define RS_TOKREQOPT_MSG_VERSIONS 0x0001 // MSGRELATED: Returns All MsgIds with OrigMsgId = MsgId.
|
|
#define RS_TOKREQOPT_MSG_ORIGMSG 0x0002 // MSGLIST: All Unique OrigMsgIds in a Group.
|
|
#define RS_TOKREQOPT_MSG_LATEST 0x0004 // MSGLIST: All Latest MsgIds in Group. MSGRELATED: Latest MsgIds for Input Msgs.
|
|
#define RS_TOKREQOPT_MSG_THREAD 0x0010 // MSGRELATED: All Msgs in Thread. MSGLIST: All Unique Thread Ids in Group.
|
|
#define RS_TOKREQOPT_MSG_PARENT 0x0020 // MSGRELATED: All Children Msgs.
|
|
#define RS_TOKREQOPT_MSG_AUTHOR 0x0040 // MSGLIST: Messages from this AuthorId
|
|
|
|
|
|
/* TODO CLEANUP: RS_TOKREQ_ANSTYPE_* values are meaningless and not used by
|
|
* RsTokenService or its implementation, and may be arbitrarly defined by each
|
|
* GXS client as they are of no usage, their use is deprecated, up until the
|
|
* definitive cleanup is done new code must use RS_DEPRECATED_TOKREQ_ANSTYPE for
|
|
* easier cleanup. */
|
|
#ifndef RS_NO_WARN_DEPRECATED
|
|
# warning RS_TOKREQ_ANSTYPE_* macros are deprecated!
|
|
#endif
|
|
#define RS_DEPRECATED_TOKREQ_ANSTYPE 0x0000
|
|
#define RS_TOKREQ_ANSTYPE_LIST 0x0001
|
|
#define RS_TOKREQ_ANSTYPE_SUMMARY 0x0002
|
|
#define RS_TOKREQ_ANSTYPE_DATA 0x0003
|
|
#define RS_TOKREQ_ANSTYPE_ACK 0x0004
|
|
|
|
|
|
/*!
|
|
* This class provides useful generic support for GXS style services.
|
|
* I expect much of this will be incorporated into the base GXS.
|
|
*/
|
|
struct RsTokReqOptions
|
|
{
|
|
RsTokReqOptions() : mOptions(0), mStatusFilter(0), mStatusMask(0),
|
|
mMsgFlagMask(0), mMsgFlagFilter(0), mReqType(0), mSubscribeFilter(0),
|
|
mSubscribeMask(0), mBefore(0), mAfter(0),mPriority(GxsRequestPriority::NORMAL) {}
|
|
|
|
/**
|
|
* Can be one or multiple RS_TOKREQOPT_*
|
|
* TODO: cleanup this should be made with proper flags instead of macros
|
|
*/
|
|
uint32_t mOptions;
|
|
|
|
// Request specific matches with Group / Message Status.
|
|
// Should be usable with any Options... applied afterwards.
|
|
uint32_t mStatusFilter;
|
|
uint32_t mStatusMask;
|
|
|
|
// use
|
|
uint32_t mMsgFlagMask, mMsgFlagFilter;
|
|
|
|
/**
|
|
* Must be one of GXS_REQUEST_TYPE_*
|
|
* TODO: cleanup this should be made an enum instead of macros
|
|
*/
|
|
uint32_t mReqType;
|
|
|
|
uint32_t mSubscribeFilter, mSubscribeMask; // Only for Groups.
|
|
|
|
// Time range... again applied after Options.
|
|
rstime_t mBefore;
|
|
rstime_t mAfter;
|
|
|
|
GxsRequestPriority mPriority;
|
|
};
|
|
|
|
/*!
|
|
* A proxy class for requesting generic service data for GXS
|
|
* This seperates the request mechanism from the actual retrieval of data
|
|
*/
|
|
class RsTokenService
|
|
{
|
|
public:
|
|
|
|
enum GxsRequestStatus : uint8_t
|
|
{
|
|
FAILED = 0,
|
|
PENDING = 1,
|
|
PARTIAL = 2,
|
|
COMPLETE = 3,
|
|
DONE = 4, /// Once all data has been retrived
|
|
CANCELLED = 5
|
|
};
|
|
|
|
RsTokenService() {}
|
|
virtual ~RsTokenService() {}
|
|
|
|
/* Data Requests */
|
|
|
|
/*!
|
|
* Use this to request group related information
|
|
* @param token The token returned for the request, store this value to poll for request completion
|
|
* @param ansType The type of result (e.g. group data, meta, ids)
|
|
* @param opts Additional option that affect outcome of request. Please see specific services, for valid values
|
|
* @param groupIds group id to request info for
|
|
* @return
|
|
*/
|
|
virtual bool requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<RsGxsGroupId> &groupIds) = 0;
|
|
|
|
/*!
|
|
* Use this to request all group related info
|
|
* @param token The token returned for the request, store this value to poll for request completion
|
|
* @param ansType The type of result (e.g. group data, meta, ids)
|
|
* @param opts Additional option that affect outcome of request. Please see specific services, for valid values
|
|
* @return
|
|
*/
|
|
virtual bool requestGroupInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts) = 0;
|
|
|
|
/*!
|
|
* Use this to get msg related information, store this value to poll for request completion
|
|
* @param token The token returned for the request
|
|
* @param ansType The type of result wanted
|
|
* @param opts Additional option that affect outcome of request. Please see specific services, for valid values
|
|
* @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs
|
|
* @return true if request successful false otherwise
|
|
*/
|
|
virtual bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const GxsMsgReq& msgIds) = 0;
|
|
|
|
/*!
|
|
* Use this to get msg related information, store this value to poll for request completion
|
|
* @param token The token returned for the request
|
|
* @param ansType The type of result wanted
|
|
* @param opts Additional option that affect outcome of request. Please see specific services, for valid values
|
|
* @param groupIds The ids of the groups to get, this retrieves all the msgs info for each grpId in list
|
|
* @return true if request successful false otherwise
|
|
*/
|
|
virtual bool requestMsgInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::list<RsGxsGroupId>& grpIds) = 0;
|
|
|
|
/*!
|
|
* For requesting msgs related to a given msg id within a group
|
|
* @param token The token returned for the request
|
|
* @param ansType The type of result wanted
|
|
* @param opts Additional option that affect outcome of request. Please see specific services, for valid values
|
|
* @param groupIds The ids of the groups to get, second entry of map empty to query for all msgs
|
|
* @return true if request successful false otherwise
|
|
*/
|
|
virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptions &opts, const std::vector<RsGxsGrpMsgIdPair>& msgIds) = 0;
|
|
|
|
/*!
|
|
* This request statistics on amount of data held
|
|
* number of groups
|
|
* number of groups subscribed
|
|
* number of messages
|
|
* size of db store
|
|
* total size of messages
|
|
* total size of groups
|
|
* @param token
|
|
*/
|
|
virtual void requestServiceStatistic(uint32_t& token, const RsTokReqOptions &opts) = 0;
|
|
|
|
/*!
|
|
* To request statistic on a group
|
|
* @param token set to value to be redeemed to get statistic
|
|
* @param grpId the id of the group
|
|
*/
|
|
virtual void requestGroupStatistic(uint32_t& token, const RsGxsGroupId& grpId, const RsTokReqOptions &opts) = 0;
|
|
|
|
|
|
/* Poll */
|
|
|
|
/*!
|
|
* Request the status of ongoing request.
|
|
* Please use this for polling as much cheaper
|
|
* than polling the specific service as they might
|
|
* not return intermediate status information
|
|
* @param token value of token to check status for
|
|
* @return the current status of request
|
|
*/
|
|
virtual GxsRequestStatus requestStatus(const uint32_t token) = 0;
|
|
|
|
/*!
|
|
* @brief Cancel Request
|
|
* If this function returns false, it may be that the request has completed
|
|
* already. Useful for very expensive request.
|
|
* @param token the token of the request to cancel
|
|
* @return false if unusuccessful in cancelling request, true if successful
|
|
*/
|
|
virtual bool cancelRequest(const uint32_t &token) = 0;
|
|
|
|
#ifdef TO_REMOVE
|
|
/**
|
|
* Block caller while request is being processed.
|
|
* Useful for blocking API implementation.
|
|
* @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
|
|
*/
|
|
RsTokenService::GxsRequestStatus waitToken(
|
|
uint32_t token,
|
|
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();
|
|
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
|
|
|
|
return st;
|
|
}
|
|
#endif
|
|
|
|
RS_SET_CONTEXT_DEBUG_LEVEL(2)
|
|
};
|