Skip to content

Khepri 0.4.0

Choose a tag to compare

@dumbbell dumbbell released this 08 Jun 14:25

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.4.0

Add a logo :-)

Fancy change

Let's start with the fanciest change: we added the logo you can spot on the right ;-)

This logo is inspired by the drawing representing the god Khepri: a dung beetle holding the Sun. Here we use a rabbit (for the RabbitMQ-originated project) holding a database diagram. I know, creativity turned to 11.

Revamp of the clustering API

Breaking change

The clustering API was completely revamped in Khepri 0.4.0. Like the rest of the public API in Khepri 0.3.0, the goal is again to make it more straightforward and consistent.

The #105 pull request gives more details about the changes and how existing code can be adapted. But here are some of the highlights:

  • It is possible to start a Khepri store with a data directory as argument. No need to configure a Ra system yourself.
  • Most functions can now wait for a Ra leader to be elected. They take a timeout as argument to limit that wait. You don't have to handle a retry loop anymore.
  • There is a khepri:stop() function now to stop a store.

Here is an example of an old code and its newer version:

  • Up to Khepri 0.3.0:

    %% `my_ra_system' is configured using `ra_system:start/1'.
    DataDir = "/var/lib/khepri",
    RaSystemConfig = RaSystemConfig0#{name => my_ra_system,
                                      data_dir => DataDir,
                                      wal_data_dir => DataDir},
    {ok, _} = ra_system:start(RaSystemConfig),
    
    %% The Khepri store is started using that Ra system.
    {ok, StoreId} = khepri:start(my_ra_system).
  • Starting from Khepri 0.4.0:

    %% The Khepri store is started with a data directory. A Ra system will be
    %% configured and started automatically.
    {ok, StoreId} = khepri:start("/var/lib/khepri").

See #105.

Several improvements to make it easier to use Khepri for Elixir developers

We had great feedback on the Erlang forums following a question we asked about what should Khepri provide to make it nice to Elixir developers.

As a result, we implemented the following improvements:

  1. Khepri path can be Erlang binaries (#93). Elixir and other languages like Gleam running on top of the BEAM runtime use Erlang binaries to implement the "string" type. With this change, their native strings can be used directly in the Khepri API.

    iex> :khepri.get_data("/:foo")
    :value
  2. The khepri module exports "bang functions" such as khepri:'get!'(StoreId, Path) (#98). They don't look as nice in Erlang, but in Elixir, they are a common practice to have a version of a function which returns its result directly (if successful) or throws an error if not. They are especially handy when using pipelines.

    iex> :khepri.get!(~p"/:foo")
    %{
      [:foo] => %{
        child_list_length: 0,
        child_list_version: 1,
        data: :value,
        payload_version: 1
      }
    }
    iex> :khepri.get!(:non_existing_store, ~p"/:foo")
    ** (ErlangError) Erlang error: :noproc
        (khepri 0.3.0) /home/dumbbell/Projects/pivotal/khepri/src/khepri.erl:2629: :khepri.unwrap_result/1
  3. The khepri_path modules exports ~p and ~P sigils (#98). They are constructs which make the parsing of Khepri Unix-like string/binary-based paths very easy in Elixir.

    iex> import :khepri_path
    
    iex> ~p"/stock/wood/:oak"
    ["stock", "wood", :oak]
    
    iex> ~P"/stock/wood/:oak"
    ["stock", "wood", :oak]

See #93, #98.

EEP-48 doc chunks

In addition to rebar3_edoc_extensions, the plugin we use to produce documentations which are nicer to the eye compared to the default EDoc HTML output, we now also use the EDoc doclet and layout modules to produce EEP-48 doc chunks. People using Khepri should now get documentation and specs right from their compatible IDE and text editors.

► rebar3 shell
===> Verifying dependencies...
===> Analyzing applications...
===> Compiling khepri
Erlang/OTP 24 [erts-12.3.2] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit] [dtrace]

Eshell V12.3.2  (abort with ^G)
1> h(khepri).

   khepri

  Khepri database API.

  This module exposes the database API to manipulate data.

  The API is mainly made of the functions used to perform simple direct atomic operations and queries on the database. In addition to that, transaction/1 are the starting point to run transaction functions. However the API to
  use inside transaction functions is provided by khepri_tx.

  This module also provides functions to start and stop a simple unclustered Khepri store. For more advanced setup and clustering, see khepri_cluster.

Other changes

  • Added khepri:count() functions (#102).
  • Added support for ETS pattern conditions in #if_data_matches{} conditions (97).
  • Improved support for Erlang/OTP 25 (#101).
  • Ra was updated from 2.0.9 from 2.0.13 (#110).
  • Clarified the difference between RDBMS and Khepri's triggers (#65).

Download

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

Upgrade

Using Rebar:

  1. Update your rebar.config:

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

Using Erlang.mk:

  1. Update your Makefile:

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