Skip to content

Extract logger from Context & renamed Global_context to Data_store - #752

Open
jbigot wants to merge 4 commits into
mainfrom
extract_logger
Open

jbigot wants to merge 4 commits into
mainfrom
extract_logger

Conversation

@jbigot

@jbigot jbigot commented Sep 4, 2026

Copy link
Copy Markdown
Member
  • Context no longer exposes a logger() accessor.
  • Each plugin now receives its own PDI::Logger& explicitly, as an additional parameter on the PDI::Plugin constructor and can access it afterwards through the inherited Plugin::logger() accessor.
  • Every function that was handed a Context& to reach its logger now takes a Logger& alongside it.
  • Removed Context_proxy, which existed solely to hand each plugin its own child logger, a role now served directly by Plugin.
  • Renamed Global_context to Data_store
    • Renamed Global_context to Data_store to match the name already used in the documentation.
    • Renamed associated files from global_context* to data_store*.
    • Renamed Data_store variables and functions named *context to *store.

Before merging your code, please check the following:

  • you have added a line describing your changes to the Changelog;
  • you have added unit tests for any new or improved feature;
  • in case you updated dependencies, you have checked pdi/docs/CheckList.md;
  • in case of a change in pdi.h, this same change must be reflected in mock_pdi/pdi.h;
  • in case of a new plugin, make sure the plugin issues the corresponding timer events;
  • you have checked your code format:
    • you have checked that you respect all conventions specified in CONTRIBUTING.md;
    • you have checked that the indentation and formatting conforms to the .clang-format;
    • you have documented with doxygen any new or changed function / class;
  • you have correctly updated the copyright headers:
    • your institution is in the copyright header of every file you (substantially) modified;
    • you have checked that the end-year of the copyright there is the current one;
  • you have updated the AUTHORS file:
    • you have added yourself to the AUTHORS file;
    • if this is a new contribution, you have added it to the AUTHORS file;
  • you have added everything to the user documentation:
    • any new CMake configuration option;
    • any change in the yaml config;
    • any change to the public or plugin API;
    • any other new or changed user-facing feature;
    • any change to the dependencies;
  • you have correctly linked your MR to one or more issues:
    • your MR solves an identified issue;
    • your commit contain the Fix #issue keyword to autoclose the issue when merged.

@jbigot
jbigot requested a review from a team September 4, 2026 14:04
@jbigot jbigot linked an issue Sep 4, 2026 that may be closed by this pull request
@jbigot
jbigot requested a review from a team September 4, 2026 14:06
* `Context` no longer exposes a `logger()` accessor.
* Each plugin now receives its own `PDI::Logger&` explicitly, as an additional
  parameter on the `PDI::Plugin` constructor and can access it afterwards
  through the inherited `Plugin::logger()` accessor.
* Every function that was handed a `Context&` to reach its logger now takes a
  `Logger&` alongside it.
* Removed `Context_proxy`, which existed solely to hand each plugin its own
  child logger, a role now served directly by `Plugin`.

A step towards #721.
* Renamed `Global_context` to `Data_store` to match the name already used in
  the documentation.
* Renamed associated files from `global_context*` to `data_store*`.
* Renamed Data_store variables and functions named `*context` to `*store`.

Anything typed as the abstract `Context` is untouched.

Fix #721.
@jbigot jbigot changed the title Extract logger from Context Extract logger from Context & renamed Global_context to Data_store Sep 6, 2026

@Yushan-Wang Yushan-Wang left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Wow, it was many files changed!
Except a bit of naming consistency, I am OK with this PR

Comment thread pdi/include/pdi/context.h
#include <pdi/pdi_fwd.h>
#include <pdi/data_descriptor.h>
#include <pdi/datatype_template.h>
#include <pdi/logger.h>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can be removed?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

logger.h is unused, while data_descriptor.h and datatype_template.h are redundant of pdi_fwd.h ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Indeed, logger.h was there for the accessor, and the accessor is gone. Good catch.

Regarding the other two, they are not equivalent to pdi_fwd.h that only declares types; the dedicated headers are the one that define the types.
Since only pointers or references are manipulated here, we could argue that it's up to the client to include them when de-referencing... This is up for debate. But this predates this PR and would break stuff in various places (reference_expression.cxx would not compile anymore for example).
I would keep it as-is for now, but it could be nice to add a separate issue, a rule in CONTRIBUTING.md, and tooling with something like iwyu to check that everything is according to the rule in the CI.

