alvises

alvises

Code and patterns for an article about KV store engine with logs, in elixir

Hi everyone,

It has been a while I wanted to write a series of articles on how to implement a working (an simple!) kv store engine using logs and elixir. I’m writing the first article, which it’s an intro of the different concepts and I was thinking to write a first super simple implementation with just one writer (with one log file), one index and a reader.

Since the article is becoming long, I wanted to keep the code as simple as possible to focus on the storage engine. To make it as easy as possible, at the beginning I was thinking force the name of process, and avoiding in general to put the pid argument in the server interface functions, like this:

defmodule LogKV.Index do
  use GenServer

  def start_link([]) do
    GenServer.start_link(__MODULE__, :empty, name: __MODULE__)
  end

  def init(:empty), do: {:ok, %{}}
  
  def update(key, offset, size) do
    GenServer.call(__MODULE__, {:update, key, offset, size})
  end

  def lookup(key) do
    GenServer.call(__MODULE__, {:lookup, key})
  end

  def handle_call({:update, key, offset, size}, _from, index_map) do
    {:reply, :ok, Map.put(index_map, key, {offset, size})}
  end

  def handle_call({:lookup, key}, _from, index_map) do
    {:reply, get_key_offset_size(key, index_map), index_map}
  end

  defp get_key_offset_size(key, index_map) do
    case Map.get(index_map, key) do
      {_offset, _size} = offset_size -> {:ok, offset_size}
      nil -> {:error, :not_found}
    end
  endend

full code with docs here: logkv_articles/lib/logkv/index.ex at 90a980eccc06d2bb55fa8f491de63916ae75d6f3 · alvises/logkv_articles · GitHub

As you can see the update/3 function doesn’t have the pid parameter. This permits me, in the article, to focus more on the functionalities rather then processes. I don’t know if this is considered an anti-pattern, but for sure brings issues with unit testing and running the tests in parallel, since I can’t run multiple processes and can’t specify multiple pids.

I then have another module, the Writer which uses the Index. Having a simple interface with just one index with an harcoded name put me in the easy position to not having to introduce in the code registry etc.. the idea is to bring all this as long as the implementation improves during the different parts.

Can you please tell me what’s your opinion about this? Should I make the code a bit more complicated introducing using Registry and making the code less coupled, or for sake of simplicity of the article I can leave the interface as it is?

If you want to have a better idea of what I’m talking about and take a look at the draft I’m writing, here’s the link: https://www.poeticoding.com/p/31d01f68-f853-48fc-93ad-8c097204af6b/
password to see the page: elixir_forum

Thanks

Alvise

Most Liked

tty

tty

The more common idioms are:

  1. name the process the same as the module if only one such process is expected in a node
  2. the name in provided if several similar processes would run on the same node and you need access to a specific process
  3. have several start_link/start to simplify usage in the console and test

I’ve seen unique process names pulled from sys.config or a database in production code. As long as you are consistent about it.

The benefit of Registry is non-atom names.

Where Next?

Popular in Questions Top

greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
mgjohns61585
Could someone help me? I’m making my first elixir program, number guessing game. I can’t figure out how to convert the user’s guess from ...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
jaysoifer
Is there a way to rollback a specific migration and only that one (“skipping” all the other ones)? Would mix ecto.rollback -v 200809061...
New
vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call t...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New

Other popular topics Top

senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
johnnyicon
Hi all, I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I’m trying to use Postgres...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 47930 226
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New

We're in Beta

About us Mission Statement