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: https://github.com/alvises/logkv_articles/blob/90a980eccc06d2bb55fa8f491de63916ae75d6f3/lib/logkv/index.ex

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

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
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 th...
New
dotdotdotPaul
Okay, I'm having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I'm sure I'...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
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
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
gonzofish
I’m currently trying to understand how to join three tables using Ecto. All the examples I’ve seen use 2, so maybe I’m just missing somet...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3268 119930 1237
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
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
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
magnetic
Hey :wave:t3: Elixir community, I’ve been learning Elixir, and working on some side projects. My editor of choice is VSCode, and althoug...
New

We're in Beta

About us Mission Statement