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
Integrate kdbEnsure into kdbOpen #3651
Integrate kdbEnsure into kdbOpen #3651
Conversation
I think the new implementation will work something like this:
This is should be enough for both gopts and notifications. The new functions |
There is now a rough sketch of the implementation, to implementing the comment above. |
This pull request introduces 3 alerts when merging f2a2b1e into 77aec77 - view on LGTM.com new alerts:
|
* i.e. there is no prefix to replace | ||
* @retval 1 if the prefix was sucessfully replaced | ||
*/ | ||
int keyReplacePrefix (Key * key, const Key * oldPrefix, const Key * newPrefix) |
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 added this function to kdb.h
since it is
- quite useful to some plugins
- much easier to use than manually calling
keyName
,keySetName
,keyNameSize
etc. - heavily optimized compared to the alternative
- uses many internals of
struct _Key
that really shouldn't be modified outside the core
* @retval 0 if @p ks contains no keys below @p root (and also not @p root itself) | ||
* @returns otherwise, the number of keys that have been renamed | ||
*/ | ||
ssize_t ksRename (KeySet * ks, const Key * root, const Key * newRoot) |
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.
We could add this function to kdb.h
as well, but I put in in kdbprivate.h
for now.
Mainly, because of the fact that it modifies keys with key->ksReference == 1
in-place. This is nice, because you can avoid allocating new keys and sometimes even completely avoids re-sorting the KeySet, but it can easily lead to memory bugs. For example in a section like this:
libelektra/src/libs/elektra/kdb.c
Lines 316 to 322 in 1e7ba55
const char * pluginName = keyBaseName (cur); | |
KeySet * pluginConfig = ksCut (contract, cur); | |
// increment ref count, because cur is part of pluginConfig and | |
// we hold a reference to cur that is still needed (via pluginName) | |
keyIncRef (cur); | |
ksRename (pluginConfig, cur, pluginConfigRoot); |
However, apart from this the function is completely safe to use and could be useful in plugins that move keys around. So maybe putting it into kdb.h
could make sense.
* in @p ks, the size of @p ks is returned. The snippet above | ||
* shows why this is useful. | ||
*/ | ||
elektraCursor ksFindHierarchy (const KeySet * ks, const Key * root, elektraCursor * end) |
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 found this neat alternative to the ksExtract
function we discussed in #2992. I put it into kdbprivate.h
for now, but I really think it should be in kdb.h
since it will be incredibly useful.
I'll also rewrite elektraKsFindCutpoint
(used by ksCut
) to use this, instead of just looking for the root and then looping over the following keys.
50af897
to
e95fd91
Compare
@markus2330 The actual integration of kdbEnsure into kdbOpen, i.e. the contracts part, should now be done. I just need to rewrite the notifications stuff and then replace the |
src/bindings/rust/elektra/src/kdb.rs
Outdated
@@ -26,8 +26,10 @@ impl Drop for KDB { | |||
impl KDB { | |||
/// Opens the session with the Key database. | |||
pub fn open<'a>() -> Result<Self, KDBError<'a>> { | |||
// FIXME: binding |
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.
@PhilippGackstatter Should I keep anything in mind here, you can I just add the new KeySet parameter? Also would using std::option
be a good idea, since the KeySet can be NULL in C?
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 think we can just add it. We could do the signature like this:
pub fn open<'a, C>(contract: C) -> Result<Self, KDBError<'a>>
where
C: Into<Option<Contract>>;
This way, we can call KDB::open(None)
and KDB::open(Contract { ... })
respectively, without having to specify Some(Contract {})
in the second case, so it's a bit nicer than using Option
directly.
I tried it here on the Rust playground.
@@ -0,0 +1,87 @@ | |||
--[[ | |||
-- TODO: cannot call std::vector<std::string> function from lua |
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.
The std::vector<std::string>
solution I used for Ruby and Python doesn't work for Lua (it seems Lua Tables can't easily be converted into std::vector
). Do we have someone who knows more about Lua and SWIG, or should we just leave elektraGOptsContract
unsupported in Lua?
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.
@manuelm as you are our best Lua hacker, do you have some idea how this can be done?
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.
This should work out of the box:
local custom_argv = kdb.StringVector()
custom_argv:push_back("test")
custom_argv:push_back("get")
custom_argv:push_back("-v")
custom_argv:push_back("user:/")
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 already found a different solution, but thanks for the help
@markus2330 Apart from the updates to the Java and the Rust binding (and the public API questions) this PR should be done, please Review (or delegate to the appropriate person) |
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.
Amazing work, I really like your attention to many details and the many other small things that you fixed.
The main issues are (maybe not so obvious from the individual comments):
- there is a bit chaos about the contract functions: in kdb.h they are called elektra.* but in other places it is in KDB namespace/class.
- modularization not ideal: *Contract functions should be (from modularity point of view) ideally be part of the module, not of the core. Ideally applications should even link against libelektra-notification (in this case they actually already do) or libelektra-opts, then the contract could also be part of that lib/plugin.
- global keyset is not documented but with this PR many semantics of the global keyset were actually assumed/fixed.
Btw. are opts/gotps
really the ideal name? Why do we have a src/libs/opts/opts.c library if it is not user-facing? Is this something that actually should be static? (see also point 2. about modularization)
src/bindings/jna/libelektra5j/src/main/java/org/libelektra/KDB.java
Outdated
Show resolved
Hide resolved
C++ uses the In Java everything has to be in a class. We could create a new I didn't call it e.g.
Unless I made a mistake, the
Yes, we should actually fix that. I didn't change any of the global keyset behaviour AFAIK (apart from not caching everything). Basically, everything this PR depends on related to the global keyset, is stuff the
The name is just a name. If you have a better idea, feel free to change it.
|
BTW I have no idea what is going on with the failing macOS build jobs. I assume it's the same problem as with the failing Jenkins build, but somehow it doesn't segfault on macOS. However, I have absolutely no clue how to reproduce this. The only thing I'm pretty sure about is that only the Java test has a problem and the other failed tests are because the Java test aborted and didn't clean up properly. |
And this is a huge change and must be documented. And afaik this is the only semantic the content of the global keyset has so far, so the docu does not need to include much else. Nobody can read your mind, so please write down how you were thinking how it should be used. (I could only copy texts from your discussion but this leads to very poor docu.)
You are obviously very efficient in renaming, most other people, including me, are not. And once users start using it at wider scale, we can forget all about renaming. I already stated that ideally there would be only one interface, which could be called "proc" (like the namespace), so there would be no need for "opts" or "gopts". Btw. it is not like that I cannot live with the current situation, I understand you if you say my suggestions are too much effort to implement. I just gave the feedback the the API situation of opts/gopts looks to me hackish and historically grown. |
I can't read @mpranj's mind either. So I don't actually know what the original intention behind the global keyset was. I'll write down what I know, but I can't guarantee it will be 100% correct.
Yes, ideally both the plugin and the library would use the same name. But that's not possible right now. There is definitely a name collision somewhere in CMake, but there might be other things that prevent this. The actual interface is pretty much the same already. The command-line argument and environment variable parsing is configured via the metadata in the
I think |
Thank you very much 💖
If the name proc is too general we also have a problem with the namespace proc. I do not see how args/arguments/variables/options are less general, though. |
The namespace
|
Unfortunately I forgot to document that the global keyset is cached. Other than that the intention and usage is documented (in multiple places). I did not think anybody would want to store pointers in the global keyset. Actually I think the way we store pointers in KeySets (at several places) is abuse of the API and not recommended for any external user/developer. On the other hand it made sense to cache the global keyset. With the cache we try to store the complete/relevant state of the KDB. The Split for example is also restored from the cache. |
a7f2695
to
1c22489
Compare
The Jenkins build should™ now work. The failing job didn't build the I still don't know why the 🍎 MMap job failed, but maybe it now works too. But looking at the Cirrus config, it should build gopts and therefore probably has a different problem. PS. No, I don't know why the tests segfaulted because of a missing plugin instead of returning the proper error. |
@mpranj I found out why the "🍎 MMap" job doesn't work. It actually has nothing to do with macOS and happens on Linux as well (with the CMake config from the Cirrus job). The immediate cause is that this line libelektra/src/plugins/mmapstorage/mmapstorage.c Line 1136 in ae419e6
clears the KeySet and removes the data that EDIT: I tried a simple solution with |
I can make a PR tomorrow at latest. If it does not break anything else it should be quick. |
You should be able to push directly to this branch. Then we'd know right away that it fixes the issue as well as not breaking anything else. |
@mpranj thank you very much for helping out here! |
@kodebach sorry you hit this bug/nasty leftover TODO, but thank you very much for reporting and pinning down the exact problem. I've pushed a fix, let's hope the build servers are happy. Works on my machine(tm). |
From my side this PR is done and the build servers are happy as well. @markus2330 Do still have any input or can this be merged? |
Thank you so much for this amazing work! So let us test this and release it asap. @tucek please make sure to rebase to master so that your work is based on top of this (it contains changes to the Java binding). |
After rebase (and rebuilding elektra) i get the following test error: Does anyone recognize the Problem? |
Have you tried doing a clean build? i.e. deleting the whole build directory and calling The JNA setup is a bit funky and doesn't really detect, if the C API changed and it should rebuild the JNA bindings. It then tries to call functions that no longer exist, when you run the tests. |
i had some so mismatch... i had to first uninstall and then reinstall elektra... thx |
Implements #2764
Basics
These points need to be fulfilled for every PR:
(added as entry in
doc/news/_preparation_next_release.md
whichcontains
_(my name)_
)Please always add something to the release notes.
(first line should have
module: short statement
syntax)close #X
, are in the commit messages.doc/news/_preparation_next_release.md
scripts/dev/reformat-all
If you have any troubles fulfilling these criteria, please write
about the trouble as comment in the PR. We will help you.
But we cannot accept PRs that do not fulfill the basics.
Checklist
Check relevant points but please do not remove entries.
For docu fixes, spell checking, and similar none of these points below
need to be checked.
(not in the PR description)
Review
Reviewers will usually check the following:
Labels
If you are already Elektra developer:
say that everything is ready to be merged.