Skip to content

Conversation

rroelke
Copy link
Member

@rroelke rroelke commented Aug 19, 2025

My work on CORE-290 intends to use opentelemetry tracing into the core library. When we introduce tracing, we will want to record each C API call as a span under which nested operations occur.

The C API calls can be intercepted via aspect template (#4430). A build process which compiles TileDB core from source can use this aspect to inject code which runs prior to each C API call.

One use of this is in the TileDB-Server repository, which also wants to add opentelemetry tracing to each C API call. However, this implementation is lacking because the aspects do not allow a span to encompass the whole C API call. The instrumentation linked starts and ends the span before invoking the API. It cannot do any better because the aspect call template function return value is not used, so a non-trivial value returned would have its destructor run right away.

This pull request modifies the template invoking the aspect call function to bind its result to a value on the stack. This runs the destructor after returning from the C API call, which will allow the aspect call function to return a tracing span object.

There is no tracing in this pull request, but the added test demonstrates the principle, modifying the existing logging hook test into a "tracing hook" which pushes messages onto a simple log before and after each C API call.


TYPE: NO_HISTORY
DESC: Enable C API aspect templates to return a non-trivial

@rroelke rroelke requested a review from davisp August 19, 2025 01:59
Copy link
Contributor

@davisp davisp left a comment

Choose a reason for hiding this comment

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

+1

Comment on lines +36 to +52
#ifndef WITH_HOOK
#define WITH_HOOK ""
#endif

enum class WhichHook { None, Logger, Tracer };

constexpr WhichHook get_constexpr_which_hook() {
constexpr std::string_view view(WITH_HOOK);
if (view == "logger") {
return WhichHook::Logger;
} else if (view == "tracer") {
return WhichHook::Tracer;
} else {
return WhichHook::None;
}
}

Copy link
Member

Choose a reason for hiding this comment

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

Add static_assert that WITH_HOOK is either logger or tracer? Or not, it's test code.

Comment on lines +36 to +43
#ifndef WITH_HOOK
#define WITH_HOOK ""
#endif

enum class WhichHook { None, Logger, Tracer };

constexpr WhichHook get_constexpr_which_hook() {
constexpr std::string_view view(WITH_HOOK);
Copy link
Member

Choose a reason for hiding this comment

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

Would this work? Users will not have to add quote marks to the define. Or not, it's test code.

Suggested change
#ifndef WITH_HOOK
#define WITH_HOOK ""
#endif
enum class WhichHook { None, Logger, Tracer };
constexpr WhichHook get_constexpr_which_hook() {
constexpr std::string_view view(WITH_HOOK);
#ifndef WITH_HOOK
#define WITH_HOOK
#endif
enum class WhichHook { None, Logger, Tracer };
constexpr WhichHook get_constexpr_which_hook() {
constexpr std::string_view view(#WITH_HOOK);

endfunction ()

hook_test(logger)
hook_test(tracer)
Copy link
Member

Choose a reason for hiding this comment

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

Seems excessive to compile multiple files twice just to make a static_assert.

Copy link
Member

Choose a reason for hiding this comment

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

On second thought, seems even more excessive to add 200 lines of test code just to check that the destructor of an object gets called at the right place. 🤔

Copy link
Member Author

Choose a reason for hiding this comment

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

Seems excessive to compile multiple files twice just to make a static_assert.

It's a bit more than that - the tests in unit_capi_hook.cc switch based on which_hook and these files add the static assertions that it compiled according to expectation

seems even more excessive to add 200 lines of test code just to check that the destructor of an object gets called at the right place

I don't agree, for the tracing spans to work properly it is a necessity that the destructors are called in the place we expect. This aspect stuff makes it pretty painful.

@rroelke rroelke merged commit 9a0d45e into main Sep 18, 2025
56 checks passed
@rroelke rroelke deleted the rr/capi-aspect-call-raii branch September 18, 2025 18:23
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.

3 participants