Skip to content
master
Switch branches/tags
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
lib
 
 
 
 
 
 
 
 
 
 
 
 
 
 

GenClient

Don't use this in production

PragDave's component library is a much more feature complete library and is of much higher quality.

GenClient is an elixir metaprogramming library made to generate boilerplate code that I found myself repeatedly writing and changing when working with GenServers.

Every time I wanted to add or remove a parameter from a GenServer module I needed to do so in several places.

GenClient lets the programmer write their logic in a single location and keep it there.

Example

Here is a module written using a standard GenServer implementation

counter.ex
defmodule Counter do
  defdelegate increment(pid),       to: Client
  defdelegate increment_by(pid, x), to: Client
  defdelegate peek(pid),            to: Client
end
counter/client.ex
defmodule Counter.Client do

  def increment(pid) do
    GenServer.cast(pid, :increment)
  end
  
  def increment_by(pid, x) do
    GenServer.cast(pid, {:increment_by, x})
  end

  def peek(pid) do
    GenServer.call(pid, :peek)
  end

end
counter/server.ex
defmodule Counter.Server do
  def handle_cast(:increment, state) do
    {:no_reply, Counter.Impl.increment(state)}
  end
  
  def handle_cast({:increment_by, x}, state) do
    {:no_reply, Counter.Impl.increment_by(state, x)}
  end
  
  def handle_call(:peek, _from, state) do
    {:reply, state, state}
  end
end
counter/impl.ex
defmodule Counter.Impl do
  def increment(state), do: state + 1
  def increment_by(state, x), do: state + x
end

The Previous Module Can be written using GenClient as follows:

counter.ex
defmodule Counter do
  use GenClient,
    for: Counter.Impl,
    calls: [:peek],
    casts: [:increment, :increment_by]
end
counter/counter.impl.ex
defmodule Counter.Impl do
  # Casts
  def increment(state), do: state + 1
  def increment_by(state, amount), do: state + amount
  
  # Calls
  def peek(state) do
    response = state
    new_state = state
    {response, new_state}
  end
  
end
The resulting api will be exactly the same

Adding as a mix dependency

  def deps do
    [{:gen_client, git:"https://github.com/LukeWood/GenClient"}]
  end

or

def deps do
  [{:gen_client, "~> 1.0.1"}]
end

About

GenClient is an elixir library made to generate boilerplate code that I found myself repeatedly writing and changing when working with GenServers

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages