EventService: Add retry configuration support
This commit is to pass configuration parameters: retry attempts,
retry interval secs and retry policy to http client and take
required delivery retry policy action.
Also, perform async wait for retryTimeoutInterval before each
retry attempts.
Tested:
- Set and verified config properties by sending PATCH req on
EventService and EventDestination uri.
- Verified the appropriate delivery retry policy action block reached.
- Verified the async_wait logic by triggering retry case depending
failed state of connection.
- could see a wait for timeout interval before next retry.
Signed-off-by: Ayushi Smriti <smriti.ayushi@linux.intel.com>
Change-Id: Id1366fca59dc9e6543c553bfe5df95a59f468bc7
Signed-off-by: AppaRao Puli <apparao.puli@linux.intel.com>
diff --git a/http/http_client.hpp b/http/http_client.hpp
index 8b1fb5c..58086dd 100644
--- a/http/http_client.hpp
+++ b/http/http_client.hpp
@@ -42,13 +42,15 @@
recvFailed,
idle,
suspended,
- closed
+ closed,
+ terminated
};
class HttpClient : public std::enable_shared_from_this<HttpClient>
{
private:
boost::beast::tcp_stream conn;
+ boost::asio::steady_timer timer;
boost::beast::flat_buffer buffer;
boost::beast::http::request<boost::beast::http::string_body> req;
boost::beast::http::response<boost::beast::http::string_body> res;
@@ -56,11 +58,15 @@
std::vector<std::pair<std::string, std::string>> headers;
std::queue<std::string> requestDataQueue;
ConnState state;
+ std::string subId;
std::string host;
std::string port;
std::string uri;
- int retryCount;
- int maxRetryAttempts;
+ uint32_t retryCount;
+ uint32_t maxRetryAttempts;
+ uint32_t retryIntervalSecs;
+ std::string retryPolicyAction;
+ bool runningTimer;
void doConnect()
{
@@ -208,10 +214,23 @@
requestDataQueue.pop();
}
- // TODO: Take 'DeliveryRetryPolicy' action.
- // For now, doing 'SuspendRetries' action.
- state = ConnState::suspended;
- return;
+ BMCWEB_LOG_DEBUG << "Retry policy is set to " << retryPolicyAction;
+ if (retryPolicyAction == "TerminateAfterRetries")
+ {
+ // TODO: delete subscription
+ state = ConnState::terminated;
+ return;
+ }
+ else if (retryPolicyAction == "SuspendRetries")
+ {
+ state = ConnState::suspended;
+ return;
+ }
+ else
+ {
+ // keep retrying, reset count and continue.
+ retryCount = 0;
+ }
}
if ((state == ConnState::connectFailed) ||
@@ -226,20 +245,43 @@
return;
}
+ if (runningTimer)
+ {
+ BMCWEB_LOG_DEBUG << "Retry timer is already running.";
+ return;
+ }
+ runningTimer = true;
+
retryCount++;
- // TODO: Perform async wait for retryTimeoutInterval before proceed.
+
+ BMCWEB_LOG_DEBUG << "Attempt retry after " << retryIntervalSecs
+ << " seconds. RetryCount = " << retryCount;
+ timer.expires_after(std::chrono::seconds(retryIntervalSecs));
+ timer.async_wait([self = shared_from_this()](
+ const boost::system::error_code& ec) {
+ self->runningTimer = false;
+ self->connStateCheck();
+ });
+ return;
}
else
{
// reset retry count.
retryCount = 0;
}
+ connStateCheck();
+ return;
+ }
+
+ void connStateCheck()
+ {
switch (state)
{
case ConnState::connectInProgress:
case ConnState::sendInProgress:
case ConnState::suspended:
+ case ConnState::terminated:
// do nothing
break;
case ConnState::initialized:
@@ -263,22 +305,20 @@
default:
break;
}
-
- return;
}
public:
- explicit HttpClient(boost::asio::io_context& ioc, const std::string& destIP,
- const std::string& destPort,
+ explicit HttpClient(boost::asio::io_context& ioc, const std::string& id,
+ const std::string& destIP, const std::string& destPort,
const std::string& destUri) :
conn(ioc),
- host(destIP), port(destPort), uri(destUri)
+ timer(ioc), subId(id), host(destIP), port(destPort), uri(destUri),
+ retryCount(0), maxRetryAttempts(5),
+ retryPolicyAction("TerminateAfterRetries"), runningTimer(false)
{
boost::asio::ip::tcp::resolver resolver(ioc);
endpoint = resolver.resolve(host, port);
state = ConnState::initialized;
- retryCount = 0;
- maxRetryAttempts = 5;
}
void sendData(const std::string& data)
@@ -306,6 +346,18 @@
{
headers = httpHeaders;
}
+
+ void setRetryConfig(const uint32_t retryAttempts,
+ const uint32_t retryTimeoutInterval)
+ {
+ maxRetryAttempts = retryAttempts;
+ retryIntervalSecs = retryTimeoutInterval;
+ }
+
+ void setRetryPolicy(const std::string& retryPolicy)
+ {
+ retryPolicyAction = retryPolicy;
+ }
};
} // namespace crow