throw Spectree_error{node, "Incorrect array ordering: `{}', only C order is supported", order_str};
{
string order_str = to_string(PC_get(node, ".order"), "");
if (order_str == "c" && order_str == "C") {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
if (order_str == "c" && order_str == "C") {
if (order_str == "c" || order_str == "C") {

We can close #743

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Wouldn't it be better to merge #743 , with a clean CHANGELOG entry, correct attribution etc. ? Then rebase this on top of it.

{
// holder types
ctx.add_datatype("array", to_array_datatype_template);
ctx.add_datatype("array", to_array_datatype_template(logger));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Shall we add logger to other types as well?
For the sake of being able to add logger information in the future?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I propose to completely drop the parameter from all templates for uniformity and to instead rely on a lambda to pass the logger when necessary. That way, we get a uniform API and no unused logger that might make contributors wonder why they're here, similarly to your comment on Dnc_io below.

Comment thread plugins/decl_netcdf/decl_netcdf.cxx Outdated
Comment thread plugins/decl_netcdf/decl_netcdf.cxx Outdated
Comment thread plugins/timer/timer.cxx Outdated
Comment thread plugins/timer/timer.cxx Outdated
Comment thread plugins/timer/timer.cxx Outdated
Comment thread plugins/timer/timer.cxx Outdated
Comment thread plugins/timer/timer.cxx Outdated
@Yushan-Wang Yushan-Wang mentioned this pull request Sep 10, 2026
19 tasks done
Comment on lines 50 to 56
target_link_libraries(pdi_set_value_plugin PUBLIC PDI::PDI_plugins spdlog::spdlog)
# logger_operation.cxx casts to PDI::Global_context to reach the root logger; that class is
# library-internal (pdi/src/, not the public pdi/include/pdi/ API) and only reachable this way
# when set_value is built as part of the PDI monorepo superbuild, not as a standalone plugin
# against an installed PDI package.
target_include_directories(pdi_set_value_plugin PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../pdi/src")
set_target_properties(pdi_set_value_plugin PROPERTIES CXX_VISIBILITY_PRESET hidden)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Are we sure we want this ? Is it technically an anti-pattern, as set_value would not be functioning as a plugin but as a core component ? If we can instead modify PDI core, should we use something similar to global_pattern(), adding a Logger::global_level(spdlog::level::level_enum) or equivalent to the public API so that our plugin can access this "on its own" ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

You're completely right. This is a quick and dirty workaround; and the reason I left it as-is is because the plan is indeed to make set_value a core component, in the next step of #378 (Cf. #751 )

That being said, if we ship in-between this is not very clean. So we can go with the approach you propose for this step and revert it in the next one.

I tried to make it go unnoticed, but you were there to watch ;p Good catch!

jmorice91

This comment was marked as duplicate.

Comment thread pdi/include/pdi/plugin.h
Plugin(Context& ctx);
Plugin(Logger& logger, Context& ctx);

virtual ~Plugin() noexcept(false);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why this dtor can throw?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Because a plugin destructor is allowed to fail, and the failure has to be reportable rather than
fatal. Since C++11 a destructor is implicitly noexcept, and a derived destructor takes its
exception specification from the base, so without noexcept(false) on ~Plugin anything thrown
from any plugin destructor would be std::terminate() instead of an error.

Plugins do throw from there:

  • ~decl_hdf5_plugin calls handle_hdf5_err("Cannot finalize HDF5 library") when H5close() fails;
  • ~set_value_plugin runs the configured on_finalize triggers, i.e. arbitrary expose / share /
    set operations, each of which can throw PDI::Error;
  • ~pycall_plugin calls pybind11::finalize_interpreter().

The exception then propagates out of Data_store::finalize() to PDI_finalize(), whose
function-try-block turns it into a PDI_status_t for the application.

It is not something this PR introduces: the line is unchanged, and noexcept(false) has been on
~Plugin since c92f64c7 (2019). The PR only adds the logger parameter to the constructor above
it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This question is unrelated to this PR.
My concern is about a feedback review for catalyst_plugin: the dtor must be specified as noexcept

catalyst_plugin::~catalyst_plugin() noexcept

With this default destructor and your answer, It seems for me that a plugin destructor marked with noexcept is not good choice. Am I mistaken?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It's a bad idea for a virtual destructor that defines the interface: whether implementations are allowed to throw. It's a good idea for an implementation to specify that it won't throw.

jbigot and others added 2 commits September 20, 2026 14:28
Co-authored-by: yushan wang <yushan.wang@cea.fr>
Co-authored-by: yushan wang <yushan.wang@cea.fr>

@jmorice91 jmorice91 left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

small fix is proposed.

General comment:
It is not clear for me when we needed to use logger instead of logger() in a plugins.
It would be nice to have a rule/recommendation for that to be sure that this PR verify this.
As you have done this huge work what is your recommendation between logger and logger()?

Ps: I'm not sure that the plugins serialize doesn't the same rule.

Comment thread pdi/src/plugin_store.h

/** Actually load the plugins
*
* \param confs the configurations specifying the list of plugin paths & plugins to load

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

missing description of ctx in the parameter list

Suggested change
* \param confs the configurations specifying the list of plugin paths & plugins to load
* \param ctx the context
* \param confs the configurations specifying the list of plugin paths & plugins to load

Comment thread pdi/src/plugin_store.h
Stored_plugin(Plugin_store& store, std::string name, PC_tree_t conf);

/** Loads a plugin if not done yet and its pre-dependencies if required
* \param plugins the list of all plugins (for dependencies)

@jmorice91 jmorice91 Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Missing description ctx as parameter for ensure_loaded

Suggested change
* \param plugins the list of all plugins (for dependencies)
* \param ctx the context
* \param plugins the list of all plugins (for dependencies)

Comment thread pdi/src/plugin_store.h

public:
/** Pre-loads a plugin
* \param ctx the context

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No ctx is used in the ctor

Suggested change

@jbigot

jbigot commented Oct 3, 2026

Copy link
Copy Markdown
Member Author

small fix is proposed.

General comment: It is not clear for me when we needed to use logger instead of logger() in a plugins. It would be nice to have a rule/recommendation for that to be sure that this PR verify this. As you have done this huge work what is your recommendation between logger and logger()?

In the constructor, a parameter named logger ill hide the member function of the same name. So in that case, it's either logger the easy choice, or this->logger() the (maybe) cleaner choice. I would say it is mostly a question of taste and I wouldn't enforce one or the other way. Maybe the best idea would be to not call the parameter logger, and use the member function to be coherent in the whole plugin implementation.

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.

Extract Logger from Global_context

4 participants