khepri_adv: Add delete_reason prop, accumulate keep-while expirations#305
Merged
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #305 +/- ##
=======================================
Coverage 89.75% 89.75%
=======================================
Files 22 22
Lines 3230 3241 +11
=======================================
+ Hits 2899 2909 +10
- Misses 331 332 +1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
dumbbell
requested changes
Oct 16, 2024
95b0ef5 to
c62b421
Compare
This change adds a new `delete_reason` key to the `node_props()` map which is either `direct` or `keep_while`. This commit changes `khepri_tree` to add the `direct` delete reason for tree nodes which were deleted because they were the target of a delete command. The `keep_while` reason will be added in the child commit. The motivation to include a delete reason is that in the child commit we will include tree nodes deleted because their keep-while conditions became unsatisfied. `delete_reason` enables the caller to distinguish between tree nodes deleted "directly" (the target of the delete command) and the others which were expired. It also enables callers of put operations to distinguish between puts (tree node creations and updates) and deletions, since a put operation could also trigger a keep-while expiration.
With this change any tree nodes removed from the tree because their keep-while condition became unsatisfied are accumulated in the return value of the put or delete operation which caused their deletion. These expired tree nodes have props maps in the return map with the `delete_reason` key set to `keep_while`. This enables callers of delete operations to distinguish between deletes which were the target of the delete command (`direct`) and expired nodes (`keep_while`). This also enables callers of put operations to distinguish between creates or updates and deletions. This change only affects functions which return the `khepri_adv:node_props_map()` - functions from the `khepri_adv` and `khepri_adv_tx` modules. Previously the node props map did not include the tree nodes removed because of expired keep-while conditions.
c62b421 to
46b6952
Compare
dumbbell
added a commit
that referenced
this pull request
Mar 27, 2025
…actions ... if the effective machine version is also old. [Why] A transaction function is extracted from the modules of a given Khepri member and is executed on all members. These members may run an older or a newer version of Khepri compared to the member that sent the transaction. Therefore, the transaction function and the Khepri public API must be aware of the effective machine version and adapt their behaviour to make sure that all state machine reaches the same state after applying a transaction. Without this, after the same transation function, an old and a new state machine may compute different state. This problem surfaced because #303 and #305 changed the return values of the advanced API: * all functions return a node props map, even those that operate on a single tree node. * all tree nodes indirectly deleted as a byproduct of another put or delete may be included in the returned node props map. This was ok with non-transaction functions because the return values are handled locally, regardless of the effective machine version. However, transactions were broken as explained in the previous paragraphs. [How] First, we introduce a new public API, `khepri_tx:does_api_comply_with()` that returns a boolean to indicate if an old or new behaviour should be expected for a specific breaking change. We then use the effective machine version passed in Ra metadata to `khepri_machine:apply()` to determine how to adapt the behaviour and return value. For queries and read-only transactions, we will need to change how we call Ra because the regular query API doesn't provide the effective machine version. This will be part of a later commit.
dumbbell
added a commit
that referenced
this pull request
Mar 28, 2025
[Why] Since #305, the returned node props map include tree nodes that were deleted as a byproduct of another put or delete. Things like the expiration of a `keep_while` condition. [How] This was a breaking change and this new option allows the caller to restore the previous behaviour of only getting directly impacted tree nodes. This will be useful in follow-up commits to solve backward compatibility in transaction handlind when some Khepri members run older versions of Khepri.
dumbbell
added a commit
that referenced
this pull request
Mar 28, 2025
…actions ... if the effective machine version is also old. [Why] A transaction function is extracted from the modules of a given Khepri member and is executed on all members. These members may run an older or a newer version of Khepri compared to the member that sent the transaction. Therefore, the transaction function and the Khepri public API must be aware of the effective machine version and adapt their behaviour to make sure that all state machine reaches the same state after applying a transaction. Without this, after the same transation function, an old and a new state machine may compute different state. This problem surfaced because #303 and #305 changed the return values of the advanced API: * all functions return a node props map, even those that operate on a single tree node. * all tree nodes indirectly deleted as a byproduct of another put or delete may be included in the returned node props map. This was ok with non-transaction functions because the return values are handled locally, regardless of the effective machine version. However, transactions were broken as explained in the previous paragraphs. [How] We already introduced a new public API, `khepri_tx:does_api_comply_with()` that returns a boolean to indicate if an old or new behaviour should be expected for a specific breaking change. We use this API to determine how to adapt the behaviour and return value of puts and deletes. For queries and read-only transactions, we will need to change how we call Ra because the regular query API doesn't provide the effective machine version. This will be part of a later commit.
dumbbell
added a commit
that referenced
this pull request
Apr 1, 2025
[Why] Since #305, the returned node props map include tree nodes that were deleted as a byproduct of another put or delete. Things like the expiration of a `keep_while` condition. [How] This was a breaking change and this new option allows the caller to restore the previous behaviour of only getting directly impacted tree nodes. This will be useful in follow-up commits to solve backward compatibility in transaction handlind when some Khepri members run older versions of Khepri.
dumbbell
added a commit
that referenced
this pull request
Apr 1, 2025
…actions ... if the effective machine version is also old. [Why] A transaction function is extracted from the modules of a given Khepri member and is executed on all members. These members may run an older or a newer version of Khepri compared to the member that sent the transaction. Therefore, the transaction function and the Khepri public API must be aware of the effective machine version and adapt their behaviour to make sure that all state machine reaches the same state after applying a transaction. Without this, after the same transation function, an old and a new state machine may compute different state. This problem surfaced because #303 and #305 changed the return values of the advanced API: * all functions return a node props map, even those that operate on a single tree node. * all tree nodes indirectly deleted as a byproduct of another put or delete may be included in the returned node props map. This was ok with non-transaction functions because the return values are handled locally, regardless of the effective machine version. However, transactions were broken as explained in the previous paragraphs. [How] We already introduced a new public API, `khepri_tx:does_api_comply_with()` that returns a boolean to indicate if an old or new behaviour should be expected for a specific breaking change. We use this API to determine how to adapt the behaviour and return value of puts and deletes. For queries and read-only transactions, we will need to change how we call Ra because the regular query API doesn't provide the effective machine version. This will be part of a later commit.
dumbbell
added a commit
that referenced
this pull request
Apr 1, 2025
[Why] Since #305, the returned node props map include tree nodes that were deleted as a byproduct of another put or delete. Things like the expiration of a `keep_while` condition. [How] This was a breaking change and this new option allows the caller to restore the previous behaviour of only getting directly impacted tree nodes. This will be useful in follow-up commits to solve backward compatibility in transaction handlind when some Khepri members run older versions of Khepri.
dumbbell
added a commit
that referenced
this pull request
Apr 1, 2025
…actions ... if the effective machine version is also old. [Why] A transaction function is extracted from the modules of a given Khepri member and is executed on all members. These members may run an older or a newer version of Khepri compared to the member that sent the transaction. Therefore, the transaction function and the Khepri public API must be aware of the effective machine version and adapt their behaviour to make sure that all state machine reaches the same state after applying a transaction. Without this, after the same transation function, an old and a new state machine may compute different state. This problem surfaced because #303 and #305 changed the return values of the advanced API: * all functions return a node props map, even those that operate on a single tree node. * all tree nodes indirectly deleted as a byproduct of another put or delete may be included in the returned node props map. This was ok with non-transaction functions because the return values are handled locally, regardless of the effective machine version. However, transactions were broken as explained in the previous paragraphs. [How] We already introduced a new public API, `khepri_tx:does_api_comply_with()` that returns a boolean to indicate if an old or new behaviour should be expected for a specific breaking change. We use this API to determine how to adapt the behaviour and return value of puts and deletes. For queries and read-only transactions, we will need to change how we call Ra because the regular query API doesn't provide the effective machine version. This will be part of a later commit.
dumbbell
added a commit
that referenced
this pull request
Apr 1, 2025
[Why] Since #305, the returned node props map include tree nodes that were deleted as a byproduct of another put or delete. Things like the expiration of a `keep_while` condition. [How] This was a breaking change and this new option allows the caller to restore the previous behaviour of only getting directly impacted tree nodes. This will be useful in follow-up commits to solve backward compatibility in transaction handlind when some Khepri members run older versions of Khepri.
dumbbell
added a commit
that referenced
this pull request
Apr 1, 2025
…actions ... if the effective machine version is also old. [Why] A transaction function is extracted from the modules of a given Khepri member and is executed on all members. These members may run an older or a newer version of Khepri compared to the member that sent the transaction. Therefore, the transaction function and the Khepri public API must be aware of the effective machine version and adapt their behaviour to make sure that all state machine reaches the same state after applying a transaction. Without this, after the same transation function, an old and a new state machine may compute different state. This problem surfaced because #303 and #305 changed the return values of the advanced API: * all functions return a node props map, even those that operate on a single tree node. * all tree nodes indirectly deleted as a byproduct of another put or delete may be included in the returned node props map. This was ok with non-transaction functions because the return values are handled locally, regardless of the effective machine version. However, transactions were broken as explained in the previous paragraphs. [How] We already introduced a new public API, `khepri_tx:does_api_comply_with()` that returns a boolean to indicate if an old or new behaviour should be expected for a specific breaking change. We use this API to determine how to adapt the behaviour and return value of puts and deletes. For queries and read-only transactions, we will need to change how we call Ra because the regular query API doesn't provide the effective machine version. This will be part of a later commit.
dumbbell
added a commit
that referenced
this pull request
Apr 1, 2025
…actions ... if the effective machine version is also old. [Why] A transaction function is extracted from the modules of a given Khepri member and is executed on all members. These members may run an older or a newer version of Khepri compared to the member that sent the transaction. Therefore, the transaction function and the Khepri public API must be aware of the effective machine version and adapt their behaviour to make sure that all state machine reaches the same state after applying a transaction. Without this, after the same transation function, an old and a new state machine may compute different state. This problem surfaced because #303 and #305 changed the return values of the advanced API: * all functions return a node props map, even those that operate on a single tree node. * all tree nodes indirectly deleted as a byproduct of another put or delete may be included in the returned node props map. This was ok with non-transaction functions because the return values are handled locally, regardless of the effective machine version. However, transactions were broken as explained in the previous paragraphs. [How] We already introduced a new public API, `khepri_tx:does_api_comply_with()` that returns a boolean to indicate if an old or new behaviour should be expected for a specific breaking change. We use this API to determine how to adapt the behaviour and return value of puts and deletes. For queries and read-only transactions, we will need to change how we call Ra because the regular query API doesn't provide the effective machine version. This will be part of a later commit.
dumbbell
added a commit
that referenced
this pull request
Apr 2, 2025
[Why] Since #305, the returned node props map include tree nodes that were deleted as a byproduct of another put or delete. Things like the expiration of a `keep_while` condition. [How] This was a breaking change and this new option allows the caller to restore the previous behaviour of only getting directly impacted tree nodes. This will be useful in follow-up commits to solve backward compatibility in transaction handlind when some Khepri members run older versions of Khepri.
dumbbell
added a commit
that referenced
this pull request
Apr 2, 2025
…actions ... if the effective machine version is also old. [Why] A transaction function is extracted from the modules of a given Khepri member and is executed on all members. These members may run an older or a newer version of Khepri compared to the member that sent the transaction. Therefore, the transaction function and the Khepri public API must be aware of the effective machine version and adapt their behaviour to make sure that all state machine reaches the same state after applying a transaction. Without this, after the same transation function, an old and a new state machine may compute different state. This problem surfaced because #303 and #305 changed the return values of the advanced API: * all functions return a node props map, even those that operate on a single tree node. * all tree nodes indirectly deleted as a byproduct of another put or delete may be included in the returned node props map. This was ok with non-transaction functions because the return values are handled locally, regardless of the effective machine version. However, transactions were broken as explained in the previous paragraphs. [How] We already introduced a new public API, `khepri_tx:does_api_comply_with()` that returns a boolean to indicate if an old or new behaviour should be expected for a specific breaking change. We use this API to determine how to adapt the behaviour and return value of puts and deletes. For queries and read-only transactions, we will need to change how we call Ra because the regular query API doesn't provide the effective machine version. This will be part of a later commit.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This change adds a
delete_reasonprop to the props map for nodes deleted with a function from the adv APIskhepri_advandkhepri_adv_tx. Tree nodes which are the target of deletion commands gain adelete_reasonproperty set todirect. This change also includes any tree nodes which were deleted because of an expired keep-while condition in the node props map. These expired nodes have adelete_reasonproperty set tokeep_whileinstead. Thedelete_reasonproperty lets callers filter on whether a change was a deletion and distinguish nodes deleted directly or indirectly.