Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fetch RuntimeInformation of SERVICE queries #1798

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

UNEXENU
Copy link
Contributor

@UNEXENU UNEXENU commented Feb 12, 2025

Adds the retrieval of runtime information for the service query using a WebSocket client.

@UNEXENU
Copy link
Contributor Author

UNEXENU commented Feb 12, 2025

@joka921 This is a first working poc, i will take car of test coverage and outdated comments in the next iteration.

Copy link

codecov bot commented Feb 12, 2025

Codecov Report

Attention: Patch coverage is 40.59829% with 139 lines in your changes missing coverage. Please review.

Project coverage is 89.87%. Comparing base (8fe0642) to head (45d827c).

Files with missing lines Patch % Lines
src/util/http/websocket/WebSocketClient.cpp 0.00% 121 Missing ⚠️
src/util/http/websocket/WebSocketClient.h 0.00% 9 Missing ⚠️
src/engine/Service.cpp 72.72% 3 Missing ⚠️
src/engine/Service.h 50.00% 2 Missing and 1 partial ⚠️
src/util/http/HttpClient.cpp 50.00% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1798      +/-   ##
==========================================
- Coverage   90.18%   89.87%   -0.31%     
==========================================
  Files         400      403       +3     
  Lines       38440    38661     +221     
  Branches     4306     4330      +24     
==========================================
+ Hits        34666    34746      +80     
- Misses       2479     2616     +137     
- Partials     1295     1299       +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Member

@joka921 joka921 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An initial look at everything but the tests,
I think currently this breaks cancellation, because I don't know whether the websocket connections will always close gracefully.

Comment on lines 625 to 633

// _____________________________________________________________________________
cppcoro::generator<std::shared_ptr<RuntimeInformation>>
Operation::getRuntimeInfoChildren() {
for (auto child : getChildren()) {
AD_CONTRACT_CHECK(child);
co_yield child->getRootOperation()->getRuntimeInfoPointer();
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are currently porting back to C++17 , so we shouldn't use generators in new code anymore.
Why not simply use std::vector<RuntimeInformation*> or maybe even better absl::InlinedVector<RuntimeInformation*> as we almost never have more than 2 children.

AD_CONTRACT_CHECK(child);
_runtimeInfo->children_.push_back(
child->getRootOperation()->getRuntimeInfoPointer());
for (auto child : getRuntimeInfoChildren()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use references when you don't need or use the copies of the child (multiple occurences).

Comment on lines 124 to 125
// Get access to the children's RuntimeInfo. Required for the `Service`, as
// it's children can't be accessed using `getChildren()` above.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not required for the service but overridden by the Service.

Comment on lines 191 to 202
if (str == "fully materialized") {
return fullyMaterialized;
} else if (str == "lazily materialized") {
return lazilyMaterialized;
} else if (str == "in progress") {
return inProgress;
} else if (str == "not started") {
return notStarted;
} else if (str == "optimized out") {
return optimizedOut;
} else if (str == "failed") {
return failed;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you set up a static HashMap for this lookup, mostly for readability`.

Comment on lines 264 to 276
auto cacheStatusFromString = [](std::string_view str) {
using ad_utility::CacheStatus;
if (str == "cached_not_pinned") {
return CacheStatus::cachedNotPinned;
} else if (str == "cached_pinned") {
return CacheStatus::cachedPinned;
} else if (str == "computed") {
return CacheStatus::computed;
} else if (str == "not_in_cache_not_computed") {
return CacheStatus::notInCacheAndNotComputed;
} else {
throw std::runtime_error(
"Unknown string value was encountered in `fromString(CacheStatus)`");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe also a separate function + also use a lookup data structure.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And also note with the respective enums in a big comment, that these functions also have to be changed...

Comment on lines 70 to 75
// Upgrade the client to a websocket connection and return a generator of
// messages received from the server.
static cppcoro::generator<std::string> readWebSocketStream(
std::unique_ptr<HttpClientImpl> client, std::string_view host,
std::string_view target);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are trying to get away from generators,
Please have a look at the InputRangeTypeErased etc. classes at the end of Iterators.h , and ask me if you have trouble.
And as stated above, you should have a possibility to cancel the websocket stream if the outer operation is cancelled.

@@ -62,6 +62,14 @@ HttpClientImpl<StreamType>::HttpClientImpl(std::string_view host,
// ____________________________________________________________________________
template <typename StreamType>
HttpClientImpl<StreamType>::~HttpClientImpl() {
// If the stream was upgraded to a websocket connection, try to close it.
if (ws_) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is something that you probably have to expose also manually (in a threadsafe way, but ask me for details if necessayr).

@@ -102,6 +112,10 @@ HttpOrHttpsResponse HttpClientImpl<StreamType>::sendRequest(
request.set(http::field::accept, acceptHeader);
request.set(http::field::content_type, contentTypeHeader);
request.set(http::field::content_length, std::to_string(requestBody.size()));
for (const auto& h : customHeaders) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
for (const auto& h : customHeaders) {
for (const auto& [key, value] : customHeaders) {
...

client->ws_->read(buffer);
co_yield beast::buffers_to_string(buffer.data());
buffer.consume(buffer.size());
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See here for something I found about cancellation

This should document, that even normal exits will throw an exception, so that calling code has to handle everything.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or you use an explicit strand that you run in this thread etc, but I'll have to llok into that again.

// ____________________________________________________________________________
cppcoro::generator<std::string> readHttpOrHttpsWebsocketStream(
const ad_utility::httpUtils::Url& url, std::string_view target) {
auto listen = [&]<typename Client>() -> cppcoro::generator<std::string> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have a look at the util/typeIdentity.h header, there i have a trick that makes the templated lambdas easier to call.

@sparql-conformance
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants