Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
---
Checks: >
boost-*,
bugprone-*,
clang-analyzer-*,
cppcoreguidelines-*,
modernize-*,
performance-*,
portability-*,
readability-*,
-bugprone-unchecked-optional-access,
-cppcoreguidelines-avoid-magic-numbers,
-modernize-use-trailing-return-type,
-readability-identifier-length,
-readability-magic-numbers
CheckOptions:
- { key: readability-identifier-length.IgnoredParameterNames, value: 'i|j|k|c|os|it' }
- { key: readability-identifier-length.IgnoredVariableNames, value: 'ec|id|it' }
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/cpp-linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ jobs:
style: file
# The file extensions to run the action against. This comma-separated string defaults to 'c,h,C,H,cpp,hpp,cc,hh,c++,h++,cxx,hxx'.
# extensions: # optional, default is c,h,C,H,cpp,hpp,cc,hh,c++,h++,cxx,hxx
# A string of regex-like patterns specifying what checks clang-tidy will use. This defaults to 'boost-*,bugprone-*,performance-*,readability-*,portability-*,modernize-*,clang-analyzer-*,cppcoreguidelines-*'. See also clang-tidy docs for more info.
tidy-checks: boost-*,bugprone-*,performance-*,readability-*,portability-*,modernize-*,-modernize-use-trailing-return-type,clang-analyzer-*,cppcoreguidelines-*
# A blank string makes clang-tidy use only the checks in .clang-tidy files.
tidy-checks: ''
# The relative path to the repository root directory. The default value '.' is relative to the runner's GITHUB_WORKSPACE environment variable.
# repo-root: # optional, default is .
# The desired version of the clang tools to use. Accepted options are strings which can be 15, 14, 13, 12, 11, 10, 9, or 8. Defaults to 12.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@
inline constexpr bool always_false_v = false;

FDv2StreamingSynchronizer::State::State(
Logger const& logger,

Check warning on line 42 in libs/client-sdk/src/data_sources/fdv2/streaming_synchronizer.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

libs/client-sdk/src/data_sources/fdv2/streaming_synchronizer.cpp:42:5 [modernize-pass-by-value]

pass by value and use std::move
boost::asio::any_io_executor const& executor,
FDv2RequestConfig const& stream_config,

Check warning on line 44 in libs/client-sdk/src/data_sources/fdv2/streaming_synchronizer.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

libs/client-sdk/src/data_sources/fdv2/streaming_synchronizer.cpp:44:5 [modernize-pass-by-value]

pass by value and use std::move

Check warning on line 44 in libs/client-sdk/src/data_sources/fdv2/streaming_synchronizer.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

libs/client-sdk/src/data_sources/fdv2/streaming_synchronizer.cpp:44:5 [bugprone-easily-swappable-parameters]

2 adjacent parameters of 'State' of similar type ('const launchdarkly::client_side::data_sources::FDv2RequestConfig &') are easily swapped by mistake
FDv2RequestConfig const& poll_config,
std::chrono::milliseconds initial_reconnect_delay)
: logger_(logger),
Expand All @@ -51,9 +51,9 @@
executor_(executor),
requester_(executor, poll_config.http_properties.Tls()) {}

