Skip to content

API design #7

@edkelly303

Description

@edkelly303

This looks really interesting!

I am an Elixir noob who wrote his first GenServer last weekend, so this feedback may be very naive and stupid; please ignore it if so.

Although the API is very much simpler and more streamlined than the traditional GenServer, it still has a few moving parts and I wonder if they're totally necessary. From my reading of the readme, it sounds like there are exactly 3 things that you might want to do when you interact with a component:

  1. Update the state of the component
  2. Get a reply from the component
  3. Update the state and get a reply

With the current API, there are two things that the user needs to do to achieve these results:

  1. Choose between one_way and two_way (2 options)
  2. Choose whether to use set_state, set_state_and_return, or neither (3 options)

That gives you 6 possible combinations of things you could write, but only 4 of them will do what you want.

two_way -> OK (replies without updating the state)
two_way + set_state -> OK (updates the state and replies with the new state)
two_way + set_state_and_return -> OK (updates the state and replies with something else)
one_way -> OK (updates the state without replying)
one_way + set_state -> ?
one_way + set_state_and_return -> ?

Would it be possible/desirable to have an API that was more like this?

defmodule KV do

  use Component.Strategy.Dynamic,
      state_name:    :kv_store,
      initial_state: %{}

  handle add(kv_store, key, value) do
    %{state: Map.put(kv_store, key, value)}
  end

  handle get(kv_store, key) do
    %{reply: Map.get(kv_store, key)}
  end

  handle merge_and_tell_me_the_new_value(kv_store, key, new_value) do
    new_kv_store = Map.update(kv_store, key, new_value, fn old_value -> old_value + new_value end)
    merged_value = Map.get(new_kv_store, key)
    %{
      state: new_kv_store,
      reply: merged_value
    }
  end
end

That way, the user doesn't have to think about which type of function they're writing - they just need to specify what they want to get out of it - a new state, a reply, or both.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions