Skip to content

Releases: rabbitmq/khepri

Khepri 0.2.0

15 Feb 16:42
Compare
Choose a tag to compare

At this point, Khepri should be considered Alpha 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.2.0

Stored procedures and triggers

This version introduces stored procedures and triggers. They allow to store code in the database itself and automatically execute it after some event occurs.

  1. Store an anonymous function in the tree:

    StoredProcPath = [path, to, stored_procedure],
    
    Fun = fun(Props) ->
              #{path := Path},
                on_action => Action} = Props
          end,
    
    khepri_machine:put(
      StoreId,
      StoredProcPath,
      #kpayload_sproc{sproc = Fun}))}.
  2. Register a trigger using an event filter:

    EventFilter = #kevf_tree{path = [stock, wood, <<"oak">>]},
    
    ok = khepri_machine:register_trigger(
           StoreId,
           TriggerId,
           EventFilter,
           StoredProcPath))}.

In the example above, as soon as the [stock, wood, <<"oak">>] node is created, updated or deleted, the anonymous function will be executed.

See #47.

Use records to describe payloads instead of macros

Breaking change

Payloads are now described as Erlang records. This allows to benefit from more compile-time checks in particular.

Here are the modifications you will have to do in your code:

% Up until 0.1.1:
khepri_machine:put(StoreId, Path, ?DATA_PAYLOAD(Data)).

% Starting from 0.2.0:
khepri_machine:put(StoreId, Path, #kpayload_data{data = Data}).

See #20.

keep_until conditions renamed to keep_while

Breaking change

The keep_until option of khepri_machine:put/3 was renamed to keep_while. The reason is that the tree node is kept while the condition is met. As soon as the condition evaluates to false, the tree node is deleted.

Here are the modifications you will have to do in your code:

% Up until 0.1.1:
khepri_machine:put(StoreId, Path, Payload, #{keep_until => #{Path => Condition}}).

% Starting from 0.2.0:
khepri_machine:put(StoreId, Path, Payload, #{keep_while => #{Path => Condition}}).

See #18.

Stacktrace frames pointing to an extracted function code have line numbers

Before, when a transaction function encountered an exception, the stacktrace would miss the source file and line number for frames pointing to the extracted code:

%% Based on the following function:
%%     crashing_fun() ->
%%         throw("Expected crash").

1> Fun = khepri_fun:to_standalone_fun(fun mod:crashing_fun/0, #{}).
2> khepri_fun:exec(Fun, []).
** exception throw: "Expected crash"
     in function  kfun__mod__crashing_fun__33048370:run/0

Now, khepri_fun decode lines information and the stacktrace frames provide the source file and the line number:

1> Fun = khepri_fun:to_standalone_fun(fun mod:crashing_fun/0, #{}).
2> khepri_fun:exec(Fun, []).
** exception throw: "Expected crash"
     in function  kfun__mod__crashing_fun__33048370:run/0 (.../mod.erl, line 30)

See #51.

Other changes

  • Ra was updated from 2.0.2 to 2.0.4.
  • Several functions of the re Erlang module are allowed in transaction functions (#41).
  • Patch several assembly instructions incorrectly decoded by beam_disasm (#39).
  • Many new assembly instructions supported in the function extraction code.
  • Annotate registers with type information to fix compilation failures related to function extracted (#36, #49).
  • The workaround to make it possible to run Dialyzer on testsuite was removed (#23). Now, one just has to use rebar as test dialyzer.
  • Modules to generate the nicer documentation were moved to https://hex.pm/packages/rebar3_edoc_extensions.

Download

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

Upgrade

Using Rebar:

  1. Update your rebar.config:

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

Using Erlang.mk:

  1. Update your Makefile:

    %% In your Makefile
    dep_khepri = hex 0.2.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.2.0 is available on Hex.pm.

Contributors

A warm thank you to contributors outside of the RabbitMQ team, this is invaluable for such a young project!

Khepri 0.1.1

16 Nov 17:35
Compare
Choose a tag to compare

At this point, Khepri should be considered Alpha 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.1.1

ReadWrite argument to khepri_tx:transaction/2 changes

Breaking change

The transaction API changed: khepri_tx:transaction/2 now takes the atoms ro, rw or auto as its second argument, instead of a boolean or auto. It makes it a bit clearer what the argument means out of context, compared to a boolean. This impacts the following APIs:

  • khepri:transaction/2
  • khepri:transaction/3
  • khepri_machine:transaction/2
  • khepri_machine:transaction/3

Here are the modifications you will have to do in your code:

%% Read/write transaction:
khepri:transaction(StoreId, Fun, true). % Up until 0.1.0
khepri:transaction(StoreId, Fun, rw).   % Starting from 0.1.1
%% Read/only transaction:
khepri:transaction(StoreId, Fun, false). % Up until 0.1.0
khepri:transaction(StoreId, Fun, ro).    % Starting from 0.1.1

The use of the auto argument remains unchanged.

See commit d7893f3.

Auto-detection of R/W transaction fixed

When a transaction function used another anonymous function which was declared outside of the transaction, that second anonymous function was not analyzed to determine the R/W nature. Therefore, if the transaction function didn't use khepri_tx:put/2 or khepri_tx:delete/1, it would be considered a read-only transaction. Unfortunately, if the second anonymous function did use one of those two APIs, the transaction would abort with a store_update_denied error.

The transaction below would be detected as read-only even though it calls khepri_tx:delete/1:

Fun = fun() -> khepri_tx:delete([foo]) end,
khepri_tx:to_standalone_fun(
  fun() -> Fun() end,
  auto),

Pull request #7 fixes this problem.

Other changes

  • Ra was updated from 2.0.1 to 2.0.2.
  • Several improvements and fixes to the testsuites and the specifications.
  • To be able to run Dialyzer on the testsuites, they are compiled at the same time as the actual source code of Khepri. Unfortunately, it means that PropEr becomes a regular dependency (instead of a test dependency), even though it is not used at runtime. That said it is a regular dependency from Rebar point of view, but not Erlang and the PropEr application won't be started or used at runtime.

Download

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

Upgrade

Using Rebar:

  1. Update your rebar.config:

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

Using Erlang.mk:

  1. Update your Makefile:

    %% In your Makefile
    dep_khepri = hex 0.1.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.1.1 is available on Hex.pm.

Khepri 0.1.0

04 Nov 15:36
Compare
Choose a tag to compare

This is the first release of Khepri.

At this point, Khepri should be considered Alpha 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.

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