void FDv2StreamingSynchronizer::State::EnsureStarted(

Check warning on line 54 in libs/client-sdk/src/data_sources/fdv2/streaming_synchronizer.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

libs/client-sdk/src/data_sources/fdv2/streaming_synchronizer.cpp:54:40 [readability-function-cognitive-complexity]

function 'EnsureStarted' has cognitive complexity of 26 (threshold 25)
data_model::Selector const& selector,
std::shared_ptr<State> self) {

Check warning on line 56 in libs/client-sdk/src/data_sources/fdv2/streaming_synchronizer.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

libs/client-sdk/src/data_sources/fdv2/streaming_synchronizer.cpp:56:28 [performance-unnecessary-value-param]

the parameter 'self' is copied for each invocation but only used as a const reference; consider making it a const reference
{
std::lock_guard lock(mutex_);
latest_selector_ = selector;
Expand Down Expand Up @@ -150,10 +150,10 @@
});
builder.logger([weak](std::string msg) {
if (auto s = weak.lock()) {
LD_LOG(s->logger_, LogLevel::kDebug) << "sse-client: " << msg;

Check warning on line 153 in libs/client-sdk/src/data_sources/fdv2/streaming_synchronizer.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

libs/client-sdk/src/data_sources/fdv2/streaming_synchronizer.cpp:153:71 [performance-unnecessary-value-param]

parameter 'msg' is passed by value and only copied once; consider moving it to avoid unnecessary copies
}
});
builder.errors([weak](sse::Error error) {

Check warning on line 156 in libs/client-sdk/src/data_sources/fdv2/streaming_synchronizer.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

libs/client-sdk/src/data_sources/fdv2/streaming_synchronizer.cpp:156:38 [performance-unnecessary-value-param]

the parameter 'error' is copied for each invocation but only used as a const reference; consider making it a const reference
if (auto s = weak.lock()) {
s->OnError(error);
}
Expand Down Expand Up @@ -193,7 +193,7 @@
auto read = ReadFDv2ResponseHeaders(headers);

std::lock_guard lock(mutex_);
latest_fdv1_fallback_ = std::move(read.fdv1_fallback);

Check warning on line 196 in libs/client-sdk/src/data_sources/fdv2/streaming_synchronizer.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

libs/client-sdk/src/data_sources/fdv2/streaming_synchronizer.cpp:196:29 [performance-move-const-arg]

std::move of the expression of the trivially-copyable type 'std::optional<FDv1FallbackDirective>' has no effect; remove std::move()
if (read.environment_id) {
latest_environment_id_ = std::move(read.environment_id);
}
Expand Down Expand Up @@ -232,7 +232,7 @@
});
}

