Skip to content

Releases: rabbitmq/khepri

v0.17.1

08 Apr 13:13
v0.17.1
6d4cf74
Compare
Choose a tag to compare

At this point, Khepri should be considered Beta and not production ready. The API will likely evolve and future releases will likely introduce breaking changes. The goal of this release is to make it easy for anyone to try it and possibly give feedback.

What's new in Khepri 0.17.1

Ra was bumped from 2.16.6 to 2.16.7. It fixes a bug with the handling of #info_reply{} that affects Khepri, as discovered by the khepri_mnesia_migration testsuites.

See #329.

Download

Khepri is available from Hex.pm: https://hex.pm/packages/khepri/0.17.1

Upgrade

Using Rebar:

  1. Update your rebar.config:

    %% In rebar.config
    {deps, [{khepri, "0.17.1"}]}.
  2. Run rebar3 upgrade khepri.

Using Erlang.mk:

  1. Update your Makefile:

    %% In your Makefile
    dep_khepri = hex 0.17.1
  2. Remove the deps/khepri directory. The new version will be fetched the next time you build your project.

Documentation

The documentation for Khepri is available on Hex.pm.

Khepri 0.17.0

07 Apr 16:53
v0.17.0
4f552b7
Compare
Choose a tag to compare

At this point, Khepri should be considered Beta and not production ready. The API will likely evolve and future releases will likely introduce breaking changes. The goal of this release is to make it easy for anyone to try it and possibly give feedback.

What's new in Khepri 0.17.0

Return tree nodes deteled by keep-while conditions in put and delete return values

Breaking change

All put and delete operations now return all nodes that were deleted by the operation. This includes nodes deleted by keep-while conditions as well as child tree nodes in the case of delete operations. See #305 and #309.

The deletion reason was added in the return tree node properties to allow the caller to distinguish nodes explicitly deleted from the nodes that were deleted as a consequence of a put or delete.

