Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ========================================
- ============== Supervisor ==============
- ========================================
- ### This module controls the processes,
- ### `Sequence.Stash` is going to store the applications state
- ### `Sequence.Server` is going to perform the logic behind the application
- defmodule Sequence.Application do
- use Application
- def start(_type, _args) do
- children = [
- {Sequence.Stash, 123},
- {Sequence.Server, nil}
- ]
- opts = [strategy: :rest_for_one, name: Sequence.Supervisor]
- Supervisor.start_link(children, opts)
- end
- end
- =============================================
- ============== Sequence.Server ==============
- =============================================
- ### Our logic is performed in this module.
- ### You would run these commands through the shell using `Sequence.Server.next_number`
- ### Or `Sequence.Server.increment(int), this is where we could pass false data into throw an exception.
- defmodule Sequence.Server do
- use GenServer
- ### This function starts the process
- ### It uses `__MODULE__` to auto discover the module it is being called in
- def start_link(_) do
- GenServer.start_link(__MODULE__, nil, name: __MODULE__)
- end
- ### Function is called to make a request to one of the `handle_call` functions below,
- ### This is matched by the second param that is supplied `:next_number`
- def next_number do
- GenServer.call(__MODULE__, :next_number)
- end
- ### Adds ten to the number that is current in the application state
- def next_ten do
- GenServer.call(__MODULE__, :next_ten)
- end
- ### This module also does the same as above
- ### Difference is it requires an integer to be provided to add the the state of the process
- ### This is also the the function that we would use to create an exception by passing a string
- def increment(delta) do
- GenServer.cast(__MODULE__, {:increment_number, delta})
- end
- ### Function initializes the process, and similar to how you would a constructor in an OOP language
- ### We use it to start our `Stash` process to store the state in the case of an exception
- def init(_) do
- {:ok, Sequence.Stash.get()}
- end
- ### These are our handlers, that are being called in the functions above, you use pattern matching
- ### for the system to understand which one to use, it is matched by the first parameter.
- def handle_call(:next_number, _from, current_number) do
- {:reply, current_number, current_number + 1}
- end
- ### Same as above, but instead adds ten to the state
- def handle_call(:next_ten, _from, current_number) do
- {:reply, current_number, current_number + 10}
- end
- ### This is similar to the `handle_call` functions, but does not return data to the user, simply stores it in the state
- ### This is also a function that you would use with pattern matching the first parameter, ex. {:increment_number, delta}
- def handle_cast({:increment_number, delta}, current_number) do
- {:noreply, current_number + delta}
- end
- ### This function is used in case of an exception, it will store the `current_number` into the applications state
- ### when an exception is called.
- def terminate(_reason, current_number) do
- Sequence.Stash.update(current_number)
- end
- ### This is simply used as formatting when you check the status of the state.
- ### This can be called at anytime to check the status of the state.
- def format_status(_reason, [_pdict, state]) do
- [data: [{'State', "The current state is '#{inspect(state)}'"}]]
- end
- end
- =============================================
- ============== Sequence.Stash ==============
- =============================================
- ### This module is used to initialize the state, you can see this in the `Sequence.Supervisor`, it is run first.
- ### The `Sequence.Server` calls the `get()` function here to get the initial value, which is set to `123` in the Supervisor.
- ### The `Update` function is called once the `Sequence.Server` module is terminated.
- defmodule Sequence.Stash do
- use GenServer
- @me __MODULE__
- def start_link(initial_number) do
- GenServer.start_link(__MODULE__, initial_number, name: @me)
- end
- def get() do
- GenServer.call(@me, {:get})
- end
- def update(new_number) do
- GenServer.cast(@me, {:update, new_number})
- end
- def init(initial_number) do
- {:ok, initial_number}
- end
- def handle_call({:get}, _from, current_number) do
- {:reply, current_number, current_number}
- end
- def handle_cast({:update, new_number}, _current_number) do
- {:noreply, new_number}
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement