Skip to content
This repository has been archived by the owner on Oct 15, 2024. It is now read-only.

doc: add decision docs for decision meeting 15.07.2021 #3919

Merged
merged 15 commits into from
Dec 9, 2021

Conversation

lawli3t
Copy link
Contributor

@lawli3t lawli3t commented Jul 4, 2021

Basics

These points need to be fulfilled for every PR:

  • Short descriptions of your changes are in the release notes
    (added as entry in doc/news/_preparation_next_release.md which
    contains _(my name)_)
    Please always add something to the release notes.
  • Details of what you changed are in commit messages
    (first line should have module: short statement syntax)
  • References to issues, e.g. close #X, are in the commit messages.
  • The buildservers are happy. If not, fix in this order:
    • add a line in doc/news/_preparation_next_release.md
    • reformat the code with scripts/dev/reformat-all
    • make all unit tests pass
    • fix all memleaks
  • The PR is rebased with current master.

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.

  • I added unit tests for my code
  • I fully described what my PR does in the documentation
    (not in the PR description)
  • I fixed all affected documentation
  • I added code comments, logging, and assertions as appropriate (see Coding Guidelines)
  • I updated all meta data (e.g. README.md of plugins and METADATA.ini)
  • I mentioned every code not directly written by me in THIRD-PARTY-LICENSES

Review

Reviewers will usually check the following:

Labels

If you are already Elektra developer:

  • Add the "work in progress" label if you do not want the PR to be reviewed yet.
  • Add the "ready to merge" label if the basics are fulfilled and you also
    say that everything is ready to be merged.

Closes #3839

@lawli3t
Copy link
Contributor Author

lawli3t commented Jul 4, 2021

@kodebach in this comment #3750 (comment) you mentioned something about

changes to the backend and global plugin stuff

Would you like to add this to the agenda of this meeting?

@lawli3t lawli3t changed the title doc: add decision docs for decision meeting mid july 2021 doc: add decision docs for decision meeting 15.07.2021 Jul 4, 2021
@kodebach
Copy link
Member

kodebach commented Jul 4, 2021

changes to the backend and global plugin stuff

Would you like to add this to the agenda of this meeting?

I "discussed" this with @markus2330. We both think that this would probably be too much and is somewhat unrelated to the rest of the agenda (which is more concerned with the C API). Despite that I would still like to briefly discuss the changes of #3693 at the end of the meeting. I would just give a brief overview of what the idea is to get some quick feedback on the general concepts. For a more in-depth discussion, we will definitely need a separate meeting and people will probably have to read the new documentation first.

Copy link
Contributor

@markus2330 markus2330 left a comment

Choose a reason for hiding this comment

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

Thank you so much for the preparation of the meeting!


## Problem

Currently, a lot of functions return the error value, regardless of error. These poses some problems, for instance authors of bindings, where it is hard to tell which error exactly occured. A big improvement to this would be returning different error codes for different types of errors, in order to be able to provide better information in cases of errors. Some functions also make use of an `errorKey`. While this seems like a decent approach, to provide additional informations in cases of error, it is currently very badly documented. It is not really transparent for the users of the function, what kind of information is included in the `errorKey` and even which messages could possibly be returned.
Copy link
Contributor

Choose a reason for hiding this comment

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

Imho here are several issues described (errors of Key/KeySet, errors of KDB). Please also have a look at earlier attempts to errors we already had: using errno (mapping of errors was troublesome).

doc/decisions/iterators.md Outdated Show resolved Hide resolved
doc/decisions/iterators.md Outdated Show resolved Hide resolved
doc/decisions/iterators.md Outdated Show resolved Hide resolved
doc/decisions/key_string_return_value.md Outdated Show resolved Hide resolved
doc/decisions/reference_counting.md Outdated Show resolved Hide resolved
- use `keyDel` to dispose of a `Key *` (whether the `Key *` comes from `keyNew`, `keyCopy`/`keyDup` or `keyBorrow`).

## Implications

Copy link
Contributor

Choose a reason for hiding this comment

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

Implications should state which code needs to be changed.

Copy link
Contributor

Choose a reason for hiding this comment

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

Still missing.

Copy link
Contributor

Choose a reason for hiding this comment

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

Still missing.

@@ -0,0 +1,40 @@
# Remove elektraMalloc() et al.
Copy link
Contributor

Choose a reason for hiding this comment

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

A related question is the documentation of the life-time of our objects. Here also improvements of the docu is needed.

doc/decisions/remove_elektra_malloc.md Outdated Show resolved Hide resolved

My main goal with removing elektraMalloc et al. is to improve developer friendliness, especially for newcomers. It is still annoying that I using e.g. strndup may be problematic, because it doesn't use elektraMalloc for allocations. But when I was new to Elektra (and I suspect many other felt the same), it was downright frustrating that you have to remember to use Elektra's special sauce instead of the standard stuff.

The functions `elektraRealloc` and `elektraMemDup` (renamed from elektraStrNDup) can stay, because they are an improvement upon the libc.
Copy link
Contributor

Choose a reason for hiding this comment

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

This would be an decision, not a rationale.

@markus2330
Copy link
Contributor

Aliases are not mentioned?

@lawli3t
Copy link
Contributor Author

lawli3t commented Jul 18, 2021

I have added and edited the documents with the decision from our meeting. Feel free to comment and add to those documents in case I have forgotten something.

@markus2330 @kodebach @mpranj @tucek

doc/decisions/error_handling.md Outdated Show resolved Hide resolved
doc/decisions/error_handling.md Outdated Show resolved Hide resolved
doc/decisions/reference_counting.md Outdated Show resolved Hide resolved
doc/decisions/reference_counting.md Outdated Show resolved Hide resolved
doc/decisions/reference_counting.md Outdated Show resolved Hide resolved
doc/decisions/remove_elektra_malloc.md Show resolved Hide resolved
doc/decisions/remove_elektra_malloc.md Outdated Show resolved Hide resolved
Copy link
Contributor

@markus2330 markus2330 left a comment

Choose a reason for hiding this comment

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

Thank you, great work!

doc/decisions/functions_with_buffers.md Outdated Show resolved Hide resolved

## Problem

The internal iterator inside KeySets seems to cause more problems than it solves.
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe write a bit about the background why it was introduced and that this is not used anymore (like discussed in the meeting: to remember errorKey in kdbSet).

doc/decisions/iterators.md Outdated Show resolved Hide resolved

## Constraints

Because the return value of the function is const char\*, there are not so many possibilities for a change to this behaviour, as every possible return value - except for a NULL pointer - could just be the value of the string of the Key. Possible changes to this behaviour would be:
Copy link
Contributor

Choose a reason for hiding this comment

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

Actually we could also change the return value, so this is not really a constraint.

Copy link
Member

Choose a reason for hiding this comment

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

I think we can say "we don't want to change the return value", because that would make the function very inconvenient to use.

Copy link
Contributor

Choose a reason for hiding this comment

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

"return value" is an error from the original text. Probably changing the API is meant?

doc/decisions/key_string_return_value.md Outdated Show resolved Hide resolved

## Decision

- add second reference counter to Key
Copy link
Contributor

Choose a reason for hiding this comment

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

See #2202: probably it is simply a documentation issue and no second ref counter is needed

Copy link
Member

Choose a reason for hiding this comment

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

Honestly, what was the decision meeting for, if we immediately reverse one of the main decisions?

See #3949 (comment) for an idea on how documentation/API naming can make the second ref counter much easier to understand.

Copy link
Contributor

Choose a reason for hiding this comment

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

Honestly, what was the decision meeting for, if we immediately reverse one of the main decisions?

In some cases we also went into timeouts and agreed there would be a follow up.

See #3949 (comment) for an idea on how documentation/API naming can make the second ref counter much easier to understand.

I like the idea but this immediately raises the question why locking the value or meta-data does not get ref-counted.

Copy link
Member

Choose a reason for hiding this comment

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

raises the question why locking the value or meta-data does not get ref-counted.

To me the question is: Why is locking value/meta-data a thing at all? Is there a use-case for it?

AFAICT we only directly use KEY_FLAG_RO_VALUE and KEY_FLAG_RO_META inside keySetMeta. KEY_LOCK_VALUE and KEY_LOCK_META are not used at all.

For the metadata case we should actually check the key name in keySetRawValue and keyMeta. Otherwise it won't work with ksAppendKey (keyMeta (k), ...) or if you create a meta key via keySetName (k, "meta:/foo").

Copy link
Contributor

Choose a reason for hiding this comment

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

To me the question is: Why is locking value/meta-data a thing at all? Is there a use-case for it?

It is an invariant of a KeySet that its keys are ordered. The locking ensures this invariant.

KEY_LOCK_META

The idea was to use this for meta keys. But probably this is now useless, as meta keys can be recognized by the namespace.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry, misread. I was thinking about if we can get rid of locking at all. And probably we can, we could simply disallow name changes with ref counter != initial value.

To answer your previous question: Locking of values was added for completeness. Other than read-only keys there is probably no usecase.

Copy link
Member

Choose a reason for hiding this comment

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

we could simply disallow name changes with ref counter != initial value.

Then you can't ever change the name from Java or another language with automatic garbage collection, where incrementing the ref counter is required.

Copy link
Contributor

Choose a reason for hiding this comment

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

As far as i understand:

  • keysets store keys in sorted by key names
  • a key's order within a key set is determined on insertion
  • the purpose of locking a key's name is to prevent (potentially) compromising the order of keys for keysets the key is contained in.

To better understand the issue:

  • what are the use cases for changing a key's name? why not making it immutable?
  • why is order within keysets so important? would it be sufficient to ensure order explicitly for use-cases requiring it?

Copy link
Member

Choose a reason for hiding this comment

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

what are the use cases for changing a key's name? why not making it immutable?

In short, to avoid doing some memory allocations. In my case I had a loop where a key was removed and a new one was added with a new basename. The same can be done with immutable keys, but it requires allocating new memory for N keys instead of reusing the old keys.

I was just confused that unlocking is currently not possible at all. When a key is added to a keyset the name is locked, but when it is removed from the keyset the name is not unlocked. To be consistent we should either have immutable keys or provide a way to unlock the keys again.

why is order within keysets so important?

It is required because we use binary search to find a key in the keyset. It is also a nice property and I don't see much reason to rework this, unless there are some huge benefits?

Copy link
Member

Choose a reason for hiding this comment

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

I think the Hashmap requires the order as well, since it only stores indices into the array. Also ksCut relies on the order of the KeySet and in general many things are easier or more efficient to implement, if there is a fixed order.

I was just confused that unlocking is currently not possible at all.

I had the same experience.

doc/decisions/reference_counting.md Outdated Show resolved Hide resolved
doc/decisions/reference_counting.md Outdated Show resolved Hide resolved
doc/decisions/reference_counting.md Show resolved Hide resolved
- use `keyDel` to dispose of a `Key *` (whether the `Key *` comes from `keyNew`, `keyCopy`/`keyDup` or `keyBorrow`).

## Implications

Copy link
Contributor

Choose a reason for hiding this comment

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

Still missing.

@markus2330
Copy link
Contributor

How can we help you to get this merged?

@lawli3t
Copy link
Contributor Author

lawli3t commented Sep 16, 2021

Good question, I have resolved everything I could immediately yesterday. The following things are still open:

Stuff I can & will add soon:

  • Reworking Problem part of error_handling
  • Improvements to remove_elektra_malloc (restructuring Rationale, )
  • Improve problem part of Iterators

Stuff where I feel I don't have enough knowledge/overview to properly improve the existing documents:

  • Resolving the big discussion on the reference counting Decision part
  • Adding implications for reference counting

@kodebach
Copy link
Member

I think reference counting was basically resolved with #3949 (comment). Additionally there will be second counter for the key name lock. However, I wouldn't call that reference counting. I would simply say the lock is shared via a counter.

With the decision to keep keyIncRef/keyDecRef, the only implications of the reference counting stuff are (AFAIK):

  • KeySets can be reference counted now. This is useful for bindings, and some (e.g. C++) may need updates.
  • Reference counts are now limited to UINT16_MAX - 1 instead of SIZE_MAX. This probably won't have any real impact, apart from a change in return type.

The implication of the counter for the name lock is simply that key names will be automatically unlocked again, when a key is removed from all keysets.

@markus2330
Copy link
Contributor

I think reference counting was basically resolved with #3949 (comment)

This still needs to be updated here in the decisions. 1-3 I agree, 4 see below, 5 we need to investigate if it actually solves the JNI problem.

Additionally there will be second counter for the key name lock. However, I wouldn't call that reference counting. I would simply say the lock is shared via a counter.

This is a separate issue #2202 where the current consensus is contrary: to not have a second ref counter just for being able to rename keys. Let us continue the discussion there.

This is useful for bindings, and some (e.g. C++) may need updates.

Yes, it needs an update. The C++ binding was very awkward: Key and KeySets had very different behavior when being copied or copy-constructed. It might be a quite big change though as most bindings wrap the C++ KeySet.

Reference counts are now limited to UINT16_MAX - 1 instead of SIZE_MAX. This probably won't have any real impact, apart from a change in return type.

Actually it is even an improvement as we get rid of platform-dependent behavior.

The implication of the counter for the name lock is simply that key names will be automatically unlocked again, when a key is removed from all keysets.

This is not an implication of anything said above. Please let us separate topics which are unrelated whenever possible. -> #2202

@kodebach
Copy link
Member

Please let us separate topics which are unrelated whenever possible. -> #2202

I just mentioned it, because we talked about it in the meeting for this issue.

Copy link
Contributor

@markus2330 markus2330 left a comment

Choose a reason for hiding this comment

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

In order to finish this, I think we should move still unclear decisions to "In Discussion". Then we are hopefully able to merge this soon.

@@ -55,6 +55,12 @@ section here.

- [Array for Warnings](warning_array.md)
- [Array](array.md)
- [Error Handling](error_handling.md)
Copy link
Contributor

Choose a reason for hiding this comment

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

Probably we should not put too much to decided but only the ones we are already sure about how to implement it.


## Problem

Currently, a lot of functions return the error value, regardless of error. These poses some problems, for instance authors of bindings, where it is hard to tell which error exactly occurred. A big improvement to this would be returning different error codes for different types of errors, in order to be able to provide better information in cases of errors. Some functions also make use of an `errorKey`.
Copy link
Contributor

Choose a reason for hiding this comment

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

Be more concrete. Afaik the only problems are:

  • name modifications which can be either invalid name or locking the key name
  • getting values of (non-)binary keys, see also Binary metadata vs flag #4194


## Considered Alternatives

- Change return types for many functions across the API
Copy link
Contributor

Choose a reason for hiding this comment

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

We could also fix the concrete instances of where multiple errors exist.


## Rationale

This simplifies and unifies error reporting across all functions. It also introduces
Copy link
Contributor

Choose a reason for hiding this comment

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

On the contrary: it would make it more complicated and if we are not very careful less unified.


## Decision

- Remove Functions:
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

## Constraints

Because the return value of the function is const char\*, there are not so many possibilities for a change to this behavior, as every possible return value - except for a NULL pointer - could just be the value of the string of the Key. Possible changes to this behavior would be:

Copy link
Contributor

Choose a reason for hiding this comment

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

sentence stops in the middle?

@@ -55,6 +55,12 @@ section here.

- [Array for Warnings](warning_array.md)
- [Array](array.md)
- [Error Handling](error_handling.md)
- [Iterators](iterators.md)
- [keyString() return value](key_string_return_value.md)
Copy link
Contributor

Choose a reason for hiding this comment

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

As this depends on error_handling.md, probably we should also move it to "In Discussion".

## Implications

## Related Decisions

Copy link
Contributor

Choose a reason for hiding this comment

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

error_handling.md should be here.

- use `keyDel` to dispose of a `Key *` (whether the `Key *` comes from `keyNew`, `keyCopy`/`keyDup` or `keyBorrow`).

## Implications

Copy link
Contributor

Choose a reason for hiding this comment

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

Still missing.

@markus2330 markus2330 merged commit 43499ed into ElektraInitiative:master Dec 9, 2021
@markus2330
Copy link
Contributor

Thank you so much! 💖

@mpranj mpranj added this to the 0.9.9 milestone Mar 8, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

open decisions
6 participants