-
Notifications
You must be signed in to change notification settings - Fork 49
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
Init logger in a Python API library #314
Conversation
This change looks reasonable enough. But I would like to hear what @mmastrac (ctor author) has to say about the root cause. It looks like he's very responsive so my guess is we'll hear back soon. |
Does it make sense to invent a persistent object for all Hyperon Rust clients? I.e. a runtime object that must be created to use the library? Python already has this, and you're using it to initialize the logger there. But Rust and C clients need to depend on ctor or do their own logger initialization. I think we might need something like a runtime object to own the thread pool for a multi-threaded interpreter. Also I was considering turning all symbol atoms into hashes for performance, and keeping the strings themselves in a central store. Things like that. If we had such an object, that would give us a place to initialize the logger without relying on ctor. |
Luke, do you have any examples of this used in mature Rust libraries? I am not crazy of having global singletons except some specific cases. Even with logger it definitely has drawbacks, for example one cannot properly configure logger from code from the very beginning. But maybe in Rust there is no other way when one need to initialize some global constant object before program started. For example it is the reason why reserved symbol atoms are Anyway I would not create some global object which keeps all what we need at once. I would instead introduce specific APIs for each case and use it to initialize storages. For example address of the string could probably be used instead of its hash and it would not require a separate store. Thread pool could be a part of interpreter and initialized with its instance. Maybe there are cases where we cannot eliminate the global storage. So it is also interesting to see how this problem solved in mature Rust libraries. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I cannot comment on the design of that fix but I can confirm that it works for me.
TLDR: this change is good to merge, IMO. But longer-term, I believe we should remove the logger init from the ctor hook, and try to put it somewhere else. More details:
Many embedded language crates use a top-level runtime state object (often a singleton):
However, I agree with you that a singleton might not be the best design. All of those above examples are rust wrappers around projects with non-rust implementations, and their decision might have been involuntary, rather than a well-considered design choice. I think the Lua case is the closest to what I have in mind. There is a top-level object but it’s not a singleton. Hyperon-experimental has the This might end up limiting the optimization that are available to us - although we could solve it like V8 solves it, by creating wrappers for objects under the management of a runner (ie. something like https://docs.rs/v8/0.73.0/v8/trait.Handle.html) Anyway, this is a bigger discussion, and I apologize for getting us off-topic with regard to logger initialization. If we ultimately moved in this direction, top-level object creation would be a logical place to init the logger. My final point about the logger is that running the initialization from ctor means that another app that wants to embed the MeTTa interpreter can’t initialize their own logger from their own main (if they wanted to use |
Thanks Luke, on the first glance Lua example is clear, but I think I need to look at the API of the library closer to understand how it works in details. I am curious why Rust has a such restricted conception of a static read-only object.As far as I remember static can be initialized by |
I used |
Merging it as a quickfix as this functionality is important, but I am ready to discuss a proper fix further. |
…to initialize the logger (the platform Environment) See trueagi-io#314
PR fixes issue with logs absence in debug releases. The root cause is that
ctor
is not called when C API static library is built in debug configuration. I am callinginit_logger
manually from C library to fix it.I opened mmastrac/rust-ctor#280 to ask
ctor
author for help in investigation.