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