To permit that, the return values of advanced put and delete operations were made uniform with other operations, always returning a map of tree node properties (#303, #310). Here is an example of the change to make to your code:

  • Up to Khepri 0.16.x:

    {ok, #{payload_version := _}} = khepri_adv:put(StoreId, Path, Value)
  • Starting from Khepri 0.17.0:

    {ok, #{Path := #{payload_version := _}}} = khepri_adv:put(StoreId, Path, Value)

Backward-compatible transaction functions

Breaking change

The breaking change above impacted the khepri_tx_adv API as well and you may need to rework transactions to take into account the possible old and new return values. Indeed, transactions submitted from a Khepri member are executed on all cluster members, regardless of the version of Khepri running there. An old node might submit a transaction executed on a new node, and a new node might submit a transaction executed on an old node.

You can use the new khepri_tx:does_api_comply_with/1 to determine what to expect. Here is an example:

khepri:transaction(
  StoreId,
  fun () ->
          %% We query Khepri to determine how the API will behave.
          UsesUniformWriteRet = try
                                    khepri_tx:does_api_comply_with(uniform_write_ret)
                                catch
                                    error:undef ->
                                        false
                                end,

          %% We use the result to match the return value appropriately. This
          %% transaction function willl work equally on Khepri 0.17.0 and older
          %% versions.
          case khepri_tx_adv:delete(Path) of
              {ok, #{Path := #{data := _}}} when UsesUniformWriteRet ->
	          %% The API used the new return value format.
		  ...;
              {ok, #{data := _}} when not UsesUniformWriteRet ->
	          %% The API used the old return value format.
		  ...;
              {ok, _} ->
                  ok
          end
  end, rw).

See #326.

Optimize the lookup of matching keep_while conditions

Khepri uses a new khepri_prefix_tree internal structure instead of the previous map to manage the reverse index. This allows to quickly eliminate non-matching entries.

See #298.

Unify khepri_cluster:members/2 and khepri_cluster:nodes/2 with other query APIs

Breaking change

khepri_cluster:members/2 and khepri_cluster:nodes/2 now take a query options map (see the documentation of the khepri:query_options() type) instead of a timeout value only.

This allows to select between a leader query and a local query with the same favor option as any store query function. Therefore, favor => consistency will use a leader query while favor => low_latency will use a local query.

Here is an example of the change to make to your code:

  • Up to Khepri 0.16.x:

    khepri_cluster:members(StoreId, Timeout),
    khepri_cluster:locally_known_nodes(StoreId)
  • Starting from Khepri 0.17.0:

    khepri_cluster:members(StoreId, #{timeout => Timeout}),
    khepri_cluster:nodes(StoreId, #{favor => low_latency})

See #300.

Other changes

  • Allow calls to khepri_path in transactions (#312).
  • Make the internal khepri_tree:tree_v*() and khepri_tree:keep_while_conds_revidx_v*() types opaque types (#299).
  • Handle expired dedups on tick to remove some load on commands (#297).
  • Ignore unknown props to return to take machine breaking changes into account (#308).
  • Fix bang function return value spec (#311).
  • Fix documentation (#316, #321).
  • Fix how we determine the need for a fence preliminary query (#317).
  • Fix how we check for the dedup mechanism support (#320).
  • Filter query/command options that are passed to transactions (#322, #327).
  • Fix keep_while corner cases (#324).
  • Horus was bumped from 0.3.0 to 0.3.1 (#307).
  • Ra was bumped from 2.14.0 to 2.16.6 (#306, #314, #318, #323, #325).

Download

Khepri is available from Hex.pm: https://hex.pm/packages/khepri/0.17.0

Upgrade

Using Rebar:

  1. Update your rebar.config:

    %% In rebar.config
    {deps, [{khepri, "0.17.0"}]}.
  2. Run rebar3 upgrade khepri.

Using Erlang.mk:

  1. Update your Makefile:

    %% In your Makefile
    dep_khepri = hex 0.17.0
  2. Remove the deps/khepri directory. The new version will be fetched the next time you build your project.

Documentation

The documentation for Khepri is available on Hex.pm.

Khepri 0.16.0

01 Apr 16:00
v0.16.0
5c70d55
Compare
Choose a tag to compare

At this point, Khepri should be considered Beta and not production ready. The API will likely evolve and future releases will likely introduce breaking changes. The goal of this release is to make it easy for anyone to try it and possibly give feedback.

What's new in Khepri 0.16.0

This release focuses on bug fixes and optimizations. It does not bring new features.

  • Fix a bug in the khepri_cluster:reset() code that was caused by a race between the local node and the rest of the cluster (#294).
  • Fix a bug when a projection is triggered in the same batch of aux effects as the projection deletion (#293).
  • Stop spamming the cluster with join/leave commands if it is not ready (#295).
  • Improve the performance of khepri_cluster:is_store_running() (#292, #296).

Download

Khepri 0.16.0 is available from Hex.pm: https://hex.pm/packages/khepri/0.16.0

Upgrade

Using Rebar:

  1. Update your rebar.config:

    %% In rebar.config
    {deps, [{khepri, "0.16.0"}]}.
  2. Run rebar3 upgrade khepri.

Using Erlang.mk:

  1. Update your Makefile:

    %% In your Makefile
    dep_khepri = hex 0.16.0
  2. Remove the deps/khepri directory. The new version will be fetched the next time you build your project.

Documentation

The documentation for Khepri 0.16.0 is available on Hex.pm.

Khepri 0.15.0

05 Sep 08:46
v0.15.0
c5d02f4
Compare
Choose a tag to compare

At this point, Khepri should be considered Beta and not production ready. The API will likely evolve and future releases will likely introduce breaking changes. The goal of this release is to make it easy for anyone to try it and possibly give feedback.

What's new in Khepri 0.15.0

Queries are always executed locally

Breaking change

So far, Khepri relied directly on the query mechanism of Ra: the query function could be evaluated by the local Ra server (regardless of its state) or the leader. There was even a "consistent" query type where the query was evaluated on the leader, but after ensuring that a quorum number of members were availble. Khepri exposed the favor query option to let the caller tweak the underlying type of query. By default, it balanced between simple leader queries and consistent queries.

Unfortunately, the fact that the query function was possibly executed on a remote node caused several issues:

  • The function reference might be invalid on the remote node because of a difference in the version of Erlang/OTP.
  • The function reference might be invalid on the remote node because the module hosting the function is not the same.
  • The function reference might be invalid on the remote node because the module hosting the function is missing.
  • Using an exported MFA instead of a function reference doesn't solve the problem because the remote copy of that MFA may still be missing or simply be incompatible (different code/behavior). This might be even more difficult to debug.

This release will now always use local queries by default to avoid them. However, there is the risk that the query works on out-of-date data if the local Ra server is behind the leader. To avoid this, we made the following related changes:

  • Synchronous puts, deletes and transactions use the reply_from Ra option to make sure that the local node got the update before returning.
  • The favor query option stays but it only takes two values now: low_latency and consistency. In the case of consistency, the local query uses the new condition option introduced in Ra 2.13.0: it will wait for the local Ra server to catch up with the leader before evaluating the query.

If you are using the favor => compromise value, you will need to update your code to pick between the other two values.

The application parameter consistent_query_interval_in_compromise was removed in #276 as part of this change.

Note that the throughput of consistent queries was divided by 2 in the process. It should be ok for most use cases as consistent queries are rarely needed.

See #238, #260 and #283.

Projections restored after snapshot install

This release contains two bug fixes that caused inconsistencies between the store and the projections ETS tables; the ETS tables har wrong data.

  • Projections were not restored if a follower caught up with the leader using a snapshot; see #259.
  • Projections were not taking into account changes to projections themselves or deletions from the store that could happen in the newly installed snapshot; see #290.

Replace khepri:unregister_projection() by khepri:unregister_projections()

Breaking change

The goal is to allow the caller to remove many or all projections in a single call.

Here is an example of the change to make to your code:

  • Up to Khepri 0.14.x:

    khepri:unregister_projection(StoreId, ProjectionName)
  • Starting from Khepri 0.15.0:

    khepri:unregister_projections(StoreId, [ProjectionName])

See #282 and #286.

Other changes

  • Add khepri_cluster:wait_for_leader/{0,1,2} (#289).
  • Fixes to khepri_cluster member queries (#287).
  • Make ?IS_KHEPRI_CONDITION/1 stricter (#265).
  • Expose ?khepri_error/2 and ?khepri_exception/2 in the public API (#266).
  • Fix the use of reply_from when (un)registering projections (#270).
  • Make is_store_running/1 and get_store_ids/0 robust against Ra servers stopping behind the scene (#271, #275).
  • Optimize transactions by using lists prepend instead of ++ (#291).
  • Ra was bumped from 2.10.1 to 2.14.0 (#263, #267, #273, #280, #285, #290).
  • Horus was bumped from 0.2.5 to 0.3.0 (#254, #268).
  • Fix two test cases in cluster_SUITE (#269, #272).
  • Rename the internal macro ?NOPROC_RETRY_INTERVAL to ?TRANSIENT_ERROR_RETRY_INTERVAL (#288).

Download

Khepri 0.15.0 is available from Hex.pm: https://hex.pm/packages/khepri/0.15.0

Upgrade

Using Rebar:

  1. Update your rebar.config:

    %% In rebar.config
    {deps, [{khepri, "0.15.0"}]}.
  2. Run rebar3 upgrade khepri.

Using Erlang.mk:

  1. Update your Makefile:

    %% In your Makefile
    dep_khepri = hex 0.15.0
  2. Remove the deps/khepri directory. The new version will be fetched the next time you build your project.

Documentation

The documentation for Khepri 0.15.0 is available on Hex.pm.

Khepri 0.14.0

16 May 08:52
v0.14.0
4621805
Compare
Choose a tag to compare

At this point, Khepri should be considered Beta and not production ready. The API will likely evolve and future releases will likely introduce breaking changes. The goal of this release is to make it easy for anyone to try it and possibly give feedback.

What's new in Khepri 0.14.0

Command deduplication

Khepri uses a retry mechanism that send a command again whenever there is an error such as noproc or nodedown. However, the state machine could receive the command twice depending the actual underlying error and the timing.

This new version adds two new commands to wrap other commands that act as a kind of handshake between the "client" and the state machine. This new mechanism is only enabled by default for R/W transactions.

The version of the state machine is bumped from 0 to 1. The code is backward-compatible with Ra cluster members which don't know about these new commands.

See #250.

Simplify {error, timeout} error type

Breaking change

The {error, {timeout, LeaderId}} error was simplified to the more common {error, timeout}, because the leader ID isn't interesting to the caller.

Here is an example of the change to make to your code:

  • Up to Khepri 0.13.x:

    case khepri:exists(StoreId, Path) of
        {error, {timeout, _LeaderId}} ->
            handle_timeout()
    end
  • Start from Khepri 0.14.0:

    case khepri:exists(StoreId, Path) of
        {error, timeout} ->
            handle_timeout()
    end

Seee #256.

Other changes

  • Fixed a bug where a projection could be executed for a tree node that doesn't match the pattern if this tree is a grand-child of the pattern (#257).
  • Ra was bumped from 2.9.1 to 2.10.1 (#258).

Download

Khepri 0.14.0 is available from Hex.pm: https://hex.pm/packages/khepri/0.14.0

Upgrade

Using Rebar:

  1. Update your rebar.config:

    %% In rebar.config
    {deps, [{khepri, "0.14.0"}]}.
  2. Run rebar3 upgrade khepri.

Using Erlang.mk:

  1. Update your Makefile:

    %% In your Makefile
    dep_khepri = hex 0.14.0
  2. Remove the deps/khepri directory. The new version will be fetched the next time you build your project.

Documentation

The documentation for Khepri 0.14.0 is available on Hex.pm.

Khepri 0.13.0

28 Mar 14:00
v0.13.0
076926a
Compare
Choose a tag to compare

At this point, Khepri should be considered Beta and not production ready. The API will likely evolve and future releases will likely introduce breaking changes. The goal of this release is to make it easy for anyone to try it and possibly give feedback.

What's new in Khepri 0.13.0

Preliminary support for Erlang/OTP 27

With the upgrade of Horus from 0.2.4 to 0.2.5, Khepri gains preliminary support for Erlang/OTP 27. We say preliminary because Erlang/OTP 27 has not been released yet, so we can't guarantee at that point that it will be fully compatible with the final version.

See #254.

Other changes

  • Fixed a bug where projections could be out-of-sync with the actual database tree content because of the way they were initialized on Ra server recovery (#255).
  • Made the #khepri_machine{} record private and opaque (#252, #253).

Download

Khepri 0.13.0 is available from Hex.pm: https://hex.pm/packages/khepri/0.13.0

Upgrade

Using Rebar:

  1. Update your rebar.config:

    %% In rebar.config
    {deps, [{khepri, "0.13.0"}]}.
  2. Run rebar3 upgrade khepri.

Using Erlang.mk:

  1. Update your Makefile:

    %% In your Makefile
    dep_khepri = hex 0.13.0
  2. Remove the deps/khepri directory. The new version will be fetched the next time you build your project.

Documentation

The documentation for Khepri 0.13.0 is available on Hex.pm.

Khepri 0.12.1

21 Feb 10:29
v0.12.1
c49aeba
Compare
Choose a tag to compare

At this point, Khepri should be considered Beta and not production ready. The API will likely evolve and future releases will likely introduce breaking changes. The goal of this release is to make it easy for anyone to try it and possibly give feedback.

What's new in Khepri 0.12.1

Handling of unknown commands

Now, if a Khepri state machine receives an unknown command, it will throw an exception. This will be useful in the future in case of an upgrade of the state machine code if new commands are introduced. If the new commands are submitted before the Ra cluster upgraded the state machine version, then the caller will be notified the command couldn't be applied.

See #251.

Download

Khepri 0.12.1 is available from Hex.pm: https://hex.pm/packages/khepri/0.12.1

Upgrade

Using Rebar:

  1. Update your rebar.config:

    %% In rebar.config
    {deps, [{khepri, "0.12.1"}]}.
  2. Run rebar3 upgrade khepri.

Using Erlang.mk:

  1. Update your Makefile:

    %% In your Makefile
    dep_khepri = hex 0.12.1
  2. Remove the deps/khepri directory. The new version will be fetched the next time you build your project.

Documentation

The documentation for Khepri 0.12.1 is available on Hex.pm.

Khepri 0.12.0

12 Feb 12:09
v0.12.0
35a9f5b
Compare
Choose a tag to compare

At this point, Khepri should be considered Beta and not production ready. The API will likely evolve and future releases will likely introduce breaking changes. The goal of this release is to make it easy for anyone to try it and possibly give feedback.

What's new in Khepri 0.12.0

Ra 2.9.1

This new release of Ra comes with an important bug fix to the consistency of the list of members/nodes returned by khepri_cluster:members/{0,1,2} and khepri_cluster:nodes/{0,1,2}. Before this change, it was possible that the returned list was out-of-date and stale.

See rabbitmq/ra#417 and #249.

Other changes

  • Fixed unregistering of non-existent projections (#248).

Download

Khepri 0.12.0 is available from Hex.pm: https://hex.pm/packages/khepri/0.12.0

Upgrade

Using Rebar:

  1. Update your rebar.config:

    %% In rebar.config
    {deps, [{khepri, "0.12.0"}]}.
  2. Run rebar3 upgrade khepri.

Using Erlang.mk:

  1. Update your Makefile:

    %% In your Makefile
    dep_khepri = hex 0.12.0
  2. Remove the deps/khepri directory. The new version will be fetched the next time you build your project.

Documentation

The documentation for Khepri 0.12.0 is available on Hex.pm.

Khepri 0.11.0

30 Jan 08:50
v0.11.0
e85821b
Compare
Choose a tag to compare

At this point, Khepri should be considered Beta and not production ready. The API will likely evolve and future releases will likely introduce breaking changes. The goal of this release is to make it easy for anyone to try it and possibly give feedback.

What's new in Khepri 0.11.0

Return {ok, _} | {error, _} from functions returning cluster members

Breaking change

Always returning a list, hiding any error behind an empty list, proved to be a bad design, as it made it way too easy to ignore or miss errors and act upon them.

This kind of return value was also inconsistent with the rest of the API.

The members list is now wrapped into an {ok, Members} tuple. Likewise for nodes lists. This forces the caller to be aware of errors and handle them. The afftected APIs are:

  • khepri_cluster:members/{1,2}
  • khepri_cluster:locally_known_members/{1,2}
  • khepri_cluster:nodes/{1,2}
  • khepri_cluster:locally_known_nodes/{1,2}

Here is an example of the change to make to your code:

  • Up-to Khepri 0.10.x:

    lists:foreach(
        fun(Node) ->
            do_something_with_node(Node)
        end,
        khepri_cluster:nodes(StoreId)).
  • Starting from Khepri 0.11.0:

    case khepri_cluster:nodes(StoreId) of
        {ok, Nodes} ->
            lists:foreach(
                fun(Node) ->
                    do_something_with_node(Node)
                end,
                Nodes);
        {error, _Reason} = Error ->
            handle_error(Error)
    end.

While working on this:

  • khepri_cluster:members/0, khepri_cluster:locally_known_members/0, khepri_cluster:nodes/0 and khepri_cluster:locally_known_nodes/0 were added to work on the default store. This is inline with all other API functions.
  • Type specifications and documentation was added for all these functions, existing and new.

See #244.

Speed up members/nodes local query

Ra now provides a new ra_leaderboard:lookup_members/1 function to query members locally that is faster that a call to the local Ra server. Khepri started to use it and, if it returns an error, it will fall back to the previous Ra server query.

See #240.

Other changes

  • Use monotonic times to mesaure a duration, not system time (#245).
  • Do not enforce the favor option when querying the "keep while" conditions or the projections states (#246).
  • Ra was bumped from 2.7.0 to 2.7.3 (#241).

Download

Khepri 0.11.0 is available from Hex.pm: https://hex.pm/packages/khepri/0.11.0

Upgrade

Using Rebar:

  1. Update your rebar.config:

    %% In rebar.config
    {deps, [{khepri, "0.11.0"}]}.
  2. Run rebar3 upgrade khepri.

Using Erlang.mk:

  1. Update your Makefile:

    %% In your Makefile
    dep_khepri = hex 0.11.0
  2. Remove the deps/khepri directory. The new version will be fetched the next time you build your project.

Documentation

The documentation for Khepri 0.11.0 is available on Hex.pm.

Khepri 0.10.1

12 Dec 09:32
v0.10.1
e4d2529
Compare
Choose a tag to compare

At this point, Khepri should be considered Beta and not production ready. The API will likely evolve and future releases will likely introduce breaking changes. The goal of this release is to make it easy for anyone to try it and possibly give feedback.

What's new in Khepri 0.10.1

This release fixes the list of files published to Hex.pm: the LICENSE-* files were missing.

See #237.

Download

Khepri 0.10.1 is available from Hex.pm: https://hex.pm/packages/khepri/0.10.1

Upgrade

Using Rebar:

  1. Update your rebar.config:

    %% In rebar.config
    {deps, [{khepri, "0.10.1"}]}.
  2. Run rebar3 upgrade khepri.

Using Erlang.mk:

  1. Update your Makefile:

    %% In your Makefile
    dep_khepri = hex 0.10.1
  2. Remove the deps/khepri directory. The new version will be fetched the next time you build your project.

Documentation

The documentation for Khepri 0.10.1 is available on Hex.pm.