File indexing completed on 2025-01-05 04:37:12
0001 /* 0002 SPDX-FileCopyrightText: 2005 Joris Guisson <joris.guisson@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 #ifndef DHTTASK_H 0007 #define DHTTASK_H 0008 0009 #include "kbucket.h" 0010 #include "rpccall.h" 0011 #include "rpcserver.h" 0012 0013 namespace net 0014 { 0015 class AddressResolver; 0016 } 0017 0018 namespace dht 0019 { 0020 class Node; 0021 class Task; 0022 class KClosestNodesSearch; 0023 0024 const bt::Uint32 MAX_CONCURRENT_REQS = 16; 0025 0026 /** 0027 * @author Joris Guisson <joris.guisson@gmail.com> 0028 * 0029 * Performs a task on K nodes provided by a KClosestNodesSearch. 0030 * This is a base class for all tasks. 0031 */ 0032 class Task : public RPCCallListener 0033 { 0034 Q_OBJECT 0035 public: 0036 /** 0037 * Create a task. 0038 * @param rpc The RPC server to do RPC calls 0039 * @param node The node 0040 * @param parent The parent object 0041 */ 0042 Task(RPCServer *rpc, Node *node, QObject *parent); 0043 ~Task() override; 0044 0045 /** 0046 * This will copy the results from the KClosestNodesSearch 0047 * object into the todo list. And call update if the task is not queued. 0048 * @param kns The KClosestNodesSearch object 0049 * @param queued Is the task queued 0050 */ 0051 void start(const KClosestNodesSearch &kns, bool queued); 0052 0053 /** 0054 * Start the task, to be used when a task is queued. 0055 */ 0056 void start(); 0057 0058 /// Decrements the outstanding_reqs 0059 void onResponse(RPCCall *c, RPCMsg::Ptr rsp) override; 0060 0061 /// Decrements the outstanding_reqs 0062 void onTimeout(RPCCall *c) override; 0063 0064 /** 0065 * Will continue the task, this will be called every time we have 0066 * rpc slots available for this task. Should be implemented by derived classes. 0067 */ 0068 virtual void update() = 0; 0069 0070 /** 0071 * A call is finished and a response was received. 0072 * @param c The call 0073 * @param rsp The response 0074 */ 0075 virtual void callFinished(RPCCall *c, RPCMsg::Ptr rsp) = 0; 0076 0077 /** 0078 * A call timedout 0079 * @param c The call 0080 */ 0081 virtual void callTimeout(RPCCall *c) = 0; 0082 0083 /** 0084 * Do a call to the rpc server, increments the outstanding_reqs variable. 0085 * @param req THe request to send 0086 * @return true if call was made, false if not 0087 */ 0088 bool rpcCall(RPCMsg::Ptr req); 0089 0090 /// See if we can do a request 0091 bool canDoRequest() const 0092 { 0093 return outstanding_reqs < MAX_CONCURRENT_REQS; 0094 } 0095 0096 /// Is the task finished 0097 bool isFinished() const 0098 { 0099 return task_finished; 0100 } 0101 0102 /// Get the number of outstanding requests 0103 bt::Uint32 getNumOutstandingRequests() const 0104 { 0105 return outstanding_reqs; 0106 } 0107 0108 bool isQueued() const 0109 { 0110 return queued; 0111 } 0112 0113 /** 0114 * Tell listeners data is ready. 0115 */ 0116 void emitDataReady(); 0117 0118 /// Kills the task 0119 void kill(); 0120 0121 /** 0122 * Add a node to the todo list 0123 * @param ip The ip or hostname of the node 0124 * @param port The port 0125 */ 0126 void addDHTNode(const QString &ip, bt::Uint16 port); 0127 0128 Q_SIGNALS: 0129 /** 0130 * The task is finsihed. 0131 * @param t The Task 0132 */ 0133 void finished(Task *t); 0134 0135 /** 0136 * Called by the task when data is ready. 0137 * Can be overrided if wanted. 0138 * @param t The Task 0139 */ 0140 void dataReady(Task *t); 0141 0142 protected: 0143 void done(); 0144 0145 protected Q_SLOTS: 0146 void onResolverResults(net::AddressResolver *res); 0147 0148 protected: 0149 dht::KBucketEntrySet visited; // nodes visited 0150 dht::KBucketEntrySet todo; // nodes todo 0151 Node *node; 0152 0153 private: 0154 RPCServer *rpc; 0155 bt::Uint32 outstanding_reqs; 0156 bool task_finished; 0157 bool queued; 0158 }; 0159 0160 } 0161 0162 #endif