This article guides you to set the state of the GenServer
on fly using iex
Hello everyone!
No excuse for a programmer to learn something new always. OK! Thoughts are apart. Let’s code.
Why would some one set the state onfly?
You may have your own reasons. In my case, I forgot add reset action to my GenServer
and pushed the code to production grade level.
Now, the server has gone live. To the client need, now I have to reset the state of the server. OK! Let’s make our client happy :)
Demo GenServer
To save our time, I have come up with a simple GenServer
code for the demo. It just maintains the state of an employee salary
.
Let’s write our server.
Create a file demo_server
.ex using your favorite editor.
$ vim demo_server.ex
Copy the following code and write to the file you have created before demo_server.ex
defmodule DemoServer do
use GenServer
@vsn 1
## Client API
def start_link employee do
GenServer.start_link __MODULE__, employee, []
end
def add_money(pid, value) do
GenServer.call(pid, {:add, value})
end
## Server API
def init(employee) do # initiating state with passed employee details
{:ok, employee}
end
# add the value to the state and returns :ok
def handle_call({:add, value},_from, %{name: name, money: money} = state) do
{:reply, "#{value} added to #{name} ", Map.put(state, :money, money+value)}
end
end
Now, open the iex
and load the file.
$ iex
iex> c "demo_server.ex"
iex> {:ok, pid} = DemoServer.start_link(%{name: "blackode", money: 25000})
iex> DemoServer.add_money, pid, 5000
"5000 added to blackode"
You shall need to be in the same directory of where the demo_server.ex
lies. Purposely, I did not write any get
handlers here to show you the another way of getting the state using pid
.
Now, how do we get the state
?
iex> :sys.get_state(pid)
%{name: "blackode", money: 30000}
# here pid is the process identifier of demo_server
iex> DemoServer.add_money(5000)
"5000 added to blackode"
ex> :sys.get_state(pid)
%{name: "blackode", money: 35000}
Now, the client asks you to reset the salary
to 0
But, we don’t have the function to call that satisfy the client.
We can still use :sys.replace_state/2
function to replace the state with new_state.
iex> :sys.replace_state pid, fn state -> %{state | money: 0}
%{money: 0, name: "blackode"}
iex> :sys.get_state pid
%{money: 0, name: "blackode"}
I took a silly reason to show you the demo. My only intention is to introduce :sys
erlang
module. You can use this module to the greater extent once you know how to use it.
Check out the GitHub repository on Killer Elixir Tips
![Blackoders
Telegram
Channel](/assets/images/extips.png)
🎉 Happy Coding :)
![author image](/assets/images/authors/blackode/blackode.png)