Line data Source code
1 : #ifndef RESILIENTNETWORKREPLY_H
2 : #define RESILIENTNETWORKREPLY_H
3 :
4 : #include <QNetworkReply>
5 : #include <QTimer>
6 : #include <QElapsedTimer>
7 : #include "NetworkRetryPolicy.h"
8 :
9 : class FangNetworkAccessManager;
10 :
11 : /**
12 : * @brief Wraps a QNetworkReply with timeout/retry logic.
13 : */
14 : class ResilientNetworkReply : public QObject
15 : {
16 : Q_OBJECT
17 :
18 : public:
19 : ResilientNetworkReply(FangNetworkAccessManager* manager,
20 : const QNetworkRequest& request,
21 : QNetworkAccessManager::Operation operation,
22 : const NetworkRetryPolicy& policy,
23 : QObject* parent = nullptr);
24 :
25 : ~ResilientNetworkReply();
26 :
27 : /**
28 : * @brief Starts our network request.
29 : */
30 : void start();
31 :
32 : /**
33 : * @brief Aborts our request.
34 : */
35 : void abort();
36 :
37 : /**
38 : * @brief Returns out QNetworkReply.
39 : */
40 : QNetworkReply* reply() const { return currentReply; }
41 :
42 : /**
43 : * @brief Returns the final URL (may have redirected)
44 : */
45 : QUrl url() const;
46 :
47 : /**
48 : * @brief Returns all data received (wait until complete to get all of it)
49 : */
50 : QByteArray readAll();
51 :
52 : /**
53 : * @brief Returns true if request completed without errors.
54 : */
55 13 : bool isSuccess() const { return isSuccessful; }
56 :
57 : /**
58 : * @brief Returns the last error.
59 : */
60 1 : QNetworkReply::NetworkError error() const { return lastError; }
61 :
62 : /**
63 : * @brief Returns the error as a string.
64 : */
65 : QString errorString() const;
66 :
67 : /**
68 : * @brief Returns number of attempts made.
69 : */
70 10 : int attemptCount() const { return currentAttemptCount; }
71 :
72 : /**
73 : * @brief Returns true if data was cached.
74 : */
75 : bool isFromCache() const { return fromCache; }
76 :
77 : /**
78 : * @brief Returns HTTP status code, if available.
79 : */
80 : int httpStatusCode() const;
81 :
82 : /**
83 : * @brief Sets a custom timeout in ms.
84 : */
85 : void setTimeout(int timeout);
86 :
87 : signals:
88 :
89 :
90 : void finished();
91 :
92 : void failed(QNetworkReply::NetworkError error);
93 :
94 : void retrying(int attemptNumber, int delay);
95 :
96 : void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
97 :
98 : void timeout();
99 :
100 : private slots:
101 : void onReplyFinished();
102 : void onReplyError(QNetworkReply::NetworkError error);
103 : void onTimeout();
104 : void onRetryTimerTimeout();
105 : void onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal);
106 :
107 : private:
108 : void executeRequest();
109 : void scheduleRetry();
110 : void cleanup();
111 :
112 : FangNetworkAccessManager* networkManager;
113 : QNetworkRequest networkRequest;
114 : QNetworkAccessManager::Operation operation;
115 : NetworkRetryPolicy retryPolicy;
116 :
117 : QNetworkReply* currentReply;
118 : QByteArray accumulatedData;
119 :
120 : QTimer timeoutTimer;
121 : QTimer retryTimer;
122 : QElapsedTimer requestTimer;
123 :
124 : int currentAttemptCount;
125 : int customTimeout; // -1 is default
126 : QNetworkReply::NetworkError lastError;
127 : QString lastErrorString;
128 : bool isSuccessful;
129 : bool fromCache;
130 : bool aborted;
131 :
132 : // Track errors across all attempts for debugging
133 : QList<QPair<int, QString>> errorHistory; // attempt number, error description
134 : };
135 :
136 : #endif // RESILIENTNETWORKREPLY_H
|