void FDv2StreamingSynchronizer::State::OnEvent(sse::Event const& event) {

Check warning on line 235 in libs/client-sdk/src/data_sources/fdv2/streaming_synchronizer.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

libs/client-sdk/src/data_sources/fdv2/streaming_synchronizer.cpp:235:40 [readability-function-cognitive-complexity]

function 'OnEvent' has cognitive complexity of 34 (threshold 25)
if (event.type() == kPingEvent) {
PollForPing(shared_from_this());
return;
Expand Down Expand Up @@ -309,11 +309,14 @@
} else if constexpr (std::is_same_v<T,
FDv2ProtocolHandler::Error>) {
if (r.kind == FDv2ProtocolHandler::Error::Kind::kServerError) {
auto const& id = r.server_error.value().id;
std::string id;
if (r.server_error) {
id = r.server_error->id.value_or("");
}
std::string msg =
"An issue was encountered receiving updates for "
"payload '" +
id.value_or("") + "' with reason: '" + r.message +
id + "' with reason: '" + r.message +
"'. Automatic retry will occur.";
LD_LOG(logger_, LogLevel::kInfo)
<< kIdentity << ": " << msg;
Expand Down
11 changes: 9 additions & 2 deletions libs/client-sdk/src/data_sources/polling_data_source.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <boost/json.hpp>
#include <boost/asio/error.hpp>
#include <boost/asio/post.hpp>
#include <boost/json.hpp>

#include <launchdarkly/client_side/data_source_status.hpp>
#include <launchdarkly/config/shared/builders/http_properties_builder.hpp>
Expand Down Expand Up @@ -66,7 +66,7 @@
config::shared::built::DataSourceConfig<config::shared::ClientSDK> const&
data_source_config,
config::shared::built::HttpProperties const& http_properties,
boost::asio::any_io_executor ioc,

Check warning on line 69 in libs/client-sdk/src/data_sources/polling_data_source.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

libs/client-sdk/src/data_sources/polling_data_source.cpp:69:34 [performance-unnecessary-value-param]

the parameter 'ioc' is copied for each invocation but only used as a const reference; consider making it a const reference
Context const& context,
IDataSourceUpdateSink& handler,
DataSourceStatusManager& status_manager,
Expand Down Expand Up @@ -148,7 +148,14 @@
<< "Polling for feature flag updates failed: "
<< (res.ErrorMessage() ? *res.ErrorMessage() : "unknown error");
} else if (res.Status() == 200) {
data_source_handler_.HandleMessage("put", res.Body().value());
if (res.Body()) {
data_source_handler_.HandleMessage("put", *res.Body());
} else {
status_manager_.SetState(
DataSourceStatus::DataSourceState::kInterrupted,
DataSourceStatus::ErrorInfo::ErrorKind::kUnknown,
"Polling response contained no body");
}
} else if (res.Status() == 304) {
// This should be handled ahead of here, but if we get a 304,
// and it didn't have an etag, we still don't want to try to
Expand Down
7 changes: 5 additions & 2 deletions libs/server-sdk/src/data_systems/fdv2/fdv2_polling_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,14 @@ static FDv2SourceResult ParseFDv2PollEvents(
}
if (auto* error = std::get_if<FDv2ProtocolHandler::Error>(&result)) {
if (error->kind == FDv2ProtocolHandler::Error::Kind::kServerError) {
auto const& id = error->server_error.value().id;
std::string id;
if (error->server_error) {
id = error->server_error->id.value_or("");
}
std::string msg =
"An issue was encountered receiving updates for "
"payload '" +
id.value_or("") + "' with reason: '" + error->message +
id + "' with reason: '" + error->message +
"'. Automatic retry will occur.";
return FDv2SourceResult{FDv2SourceResult::Interrupted{
MakeError(ErrorKind::kErrorResponse, 0, std::move(msg))}};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,11 +272,14 @@ void FDv2StreamingSynchronizer::State::OnEvent(sse::Event const& event) {
} else if constexpr (std::is_same_v<T,
FDv2ProtocolHandler::Error>) {
if (r.kind == FDv2ProtocolHandler::Error::Kind::kServerError) {
auto const& id = r.server_error.value().id;
std::string id;
if (r.server_error) {
id = r.server_error->id.value_or("");
}
std::string msg =
"An issue was encountered receiving updates for "
"payload '" +
id.value_or("") + "' with reason: '" + r.message +
id + "' with reason: '" + r.message +
"'. Automatic retry will occur.";
LD_LOG(logger_, LogLevel::kInfo)
<< kIdentity << ": " << msg;
Expand Down
10 changes: 7 additions & 3 deletions libs/server-sdk/src/evaluation/rules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "../data_components/big_segments/big_segment_store_wrapper.hpp"

#include <cstdint>
#include <optional>
#include <string>
#include <utility>
Expand All @@ -30,8 +31,9 @@ enum EvaluationReason::BigSegmentsStatus ToBigSegmentsStatus(
return EvaluationReason::BigSegmentsStatus::kHealthy;
}

std::string MakeBigSegmentRef(Segment const& segment) {
return segment.key + ".g" + std::to_string(*segment.generation);
std::string MakeBigSegmentRef(std::string const& key,
std::uint64_t generation) {
return key + ".g" + std::to_string(generation);
}

// Evaluates membership in an unbounded (Big) segment. Returns true/false for a
Expand All @@ -46,6 +48,7 @@ std::optional<bool> MatchBigSegment(Segment const& segment,
EvaluationReason::BigSegmentsStatus::kNotConfigured);
return false;
}
std::uint64_t const generation = *segment.generation;

// An absent or empty unboundedContextKind defaults to "user".
ContextKind const kind = (segment.unboundedContextKind &&
Expand Down Expand Up @@ -81,7 +84,8 @@ std::optional<bool> MatchBigSegment(Segment const& segment,
membership = stack.FindMembership(key);
}

return membership->CheckMembership(MakeBigSegmentRef(segment));
return membership->CheckMembership(
MakeBigSegmentRef(segment.key, generation));
}

} // namespace
Expand Down
Loading